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