Remove stdio.h (item 2 of EFFECTIVE C++)
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv3.cxx
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
16 /* $Id$ */
17
18 //_________________________________________________________________________
19 // Implementation version v0 of PHOS Manager class 
20 // Layout EMC + PPSD has name GPS2  
21 // The main goal of this version of AliPHOS is to calculte the 
22 //  induced charged in the PIN diode, taking into account light
23 //  tracking in the PbWO4 crystal, induced signal in the 
24 //  PIN due to MIPS particle and electronic noise.
25 // This is done in the StepManager 
26 //                  
27 //*-- Author:  Odd Harald Odland & Gines Martinez (SUBATECH)
28
29
30 // --- ROOT system ---
31 #include "TRandom.h"
32
33 // --- Standard library ---
34
35 #include <string.h>
36 #include <stdlib.h>
37 #include <strstream.h>
38
39 // --- AliRoot header files ---
40
41 #include "AliPHOSv3.h"
42 #include "AliPHOSHit.h"
43 #include "AliPHOSCPVDigit.h"
44 #include "AliRun.h"
45 #include "AliConst.h"
46 #include "AliMC.h"
47 #include "AliPHOSGeometry.h"
48
49 ClassImp(AliPHOSv3)
50
51 //____________________________________________________________________________
52   AliPHOSv3::AliPHOSv3(void) : AliPHOSv1() 
53 {
54   // default ctor: initialize daa members
55
56   fLightYieldMean         = 0. ;         
57   fIntrinsicPINEfficiency = 0. ; 
58   fLightYieldAttenuation  = 0. ;  
59   fRecalibrationFactor    = 0. ;    
60   fElectronsPerGeV        = 0. ;
61   fAPDGain                = 0. ;    
62   
63 }
64
65 //____________________________________________________________________________
66   AliPHOSv3::AliPHOSv3(const char *name, const char *title):
67 AliPHOSv1(name,title)
68 {
69   // ctor 
70
71   // The light yield is a poissonian distribution of the number of
72   // photons created in the PbWo4 crystal, calculated using following formula
73   // NumberOfPhotons = EnergyLost * LightYieldMean* APDEfficiency * 
74   //              exp (-LightYieldAttenuation * DistanceToPINdiodeFromTheHit);
75   // LightYieldMean is parameter calculated to be over 47000 photons per GeV  
76   // APDEfficiency is 0.02655
77   // k_0 is 0.0045 from Valery Antonenko 
78   // The number of electrons created in the APD is 
79   // NumberOfElectrons = APDGain * LightYield
80   // The APD Gain is 300
81
82   fLightYieldMean = 47000;
83   fIntrinsicPINEfficiency = 0.02655 ; //APD= 0.1875/0.1271 * 0.018 (PIN)
84   fLightYieldAttenuation = 0.0045 ; 
85   fRecalibrationFactor = 13.418/ fLightYieldMean ;
86   fElectronsPerGeV = 2.77e+8 ;
87   fAPDGain= 300. ;
88 }
89
90 // //____________________________________________________________________________
91 // AliPHOSv3::AliPHOSv3(AliPHOSReconstructioner * Reconstructioner, const char *name, const char *title):
92 //   AliPHOSv1(Reconstructioner,name,title)
93 // {
94 //   // ctor 
95
96 //   // Number of electrons created in the PIN due to light collected in the PbWo4 crystal is calculated using 
97 //   // following formula
98 //   // NumberOfElectrons = EnergyLost * LightYield * PINEfficiency * 
99 //   //                     exp (-LightYieldAttenuation * DistanceToPINdiodeFromTheHit) *
100 //   //                     RecalibrationFactor ;
101 //   // LightYield is obtained as a Poissonian distribution with a mean at 700000 photons per GeV fromValery Antonenko
102 //   // PINEfficiency is 0.1875 
103 //   // k_0 is 0.0045 from Valery Antonenko 
104
105 //   fLightYieldMean = 700000.;
106 //   fIntrinsicPINEfficiency = 0.1875 ;
107 //   fLightYieldAttenuation = 0.0045 ;
108 //   fRecalibrationFactor = 6.2 / fLightYieldMean ;
109 //   fRecalibrationFactor = 5.67 /fLightYieldMean ;//25.04.2001 OHO
110 //   fElectronsPerGeV = 2.77e+8 ;
111 // }
112 //____________________________________________________________________________
113
114 void AliPHOSv3::StepManager(void)
115 {
116   // Accumulates hits as long as the track stays in a single crystal or PPSD gas Cell
117
118 //    if (gMC->IsTrackEntering())
119 //      cout << "Track enters the volume " << gMC->CurrentVolName() << endl;
120 //    if (gMC->IsTrackExiting())
121 //      cout << "Track leaves the volume " << gMC->CurrentVolName() << endl;
122
123   Int_t          relid[4] ;        // (box, layer, row, column) indices
124   Int_t          absid    ;        // absolute cell ID number
125   Float_t        xyze[4]={0,0,0,0}  ; // position wrt MRS and energy deposited
126
127   TLorentzVector pos      ;     // Lorentz vector of the track current position
128   Int_t          copy     ;
129   Float_t        fLightYield ;   // Light Yield per GeV
130
131   Int_t tracknumber =  gAlice->CurrentTrack() ; 
132   Int_t primary     =  gAlice->GetPrimary( gAlice->CurrentTrack() ); 
133   TString name      =  GetGeometry()->GetName() ; 
134   Float_t        lostenergy ;
135   Float_t        global[3] ;
136   Float_t        local[3] ;
137
138
139   if ( name == "GPS2" || name == "MIXT" ) {            // ======> CPV is a GPS' PPSD
140
141     if( gMC->CurrentVolID(copy) == gMC->VolId("PPCE") ) // We are inside a gas cell 
142     {
143       gMC->TrackPosition(pos) ;
144       xyze[0] = pos[0] ;
145       xyze[1] = pos[1] ;
146       xyze[2] = pos[2] ;
147       xyze[3] = gMC->Edep() ; 
148
149       if ( xyze[3] != 0) { // there is deposited energy 
150         gMC->CurrentVolOffID(5, relid[0]) ;  // get the PHOS Module number
151         if ( name == "MIXT" && strcmp(gMC->CurrentVolOffName(5),"PHO1") == 0 ){
152           relid[0] += GetGeometry()->GetNModules() - GetGeometry()->GetNPPSDModules();
153         }
154         gMC->CurrentVolOffID(3, relid[1]) ;  // get the Micromegas Module number 
155       // 1-> GetGeometry()->GetNumberOfModulesPhi() * GetGeometry()->GetNumberOfModulesZ() upper
156       //   > GetGeometry()->GetNumberOfModulesPhi() * GetGeometry()->GetNumberOfModulesZ() lower
157         gMC->CurrentVolOffID(1, relid[2]) ;  // get the row number of the cell
158         gMC->CurrentVolID(relid[3]) ;        // get the column number 
159
160         // get the absolute Id number
161
162         GetGeometry()->RelToAbsNumbering(relid, absid) ; 
163
164         // add current hit to the hit list      
165           AddHit(fIshunt, primary, tracknumber, absid, xyze);
166
167
168       } // there is deposited energy 
169     } // We are inside the gas of the CPV  
170   } // GPS2 configuration
171
172   if ( name == "IHEP" || name == "MIXT" ) {       // ======> CPV is a IHEP's one
173
174     // Yuri Kharlov, 28 September 2000
175
176     if( gMC->CurrentVolID(copy) == gMC->VolId("PCPQ") &&
177         gMC->IsTrackEntering()  &&
178         gMC->TrackCharge() != 0) {      
179
180       gMC -> TrackPosition(pos);
181       Float_t xyzm[3], xyzd[3] ;
182       Int_t i;
183       for (i=0; i<3; i++) xyzm[i] = pos[i];
184       gMC -> Gmtod (xyzm, xyzd, 1);    // transform coordinate from master to daughter system
185
186       Float_t        xyd[3]={0,0,0}   ;   //local posiiton of the entering
187       xyd[0]  = xyzd[0];
188       xyd[1]  =-xyzd[1];
189       xyd[2]  =-xyzd[2];
190
191       
192       // Current momentum of the hit's track in the local ref. system
193         TLorentzVector pmom     ;        //momentum of the particle initiated hit
194       gMC -> TrackMomentum(pmom);
195       Float_t pm[3], pd[3];
196       for (i=0; i<3; i++) pm[i]   = pmom[i];
197       gMC -> Gmtod (pm, pd, 2);        // transform 3-momentum from master to daughter system
198       pmom[0] = pd[0];
199       pmom[1] =-pd[1];
200       pmom[2] =-pd[2];
201       
202       // Digitize the current CPV hit:
203
204       // 1. find pad response and
205       
206       Int_t moduleNumber;
207       gMC->CurrentVolOffID(3,moduleNumber);
208       moduleNumber--;
209
210
211       TClonesArray *cpvDigits = new TClonesArray("AliPHOSCPVDigit",0);   // array of digits for current hit
212       CPVDigitize(pmom,xyd,moduleNumber,cpvDigits);
213       
214       Float_t xmean = 0;
215       Float_t zmean = 0;
216       Float_t qsum  = 0;
217       Int_t   idigit,ndigits;
218
219       // 2. go through the current digit list and sum digits in pads
220
221       ndigits = cpvDigits->GetEntriesFast();
222       for (idigit=0; idigit<ndigits-1; idigit++) {
223         AliPHOSCPVDigit  *cpvDigit1 = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(idigit));
224         Float_t x1 = cpvDigit1->GetXpad() ;
225         Float_t z1 = cpvDigit1->GetYpad() ;
226         for (Int_t jdigit=idigit+1; jdigit<ndigits; jdigit++) {
227           AliPHOSCPVDigit  *cpvDigit2 = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(jdigit));
228           Float_t x2 = cpvDigit2->GetXpad() ;
229           Float_t z2 = cpvDigit2->GetYpad() ;
230           if (x1==x2 && z1==z2) {
231             Float_t qsum = cpvDigit1->GetQpad() + cpvDigit2->GetQpad() ;
232             cpvDigit2->SetQpad(qsum) ;
233             cpvDigits->RemoveAt(idigit) ;
234           }
235         }
236       }
237       cpvDigits->Compress() ;
238
239       // 3. add digits to temporary hit list fTmpHits
240
241       ndigits = cpvDigits->GetEntriesFast();
242       for (idigit=0; idigit<ndigits; idigit++) {
243         AliPHOSCPVDigit  *cpvDigit = dynamic_cast<AliPHOSCPVDigit*>(cpvDigits->UncheckedAt(idigit));
244         relid[0] = moduleNumber + 1 ;                             // CPV (or PHOS) module number
245         relid[1] =-1 ;                                            // means CPV
246         relid[2] = cpvDigit->GetXpad() ;                          // column number of a pad
247         relid[3] = cpvDigit->GetYpad() ;                          // row    number of a pad
248         
249         // get the absolute Id number
250         GetGeometry()->RelToAbsNumbering(relid, absid) ; 
251
252         // add current digit to the temporary hit list
253         xyze[0] = 0. ;
254         xyze[1] = 0. ;
255         xyze[2] = 0. ;
256         xyze[3] = cpvDigit->GetQpad() ;                           // amplitude in a pad
257         primary = -1;                                             // No need in primary for CPV
258         AddHit(fIshunt, primary, tracknumber, absid, xyze);
259
260         if (cpvDigit->GetQpad() > 0.02) {
261           xmean += cpvDigit->GetQpad() * (cpvDigit->GetXpad() + 0.5);
262           zmean += cpvDigit->GetQpad() * (cpvDigit->GetYpad() + 0.5);
263           qsum  += cpvDigit->GetQpad();
264         }
265       }
266       delete cpvDigits;
267     }
268   } // end of IHEP configuration
269   
270
271 if(gMC->CurrentVolID(copy)==gMC->VolId("PXTL")){// We are inside a PBWO4 crystal
272     gMC->TrackPosition(pos) ;
273     xyze[0] = pos[0] ;
274     xyze[1] = pos[1] ;
275     xyze[2] = pos[2] ;
276     global[0] = pos[0] ;
277     global[1] = pos[1] ;
278     global[2] = pos[2] ;
279     lostenergy = gMC->Edep(); 
280     xyze[3] = gMC->Edep() ;
281
282   
283   if ( (xyze[3] != 0) ){//Track is inside the crystal and deposits some energy
284
285       gMC->CurrentVolOffID(10, relid[0]) ; // get the PHOS module number ;
286
287       if ( name == "MIXT" && strcmp(gMC->CurrentVolOffName(10),"PHO1") == 0 )
288         relid[0] += GetGeometry()->GetNModules() - GetGeometry()->GetNPPSDModules();      
289
290       relid[1] = 0   ;                    // means PBW04
291    gMC->CurrentVolOffID(4, relid[2]) ; // get the row number inside the module
292    gMC->CurrentVolOffID(3, relid[3]) ; // get the cell number inside the module
293       
294       // get the absolute Id number
295
296    GetGeometry()->RelToAbsNumbering(relid, absid) ; 
297
298    gMC->Gmtod(global, local, 1) ;
299
300    //Calculates the light yield, the number of photns produced in the
301    //crystal 
302    fLightYield = gRandom->Poisson(
303                                   fLightYieldMean * lostenergy *
304                                   fIntrinsicPINEfficiency * 
305                                   exp(-fLightYieldAttenuation *
306                                       (local[1]+GetGeometry()->GetCrystalSize(1)/2.0 ))
307                                   ) ;
308    //Calculates de energy deposited in the crystal  
309    xyze[3] = (fRecalibrationFactor/100.) * fAPDGain * fLightYield  ;
310   
311     
312    // cout<<"xyze[3]:    "<<xyze[3]<<   endl;
313    //cout<<"lostenergy: "<<lostenergy<<endl; 
314
315
316         
317
318       // add current hit to the hit list
319  
320
321    if (xyze[3] != 0.) AddHit(fIshunt, primary,tracknumber, absid, xyze);
322   
323
324     } // there is deposited energy
325   } // we are inside a PHOS Xtal
326
327 //  if(gMC->CurrentVolID(copy) == gMC->VolId("PPIN"))//We are inside the PIN diode 
328 //     {
329 //       cout<<" Inside PIN "<<endl;
330 //       gMC->TrackPosition(pos) ;
331 //       global[0] = pos[0] ;
332 //       global[1] = pos[1] ;
333 //       global[2] = pos[2] ;
334 //       xyze[0] = pos[0] ;
335 //       xyze[1] = pos[1] ;
336 //       xyze[2] = pos[2] ;
337 //       lostenergy = gMC->Edep() ;
338 //       xyze[3] = gMC->Edep() ;
339       
340 //       if ( xyze[3] != 0 ) {
341 //      gMC->CurrentVolOffID(11, relid[0]) ; // get the PHOS module number ;
342 //      relid[1] = 0   ;                    // means PW04 and PIN
343 //      gMC->CurrentVolOffID(5, relid[2]) ; // get the row number inside the module
344 //      gMC->CurrentVolOffID(4, relid[3]) ; // get the cell number inside the module
345         
346 //      // get the absolute Id number
347         
348 //      Int_t absid ; 
349 //      GetGeometry()->RelToAbsNumbering(relid,absid) ;
350 //      gMC->Gmtod(global, local, 1) ;
351
352 // // calculating number of electrons in the PIN diode asociated to this hit
353
354 //        //nElectrons = lostenergy * fElectronsPerGeV ;
355 //        //  xyze[3] = nElectrons * fRecalibrationFactor ;
356 //           apdgain = gRandom->Poisson(300.) ;
357 //           // apdgain = 300.;
358 //    //if(local[1]<-0.0045) xyze[3] = apdgain * nElectrons * fRecalibrationFactor/10000.;
359
360 //     if(local[1]<-0.0045) xyze[3] = apdgain * lostenergy * fElectronsPerGeV* (fRecalibrationFactor/100.);
361
362 //    //if((local[1]>-0.0045)&&(gMC->TrackPid()==-11)) xyze[3] = apdgain * nElectrons * fRecalibrationFactor/10000.;
363
364 //      if((local[1]>-0.0045)&&(gMC->TrackPid()==-11)) xyze[3] = apdgain * lostenergy * fElectronsPerGeV * (fRecalibrationFactor/100.);
365
366 //    //if(local[1]>-0.0045) xyze[3] = nElectrons * fRecalibrationFactor/10000.;
367
368 //      if(local[1]>-0.0045) xyze[3] = lostenergy * fElectronsPerGeV * (fRecalibrationFactor/100.);
369           
370 //        // add current hit to the hit list
371
372 //        AddHit(fIshunt, primary, tracknumber, absid, xyze);
373
374 //        //printf("PIN volume is  %d, %d, %d, %d \n",relid[0],relid[1],relid[2],relid[3]);
375 //        printf("Lost energy in the PIN is %f \n",lostenergy) ;
376 //       } // there is deposited energy
377 //     } // we are inside a PHOS XtalPHOS PIN diode
378 }