]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSv1.cxx
Corrected comment (Andrea)
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv1.cxx
CommitLineData
7587f5a5 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
b2a60966 16/* $Id$ */
5f20d3fb 17
702ab87e 18/* History of cvs commits:
19 *
20 * $Log$
7ca4655f 21 * Revision 1.107 2007/02/01 10:34:47 hristov
22 * Removing warnings on Solaris x86
23 *
ad4aeaf4 24 * Revision 1.106 2006/11/14 17:11:15 hristov
25 * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
26 *
e939a978 27 * Revision 1.105 2006/09/13 07:31:01 kharlov
28 * Effective C++ corrections (T.Pocheptsov)
29 *
43fbaae1 30 * Revision 1.104 2005/05/28 14:19:05 schutz
31 * Compilation warnings fixed by T.P.
32 *
702ab87e 33 */
34
7587f5a5 35//_________________________________________________________________________
5f20d3fb 36// Implementation version v1 of PHOS Manager class
a3dfe79c 37//---
a3dfe79c 38//---
39// Layout EMC + CPV has name IHEP:
ed4205d8 40// Produces hits for CPV, cumulated hits
41//---
ed4205d8 42//---
5f20d3fb 43//*-- Author: Yves Schutz (SUBATECH)
b2a60966 44
7587f5a5 45
46// --- ROOT system ---
7ca4655f 47#include <TClonesArray.h>
88cb7938 48#include <TParticle.h>
88cb7938 49#include <TVirtualMC.h>
7587f5a5 50
51// --- Standard library ---
52
88cb7938 53
7587f5a5 54// --- AliRoot header files ---
97cee223 55#include "AliPHOSCPVDigit.h"
97cee223 56#include "AliPHOSGeometry.h"
88cb7938 57#include "AliPHOSHit.h"
88cb7938 58#include "AliPHOSv1.h"
59#include "AliRun.h"
5d12ce38 60#include "AliMC.h"
7587f5a5 61
62ClassImp(AliPHOSv1)
63
bea63bea 64//____________________________________________________________________________
02ab1add 65AliPHOSv1::AliPHOSv1():
43fbaae1 66 fLightYieldMean(0.),
67 fIntrinsicPINEfficiency(0.),
68 fLightYieldAttenuation(0.),
69 fRecalibrationFactor(0.),
70 fElectronsPerGeV(0.),
71 fAPDGain(0.),
72 fLightFactor(0.),
73 fAPDFactor(0.)
bea63bea 74{
43fbaae1 75 //Def ctor.
bea63bea 76}
77
7587f5a5 78//____________________________________________________________________________
79AliPHOSv1::AliPHOSv1(const char *name, const char *title):
43fbaae1 80 AliPHOSv0(name,title),
81 fLightYieldMean(0.),
82 fIntrinsicPINEfficiency(0.),
83 fLightYieldAttenuation(0.),
84 fRecalibrationFactor(0.),
85 fElectronsPerGeV(0.),
86 fAPDGain(0.),
87 fLightFactor(0.),
88 fAPDFactor(0.)
7587f5a5 89{
5f20d3fb 90 //
ed4205d8 91 // We store hits :
5f20d3fb 92 // - fHits (the "normal" one), which retains the hits associated with
93 // the current primary particle being tracked
94 // (this array is reset after each primary has been tracked).
95 //
fa412d9b 96
037cc66d 97
5f20d3fb 98
99 // We do not want to save in TreeH the raw hits
100 // But save the cumulated hits instead (need to create the branch myself)
101 // It is put in the Digit Tree because the TreeH is filled after each primary
7b326aac 102 // and the TreeD at the end of the event (branch is set in FinishEvent() ).
5f20d3fb 103
ed4205d8 104 fHits= new TClonesArray("AliPHOSHit",1000) ;
5d12ce38 105 gAlice->GetMCApp()->AddHitList(fHits) ;
5f20d3fb 106
ed4205d8 107 fNhits = 0 ;
5f20d3fb 108
f6d1e5e1 109 fIshunt = 2 ; // All hits are associated with primary particles
7b326aac 110
9688c1dd 111 //Photoelectron statistics:
112 // The light yield is a poissonian distribution of the number of
113 // photons created in the PbWo4 crystal, calculated using following formula
114 // NumberOfPhotons = EnergyLost * LightYieldMean* APDEfficiency *
115 // exp (-LightYieldAttenuation * DistanceToPINdiodeFromTheHit);
116 // LightYieldMean is parameter calculated to be over 47000 photons per GeV
117 // APDEfficiency is 0.02655
118 // k_0 is 0.0045 from Valery Antonenko
119 // The number of electrons created in the APD is
120 // NumberOfElectrons = APDGain * LightYield
121 // The APD Gain is 300
122 fLightYieldMean = 47000;
123 fIntrinsicPINEfficiency = 0.02655 ; //APD= 0.1875/0.1271 * 0.018 (PIN)
27f33ee5 124 fLightYieldAttenuation = 0.0045 ;
125 fRecalibrationFactor = 13.418/ fLightYieldMean ;
126 fElectronsPerGeV = 2.77e+8 ;
127 fAPDGain = 300. ;
128 fLightFactor = fLightYieldMean * fIntrinsicPINEfficiency ;
184569b0 129 fAPDFactor = (fRecalibrationFactor/100.) * fAPDGain ;
5f20d3fb 130}
131
7587f5a5 132//____________________________________________________________________________
bea63bea 133AliPHOSv1::~AliPHOSv1()
b2a60966 134{
bea63bea 135 // dtor
88cb7938 136 if ( fHits) {
ed4205d8 137 fHits->Delete() ;
138 delete fHits ;
139 fHits = 0 ;
184569b0 140 }
7587f5a5 141}
142
7587f5a5 143//____________________________________________________________________________
2af5445a 144void AliPHOSv1::AddHit(Int_t shunt, Int_t primary, Int_t Id, Float_t * hits)
bea63bea 145{
146 // Add a hit to the hit list.
f6d1e5e1 147 // A PHOS hit is the sum of all hits in a single crystal from one primary and within some time gate
bea63bea 148
5f20d3fb 149 Int_t hitCounter ;
bea63bea 150 AliPHOSHit *newHit ;
5f20d3fb 151 AliPHOSHit *curHit ;
152 Bool_t deja = kFALSE ;
fa7cce36 153 AliPHOSGeometry * geom = GetGeometry() ;
bea63bea 154
2af5445a 155 newHit = new AliPHOSHit(shunt, primary, Id, hits) ;
bea63bea 156
7854a24a 157 for ( hitCounter = fNhits-1 ; hitCounter >= 0 && !deja ; hitCounter-- ) {
29b077b5 158 curHit = dynamic_cast<AliPHOSHit*>((*fHits)[hitCounter]) ;
9688c1dd 159 if(curHit->GetPrimary() != primary) break ;
160 // We add hits with the same primary, while GEANT treats primaries succesively
ed4205d8 161 if( *curHit == *newHit ) {
f15a01eb 162 *curHit + *newHit ;
ed4205d8 163 deja = kTRUE ;
5f20d3fb 164 }
165 }
166
167 if ( !deja ) {
ed4205d8 168 new((*fHits)[fNhits]) AliPHOSHit(*newHit) ;
7b326aac 169 // get the block Id number
9688c1dd 170 Int_t relid[4] ;
fa7cce36 171 geom->AbsToRelNumbering(Id, relid) ;
184569b0 172
ed4205d8 173 fNhits++ ;
5f20d3fb 174 }
184569b0 175
bea63bea 176 delete newHit;
bea63bea 177}
178
7b326aac 179//____________________________________________________________________________
180void AliPHOSv1::FinishPrimary()
181{
182 // called at the end of each track (primary) by AliRun
183 // hits are reset for each new track
184 // accumulate the total hit-multiplicity
7b326aac 185
186}
187
188//____________________________________________________________________________
189void AliPHOSv1::FinishEvent()
190{
191 // called at the end of each event by AliRun
192 // accumulate the hit-multiplicity and total energy per block
193 // if the values have been updated check it
88cb7938 194
88cb7938 195 AliDetector::FinishEvent();
7b326aac 196}
5f20d3fb 197//____________________________________________________________________________
7587f5a5 198void AliPHOSv1::StepManager(void)
199{
9688c1dd 200 // Accumulates hits as long as the track stays in a single crystal or CPV gas Cell
b2a60966 201
4f5bbbd4 202 Int_t relid[4] ; // (box, layer, row, column) indices
203 Int_t absid ; // absolute cell ID number
471193a8 204 Float_t xyzte[5]={-1000.,-1000.,-1000.,0.,0.} ; // position wrt MRS, time and energy deposited
4f5bbbd4 205 TLorentzVector pos ; // Lorentz vector of the track current position
fa412d9b 206 Int_t copy ;
7587f5a5 207
fa7cce36 208 TString name = GetGeometry()->GetName() ;
037cc66d 209
9688c1dd 210 Int_t moduleNumber ;
211
d6fb41ac 212 static Int_t idPCPQ = gMC->VolId("PCPQ");
213 if( gMC->CurrentVolID(copy) == idPCPQ &&
9688c1dd 214 (gMC->IsTrackEntering() ) &&
215 gMC->TrackCharge() != 0) {
f6d1e5e1 216
9688c1dd 217 gMC -> TrackPosition(pos);
f6d1e5e1 218
9688c1dd 219 Float_t xyzm[3], xyzd[3] ;
220 Int_t i;
221 for (i=0; i<3; i++) xyzm[i] = pos[i];
222 gMC -> Gmtod (xyzm, xyzd, 1); // transform coordinate from master to daughter system
223
e3daf02c 224 Float_t xyd[3]={0,0,0} ; //local position of the entering
9688c1dd 225 xyd[0] = xyzd[0];
53e03a1e 226 xyd[1] =-xyzd[2];
227 xyd[2] =-xyzd[1];
f6d1e5e1 228
9688c1dd 229 // Current momentum of the hit's track in the local ref. system
230 TLorentzVector pmom ; //momentum of the particle initiated hit
231 gMC -> TrackMomentum(pmom);
232 Float_t pm[3], pd[3];
233 for (i=0; i<3; i++)
234 pm[i] = pmom[i];
f6d1e5e1 235
9688c1dd 236 gMC -> Gmtod (pm, pd, 2); // transform 3-momentum from master to daughter system
237 pmom[0] = pd[0];
cf75bc19 238 pmom[1] =-pd[1];
239 pmom[2] =-pd[2];
f6d1e5e1 240
9688c1dd 241 // Digitize the current CPV hit:
242
243 // 1. find pad response and
244 gMC->CurrentVolOffID(3,moduleNumber);
245 moduleNumber--;
246
247 TClonesArray *cpvDigits = new TClonesArray("AliPHOSCPVDigit",0); // array of digits for current hit
90cceaf6 248 CPVDigitize(pmom,xyd,cpvDigits);
fa412d9b 249
9688c1dd 250 Float_t xmean = 0;
251 Float_t zmean = 0;
252 Float_t qsum = 0;
253 Int_t idigit,ndigits;
254
255 // 2. go through the current digit list and sum digits in pads
256
257 ndigits = cpvDigits->GetEntriesFast();
258 for (idigit=0; idigit<ndigits-1; idigit++) {
29b077b5 259 AliPHOSCPVDigit *cpvDigit1 = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(idigit));
9688c1dd 260 Float_t x1 = cpvDigit1->GetXpad() ;
261 Float_t z1 = cpvDigit1->GetYpad() ;
262 for (Int_t jdigit=idigit+1; jdigit<ndigits; jdigit++) {
29b077b5 263 AliPHOSCPVDigit *cpvDigit2 = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(jdigit));
9688c1dd 264 Float_t x2 = cpvDigit2->GetXpad() ;
265 Float_t z2 = cpvDigit2->GetYpad() ;
266 if (x1==x2 && z1==z2) {
ad4aeaf4 267 Float_t qsumpad = cpvDigit1->GetQpad() + cpvDigit2->GetQpad() ;
268 cpvDigit2->SetQpad(qsumpad) ;
9688c1dd 269 cpvDigits->RemoveAt(idigit) ;
fa412d9b 270 }
271 }
9688c1dd 272 }
273 cpvDigits->Compress() ;
274
275 // 3. add digits to temporary hit list fTmpHits
276
277 ndigits = cpvDigits->GetEntriesFast();
278 for (idigit=0; idigit<ndigits; idigit++) {
29b077b5 279 AliPHOSCPVDigit *cpvDigit = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(idigit));
9688c1dd 280 relid[0] = moduleNumber + 1 ; // CPV (or PHOS) module number
281 relid[1] =-1 ; // means CPV
282 relid[2] = cpvDigit->GetXpad() ; // column number of a pad
283 relid[3] = cpvDigit->GetYpad() ; // row number of a pad
284
285 // get the absolute Id number
286 GetGeometry()->RelToAbsNumbering(relid, absid) ;
287
288 // add current digit to the temporary hit list
289
471193a8 290 xyzte[3] = gMC->TrackTime() ;
291 xyzte[4] = cpvDigit->GetQpad() ; // amplitude in a pad
2af5445a 292
293 Int_t primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
294 AddHit(fIshunt, primary, absid, xyzte);
9688c1dd 295
296 if (cpvDigit->GetQpad() > 0.02) {
297 xmean += cpvDigit->GetQpad() * (cpvDigit->GetXpad() + 0.5);
298 zmean += cpvDigit->GetQpad() * (cpvDigit->GetYpad() + 0.5);
299 qsum += cpvDigit->GetQpad();
fa412d9b 300 }
fa412d9b 301 }
e534a69d 302 if (cpvDigits) {
303 cpvDigits->Delete();
304 delete cpvDigits;
305 cpvDigits=0;
306 }
9688c1dd 307 }
037cc66d 308
9688c1dd 309
d6fb41ac 310 static Int_t idPXTL = gMC->VolId("PXTL");
311 if(gMC->CurrentVolID(copy) == idPXTL ) { // We are inside a PBWO crystal
9688c1dd 312
fa412d9b 313 gMC->TrackPosition(pos) ;
471193a8 314 xyzte[0] = pos[0] ;
315 xyzte[1] = pos[1] ;
316 xyzte[2] = pos[2] ;
597e6309 317
9688c1dd 318 Float_t global[3], local[3] ;
319 global[0] = pos[0] ;
320 global[1] = pos[1] ;
321 global[2] = pos[2] ;
322 Float_t lostenergy = gMC->Edep();
f6d1e5e1 323
324 //Put in the TreeK particle entering PHOS and all its parents
325 if ( gMC->IsTrackEntering() ){
326 Float_t xyzd[3] ;
471193a8 327 gMC -> Gmtod (xyzte, xyzd, 1); // transform coordinate from master to daughter system
97c3e101 328 if (xyzd[1] < -GetGeometry()->GetCrystalSize(1)/2.+0.1){ //Entered close to forward surface
5d12ce38 329 Int_t parent = gAlice->GetMCApp()->GetCurrentTrackNumber() ;
81d4c3d5 330 TParticle * part = gAlice->GetMCApp()->Particle(parent) ;
331 Float_t vert[3],vertd[3] ;
332 vert[0]=part->Vx() ;
333 vert[1]=part->Vy() ;
334 vert[2]=part->Vz() ;
335 gMC -> Gmtod (vert, vertd, 1); // transform coordinate from master to daughter system
2af5445a 336 if(vertd[1]<-GetGeometry()->GetCrystalSize(1)/2.-0.1){ //Particle is created in foront of PHOS
337 //0.1 to get rid of numerical errors
338 part->SetBit(kKeepBit);
81d4c3d5 339 while ( parent != -1 ) {
340 part = gAlice->GetMCApp()->Particle(parent) ;
81d4c3d5 341 part->SetBit(kKeepBit);
342 parent = part->GetFirstMother() ;
343 }
f6d1e5e1 344 }
345 }
346 }
9688c1dd 347 if ( lostenergy != 0 ) { // Track is inside the crystal and deposits some energy
471193a8 348 xyzte[3] = gMC->TrackTime() ;
f6d1e5e1 349
9688c1dd 350 gMC->CurrentVolOffID(10, moduleNumber) ; // get the PHOS module number ;
7b326aac 351
9688c1dd 352 Int_t strip ;
353 gMC->CurrentVolOffID(3, strip);
354 Int_t cell ;
355 gMC->CurrentVolOffID(2, cell);
f6d1e5e1 356
9688c1dd 357 Int_t row = 1 + GetGeometry()->GetNZ() - strip % GetGeometry()->GetNZ() ;
358 Int_t col = (Int_t) TMath::Ceil((Double_t) strip/GetGeometry()->GetNZ()) -1 ;
f6d1e5e1 359
9688c1dd 360 absid = (moduleNumber-1)*GetGeometry()->GetNCristalsInModule() +
361 row + (col*GetGeometry()->GetEMCAGeometry()->GetNCellsInStrip() + cell-1)*GetGeometry()->GetNZ() ;
f6d1e5e1 362
9688c1dd 363 gMC->Gmtod(global, local, 1) ;
364
471193a8 365 //Calculates the light yield, the number of photons produced in the
9688c1dd 366 //crystal
27f33ee5 367 Float_t lightYield = gRandom->Poisson(fLightFactor * lostenergy *
9688c1dd 368 exp(-fLightYieldAttenuation *
369 (local[1]+GetGeometry()->GetCrystalSize(1)/2.0 ))
370 ) ;
471193a8 371
9688c1dd 372 //Calculates de energy deposited in the crystal
471193a8 373 xyzte[4] = fAPDFactor * lightYield ;
9688c1dd 374
2af5445a 375 Int_t primary ;
376 if(fIshunt == 2){
377 primary = gAlice->GetMCApp()->GetCurrentTrackNumber() ;
378 TParticle * part = gAlice->GetMCApp()->Particle(primary) ;
379 while ( !part->TestBit(kKeepBit) ) {
380 primary = part->GetFirstMother() ;
381 if(primary == -1){
382 primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
383 break ; //there is a possibility that particle passed e.g. thermal isulator and hits a side
384 //surface of the crystal. In this case it may have no primary at all.
385 //We can not easily separate this case from the case when this is part of the shower,
386 //developed in the neighboring crystal.
387 }
388 part = gAlice->GetMCApp()->Particle(primary) ;
389 }
5a49626b 390 }
2af5445a 391 else
392 primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
5a49626b 393
2af5445a 394
395
9688c1dd 396 // add current hit to the hit list
21cd0c07 397 // Info("StepManager","%d %d", primary, tracknumber) ;
2af5445a 398 AddHit(fIshunt, primary, absid, xyzte);
184569b0 399
fa412d9b 400 } // there is deposited energy
401 } // we are inside a PHOS Xtal
f6d1e5e1 402
fa412d9b 403}
404
405//____________________________________________________________________________
90cceaf6 406void AliPHOSv1::CPVDigitize (TLorentzVector p, Float_t *zxhit, TClonesArray *cpvDigits)
fa412d9b 407{
408 // ------------------------------------------------------------------------
409 // Digitize one CPV hit:
410 // On input take exact 4-momentum p and position zxhit of the hit,
411 // find the pad response around this hit and
412 // put the amplitudes in the pads into array digits
413 //
414 // Author: Yuri Kharlov (after Serguei Sadovsky)
415 // 2 October 2000
416 // ------------------------------------------------------------------------
417
fa7cce36 418 const Float_t kCelWr = GetGeometry()->GetPadSizePhi()/2; // Distance between wires (2 wires above 1 pad)
a3dfe79c 419 const Float_t kDetR = 0.1; // Relative energy fluctuation in track for 100 e-
420 const Float_t kdEdx = 4.0; // Average energy loss in CPV;
421 const Int_t kNgamz = 5; // Ionization size in Z
422 const Int_t kNgamx = 9; // Ionization size in Phi
423 const Float_t kNoise = 0.03; // charge noise in one pad
fa412d9b 424
425 Float_t rnor1,rnor2;
426
427 // Just a reminder on axes notation in the CPV module:
428 // axis Z goes along the beam
429 // axis X goes across the beam in the module plane
430 // axis Y is a normal to the module plane showing from the IP
431
432 Float_t hitX = zxhit[0];
433 Float_t hitZ =-zxhit[1];
434 Float_t pX = p.Px();
435 Float_t pZ =-p.Pz();
436 Float_t pNorm = p.Py();
a3dfe79c 437 Float_t eloss = kdEdx;
3d402178 438
21cd0c07 439//Info("CPVDigitize", "YVK : %f %f | %f %f %d", hitX, hitZ, pX, pZ, pNorm) ;
7b326aac 440
fa7cce36 441 Float_t dZY = pZ/pNorm * GetGeometry()->GetCPVGasThickness();
442 Float_t dXY = pX/pNorm * GetGeometry()->GetCPVGasThickness();
fa412d9b 443 gRandom->Rannor(rnor1,rnor2);
a3dfe79c 444 eloss *= (1 + kDetR*rnor1) *
fa7cce36 445 TMath::Sqrt((1 + ( pow(dZY,2) + pow(dXY,2) ) / pow(GetGeometry()->GetCPVGasThickness(),2)));
446 Float_t zhit1 = hitZ + GetGeometry()->GetCPVActiveSize(1)/2 - dZY/2;
447 Float_t xhit1 = hitX + GetGeometry()->GetCPVActiveSize(0)/2 - dXY/2;
fa412d9b 448 Float_t zhit2 = zhit1 + dZY;
449 Float_t xhit2 = xhit1 + dXY;
450
a3dfe79c 451 Int_t iwht1 = (Int_t) (xhit1 / kCelWr); // wire (x) coordinate "in"
452 Int_t iwht2 = (Int_t) (xhit2 / kCelWr); // wire (x) coordinate "out"
fa412d9b 453
454 Int_t nIter;
455 Float_t zxe[3][5];
456 if (iwht1==iwht2) { // incline 1-wire hit
457 nIter = 2;
458 zxe[0][0] = (zhit1 + zhit2 - dZY*0.57735) / 2;
a3dfe79c 459 zxe[1][0] = (iwht1 + 0.5) * kCelWr;
460 zxe[2][0] = eloss/2;
fa412d9b 461 zxe[0][1] = (zhit1 + zhit2 + dZY*0.57735) / 2;
a3dfe79c 462 zxe[1][1] = (iwht1 + 0.5) * kCelWr;
463 zxe[2][1] = eloss/2;
fa412d9b 464 }
465 else if (TMath::Abs(iwht1-iwht2) != 1) { // incline 3-wire hit
466 nIter = 3;
467 Int_t iwht3 = (iwht1 + iwht2) / 2;
a3dfe79c 468 Float_t xwht1 = (iwht1 + 0.5) * kCelWr; // wire 1
469 Float_t xwht2 = (iwht2 + 0.5) * kCelWr; // wire 2
470 Float_t xwht3 = (iwht3 + 0.5) * kCelWr; // wire 3
fa412d9b 471 Float_t xwr13 = (xwht1 + xwht3) / 2; // center 13
472 Float_t xwr23 = (xwht2 + xwht3) / 2; // center 23
473 Float_t dxw1 = xhit1 - xwr13;
474 Float_t dxw2 = xhit2 - xwr23;
a3dfe79c 475 Float_t egm1 = TMath::Abs(dxw1) / ( TMath::Abs(dxw1) + TMath::Abs(dxw2) + kCelWr );
476 Float_t egm2 = TMath::Abs(dxw2) / ( TMath::Abs(dxw1) + TMath::Abs(dxw2) + kCelWr );
477 Float_t egm3 = kCelWr / ( TMath::Abs(dxw1) + TMath::Abs(dxw2) + kCelWr );
fa412d9b 478 zxe[0][0] = (dXY*(xwr13-xwht1)/dXY + zhit1 + zhit1) / 2;
479 zxe[1][0] = xwht1;
a3dfe79c 480 zxe[2][0] = eloss * egm1;
fa412d9b 481 zxe[0][1] = (dXY*(xwr23-xwht1)/dXY + zhit1 + zhit2) / 2;
482 zxe[1][1] = xwht2;
a3dfe79c 483 zxe[2][1] = eloss * egm2;
fa412d9b 484 zxe[0][2] = dXY*(xwht3-xwht1)/dXY + zhit1;
485 zxe[1][2] = xwht3;
a3dfe79c 486 zxe[2][2] = eloss * egm3;
fa412d9b 487 }
488 else { // incline 2-wire hit
489 nIter = 2;
a3dfe79c 490 Float_t xwht1 = (iwht1 + 0.5) * kCelWr;
491 Float_t xwht2 = (iwht2 + 0.5) * kCelWr;
fa412d9b 492 Float_t xwr12 = (xwht1 + xwht2) / 2;
493 Float_t dxw1 = xhit1 - xwr12;
494 Float_t dxw2 = xhit2 - xwr12;
495 Float_t egm1 = TMath::Abs(dxw1) / ( TMath::Abs(dxw1) + TMath::Abs(dxw2) );
496 Float_t egm2 = TMath::Abs(dxw2) / ( TMath::Abs(dxw1) + TMath::Abs(dxw2) );
497 zxe[0][0] = (zhit1 + zhit2 - dZY*egm1) / 2;
498 zxe[1][0] = xwht1;
a3dfe79c 499 zxe[2][0] = eloss * egm1;
fa412d9b 500 zxe[0][1] = (zhit1 + zhit2 + dZY*egm2) / 2;
501 zxe[1][1] = xwht2;
a3dfe79c 502 zxe[2][1] = eloss * egm2;
fa412d9b 503 }
bea63bea 504
fa412d9b 505 // Finite size of ionization region
506
fa7cce36 507 Int_t nCellZ = GetGeometry()->GetNumberOfCPVPadsZ();
508 Int_t nCellX = GetGeometry()->GetNumberOfCPVPadsPhi();
a3dfe79c 509 Int_t nz3 = (kNgamz+1)/2;
510 Int_t nx3 = (kNgamx+1)/2;
511 cpvDigits->Expand(nIter*kNgamx*kNgamz);
29b077b5 512 TClonesArray &ldigits = *(static_cast<TClonesArray *>(cpvDigits));
fa412d9b 513
514 for (Int_t iter=0; iter<nIter; iter++) {
515
516 Float_t zhit = zxe[0][iter];
517 Float_t xhit = zxe[1][iter];
518 Float_t qhit = zxe[2][iter];
fa7cce36 519 Float_t zcell = zhit / GetGeometry()->GetPadSizeZ();
520 Float_t xcell = xhit / GetGeometry()->GetPadSizePhi();
fa412d9b 521 if ( zcell<=0 || xcell<=0 ||
522 zcell>=nCellZ || xcell>=nCellX) return;
523 Int_t izcell = (Int_t) zcell;
524 Int_t ixcell = (Int_t) xcell;
525 Float_t zc = zcell - izcell - 0.5;
526 Float_t xc = xcell - ixcell - 0.5;
a3dfe79c 527 for (Int_t iz=1; iz<=kNgamz; iz++) {
fa412d9b 528 Int_t kzg = izcell + iz - nz3;
529 if (kzg<=0 || kzg>nCellZ) continue;
530 Float_t zg = (Float_t)(iz-nz3) - zc;
a3dfe79c 531 for (Int_t ix=1; ix<=kNgamx; ix++) {
fa412d9b 532 Int_t kxg = ixcell + ix - nx3;
533 if (kxg<=0 || kxg>nCellX) continue;
534 Float_t xg = (Float_t)(ix-nx3) - xc;
535
536 // Now calculate pad response
537 Float_t qpad = CPVPadResponseFunction(qhit,zg,xg);
a3dfe79c 538 qpad += kNoise*rnor2;
fa412d9b 539 if (qpad<0) continue;
540
541 // Fill the array with pad response ID and amplitude
3d402178 542 new(ldigits[cpvDigits->GetEntriesFast()]) AliPHOSCPVDigit(kxg,kzg,qpad);
fa412d9b 543 }
fa412d9b 544 }
fa412d9b 545 }
546}
547
548//____________________________________________________________________________
549Float_t AliPHOSv1::CPVPadResponseFunction(Float_t qhit, Float_t zhit, Float_t xhit) {
550 // ------------------------------------------------------------------------
551 // Calculate the amplitude in one CPV pad using the
552 // cumulative pad response function
553 // Author: Yuri Kharlov (after Serguei Sadovski)
554 // 3 October 2000
555 // ------------------------------------------------------------------------
556
fa7cce36 557 Double_t dz = GetGeometry()->GetPadSizeZ() / 2;
558 Double_t dx = GetGeometry()->GetPadSizePhi() / 2;
559 Double_t z = zhit * GetGeometry()->GetPadSizeZ();
560 Double_t x = xhit * GetGeometry()->GetPadSizePhi();
fa412d9b 561 Double_t amplitude = qhit *
562 (CPVCumulPadResponse(z+dz,x+dx) - CPVCumulPadResponse(z+dz,x-dx) -
563 CPVCumulPadResponse(z-dz,x+dx) + CPVCumulPadResponse(z-dz,x-dx));
564 return (Float_t)amplitude;
7587f5a5 565}
566
fa412d9b 567//____________________________________________________________________________
568Double_t AliPHOSv1::CPVCumulPadResponse(Double_t x, Double_t y) {
569 // ------------------------------------------------------------------------
570 // Cumulative pad response function
571 // It includes several terms from the CF decomposition in electrostatics
572 // Note: this cumulative function is wrong since omits some terms
573 // but the cell amplitude obtained with it is correct because
574 // these omitting terms cancel
575 // Author: Yuri Kharlov (after Serguei Sadovski)
576 // 3 October 2000
577 // ------------------------------------------------------------------------
578
a3dfe79c 579 const Double_t kA=1.0;
580 const Double_t kB=0.7;
fa412d9b 581
582 Double_t r2 = x*x + y*y;
583 Double_t xy = x*y;
584 Double_t cumulPRF = 0;
585 for (Int_t i=0; i<=4; i++) {
a3dfe79c 586 Double_t b1 = (2*i + 1) * kB;
fa412d9b 587 cumulPRF += TMath::Power(-1,i) * TMath::ATan( xy / (b1*TMath::Sqrt(b1*b1 + r2)) );
588 }
a3dfe79c 589 cumulPRF *= kA/(2*TMath::Pi());
fa412d9b 590 return cumulPRF;
591}
7eb9d12d 592