]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG4/AliGammaMCDataReader.cxx
Protection against cluster labels larger than kinematics entries
[u/mrichter/AliRoot.git] / PWG4 / AliGammaMCDataReader.cxx
1
2 /**************************************************************************
3  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4  *                                                                        *
5  * Author: The ALICE Off-line Project.                                    *
6  * Contributors are mentioned in the code where appropriate.              *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16 /* $Id$ */
17
18 /* History of cvs commits:
19  *
20  * $Log$
21  * Revision 1.4  2007/10/29 13:48:42  gustavo
22  * Corrected coding violations
23  *
24  * Revision 1.2  2007/08/17 12:40:04  schutz
25  * New analysis classes by Gustavo Conesa
26  *
27  * Revision 1.1.2.1  2007/07/26 10:32:09  schutz
28  * new analysis classes in the the new analysis framework
29  *
30  *
31  */
32
33 //_________________________________________________________________________
34 // Class for reading data (Kinematics and ESDs) in order to do prompt gamma correlations
35 //  Class created from old AliPHOSGammaJet 
36 //  (see AliRoot versions previous Release 4-09)
37 //
38 //*-- Author: Gustavo Conesa (LNF-INFN) 
39 //////////////////////////////////////////////////////////////////////////////
40
41
42 // --- ROOT system ---
43 #include <TFormula.h>
44 #include <TParticle.h>
45  
46 //---- ANALYSIS system ----
47 #include "AliGammaMCDataReader.h" 
48 #include "AliESDEvent.h"
49 #include "AliESDVertex.h"
50 #include "AliESDCaloCluster.h"
51 #include "AliStack.h"
52 #include "AliLog.h"
53
54 ClassImp(AliGammaMCDataReader)
55
56 //____________________________________________________________________________
57   AliGammaMCDataReader::AliGammaMCDataReader() : 
58     AliGammaReader()
59 {
60   //Default Ctor
61   
62   //Initialize parameters
63   fDataType=kMCData;
64   
65 }
66
67 //____________________________________________________________________________
68 AliGammaMCDataReader::AliGammaMCDataReader(const AliGammaMCDataReader & g) :   
69   AliGammaReader(g)
70 {
71   // cpy ctor
72 }
73
74 //_________________________________________________________________________
75 AliGammaMCDataReader & AliGammaMCDataReader::operator = (const AliGammaMCDataReader & source)
76 {
77   // assignment operator
78   
79   if(&source == this) return *this;
80   
81
82   return *this;
83   
84 }
85
86 //____________________________________________________________________________
87 void AliGammaMCDataReader::CreateParticleList(TObject * data, TObject * kine,
88                                               TClonesArray * plCTS, 
89                                               TClonesArray * plEMCAL,  
90                                               TClonesArray * plPHOS,   
91                                               TClonesArray * plPrimCTS, 
92                                               TClonesArray * plPrimEMCAL, 
93                                               TClonesArray * plPrimPHOS){
94   
95   //Create a list of particles from the ESD. These particles have been measured 
96   //by the Central Tracking system (TPC+ITS+...), PHOS and EMCAL 
97   //Also create particle list with mothers.
98
99   AliESDEvent* esd = (AliESDEvent*) data;
100   AliStack* stack = (AliStack*) kine;
101   
102   Int_t npar  = 0 ;
103   Double_t *pid = new Double_t[AliPID::kSPECIESN];  
104   AliDebug(3,"Fill particle lists");
105   
106   //Get vertex for momentum calculation  
107   Double_t v[3] ; //vertex ;
108   esd->GetVertex()->GetXYZ(v) ; 
109   
110   //########### CALORIMETERS ##############  
111   Int_t nCaloCluster = esd->GetNumberOfCaloClusters() ;  
112   Int_t indexPH = plPHOS->GetEntries() ;
113   Int_t indexEM = plEMCAL->GetEntries() ;
114   
115   for (npar =  0; npar <  nCaloCluster; npar++) {//////////////CaloCluster loop
116     AliESDCaloCluster * clus = esd->GetCaloCluster(npar) ; // retrieve cluster from esd
117     Int_t type = clus->GetClusterType();
118     
119     //########### PHOS ##############
120     if(fSwitchOnPHOS && type ==  AliESDCaloCluster::kPHOSCluster){
121       AliDebug(4,Form("PHOS clusters: E %f, match %d", clus->E(),clus->GetTrackMatched()));
122       
123       if(clus->GetTrackMatched()==-1){
124         TLorentzVector momentum ;
125         clus->GetMomentum(momentum, v);      
126         Double_t phi = momentum.Phi();
127         if(phi<0) phi+=TMath::TwoPi() ;
128         if(momentum.Pt() > fNeutralPtCut &&  TMath::Abs(momentum.Eta()) < fPHOSEtaCut &&
129            phi > fPhiPHOSCut[0] && phi < fPhiPHOSCut[1] ) {
130           
131           pid=clus->GetPid();   
132           Int_t pdg = 22;
133           
134           if(IsPHOSPIDOn()){
135             AliDebug(5,Form("E %1.2f; PID: ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f,pi %0.2f, k %0.2f, p %0.2f, k0 %0.2f, n %0.2f, mu %0.2f ",
136                             momentum.E(),pid[AliPID::kPhoton],pid[AliPID::kPi0],pid[AliPID::kElectron],pid[AliPID::kEleCon],pid[AliPID::kPion],
137                             pid[AliPID::kKaon],pid[AliPID::kProton], pid[AliPID::kKaon0],pid[AliPID::kNeutron], pid[AliPID::kMuon]));
138             
139             Float_t wPhoton =  fPHOSPhotonWeight;
140             Float_t wPi0 =  fPHOSPi0Weight;
141             
142             if(fPHOSWeightFormula){
143               wPhoton = fPHOSPhotonWeightFormula->Eval(momentum.E()) ;
144               wPi0 =    fPHOSPi0WeightFormula->Eval(momentum.E());
145             }
146             
147             if(pid[AliPID::kPhoton] > wPhoton) 
148               pdg = kPhoton ;
149             else if(pid[AliPID::kPi0] > wPi0) 
150               pdg = kPi0 ; 
151             else if(pid[AliPID::kElectron] > fPHOSElectronWeight)  
152               pdg = kElectron ;
153             else if(pid[AliPID::kEleCon] > fPHOSElectronWeight) 
154               pdg = kEleCon ;
155             else if(pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] > fPHOSChargeWeight) 
156               pdg = kChargedHadron ;  
157             else if(pid[AliPID::kKaon0]+pid[AliPID::kNeutron] > fPHOSNeutralWeight) 
158               pdg = kNeutralHadron ; 
159             
160             else if(pid[AliPID::kElectron]+pid[AliPID::kEleCon]+pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton]  >  
161                     pid[AliPID::kPhoton] + pid[AliPID::kPi0]+pid[AliPID::kKaon0]+pid[AliPID::kNeutron]) 
162               pdg = kChargedUnknown  ; 
163             else 
164               pdg = kNeutralUnknown ; 
165             //neutral cluster, unidentifed.
166           }
167           
168           if(pdg != kElectron && pdg != kEleCon && pdg !=kChargedHadron && pdg !=kChargedUnknown ){//keep only neutral particles in the array
169
170             TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1, momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E(), v[0], v[1], v[2], 0);           
171             new((*plPHOS)[indexPH])   TParticle(*particle) ;
172             AliDebug(4,Form("PHOS added: pdg %d, pt %f, phi %f, eta %f", pdg, particle->Pt(),particle->Phi(),particle->Eta()));
173  
174             //###############
175             //Check kinematics
176             //###############
177             TParticle * pmother = new TParticle();
178             Int_t label = clus->GetLabel();
179             if(label < stack->GetNprimary())
180               pmother = GetMotherParticle(label,stack, "PHOS",momentum);
181             else 
182               AliInfo(Form("PHOS: Bad label %d, too large, NPrimaries %d",label,stack->GetNprimary()));
183             new((*plPrimPHOS)[indexPH])   TParticle(*pmother) ;
184             
185             indexPH++;
186           }
187           else AliDebug(4,Form("PHOS charged cluster NOT added: pdg %d, pt %f, phi %f, eta %f\n", 
188                                pdg, momentum.Pt(),momentum.Phi(),momentum.Eta()));      
189           
190         }//pt, eta, phi cut
191         else    AliDebug(4,"Particle not added");
192       }//track-match?
193     }//PHOS cluster
194
195     //################ EMCAL ##############
196     else if(fSwitchOnEMCAL &&  type ==  AliESDCaloCluster::kEMCALClusterv1){
197       AliDebug(4,Form("EMCAL clusters: E %f, match %d", clus->E(),clus->GetTrackMatched()));
198       
199       if(clus->GetTrackMatched()==-1 ){
200         TLorentzVector momentum ;
201         clus->GetMomentum(momentum, v); 
202         Double_t phi = momentum.Phi();
203         if(phi<0) phi+=TMath::TwoPi() ;
204         if(momentum.Pt() > fNeutralPtCut &&  TMath::Abs(momentum.Eta()) < fEMCALEtaCut &&
205            phi > fPhiEMCALCut[0] && phi < fPhiEMCALCut[1] ) {
206           
207           pid=clus->GetPid();   
208           Int_t pdg = 22;
209           
210           if(IsEMCALPIDOn()){
211             AliDebug(5,Form("E %1.2f; PID: ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f,pi %0.2f, k %0.2f, p %0.2f, k0 %0.2f, n %0.2f, mu %0.2f ",
212                             momentum.E(),pid[AliPID::kPhoton],pid[AliPID::kPi0],pid[AliPID::kElectron],pid[AliPID::kEleCon],pid[AliPID::kPion],
213                             pid[AliPID::kKaon],pid[AliPID::kProton], pid[AliPID::kKaon0],pid[AliPID::kNeutron], pid[AliPID::kMuon]));
214             
215             if(pid[AliPID::kPhoton] > fEMCALPhotonWeight) 
216               pdg = kPhoton ;
217             else if(pid[AliPID::kPi0] > fEMCALPi0Weight) 
218               pdg = kPi0 ; 
219             else if(pid[AliPID::kElectron] > fEMCALElectronWeight)  
220               pdg = kElectron ;
221             else if(pid[AliPID::kEleCon] > fEMCALElectronWeight) 
222               pdg = kEleCon ;
223             else if(pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton] > fEMCALChargeWeight) 
224               pdg = kChargedHadron ;  
225             else if(pid[AliPID::kKaon0]+pid[AliPID::kNeutron] > fEMCALNeutralWeight) 
226               pdg = kNeutralHadron ; 
227             else if(pid[AliPID::kElectron]+pid[AliPID::kEleCon]+pid[AliPID::kPion]+pid[AliPID::kKaon]+pid[AliPID::kProton]  >  
228                     pid[AliPID::kPhoton] + pid[AliPID::kPi0]+pid[AliPID::kKaon0]+pid[AliPID::kNeutron]) 
229               pdg = kChargedUnknown ; 
230             else 
231               pdg = kNeutralUnknown ;
232           }
233           
234           if(pdg != kElectron && pdg != kEleCon && pdg !=kChargedHadron && pdg !=kChargedUnknown){//keep only neutral particles in the array
235
236             TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1, momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E(), v[0], v[1], v[2], 0);
237             new((*plEMCAL)[indexEM])   TParticle(*particle) ;
238             AliDebug(4,Form("EMCAL cluster added: pdg %f, pt %f, phi %f, eta %f", pdg, particle->Pt(),particle->Phi(),particle->Eta()));
239             
240             //###############
241             //Check kinematics
242             //###############
243             TParticle * pmother = new TParticle();
244             Int_t label = clus->GetLabel();
245             if(label < stack->GetNprimary())
246               pmother = GetMotherParticle(label,stack, "EMCAL",momentum);
247             else 
248               AliInfo(Form("EMCAL: Bad label %d, too large, NPrimaries %d",label,stack->GetNprimary()));            
249             new((*plPrimEMCAL)[indexEM])   TParticle(*pmother) ;
250
251             indexEM++;
252           }
253           else AliDebug(4,Form("EMCAL charged cluster NOT added: pdg %d, pt %f, phi %f, eta %f", 
254                                pdg, momentum.Pt(),momentum.Phi(),momentum.Eta()));
255           
256         }//pt, phi, eta cut
257         else    AliDebug(4,"Particle not added");
258       }//track-matched
259     }//EMCAL cluster
260
261   }//cluster loop
262
263  
264
265   //########### CTS (TPC+ITS) #####################
266   Int_t nTracks   = esd->GetNumberOfTracks() ;
267   Int_t indexCh  = plCTS->GetEntries() ;
268
269   if(fSwitchOnCTS){
270     AliDebug(3,Form("Number of tracks %d",nTracks));
271   
272     for (npar =  0; npar <  nTracks; npar++) {////////////// track loop
273       AliESDtrack * track = esd->GetTrack(npar) ; // retrieve track from esd
274       
275       //We want tracks fitted in the detectors:
276       ULong_t status=AliESDtrack::kTPCrefit;
277       status|=AliESDtrack::kITSrefit;
278     
279       //We want tracks whose PID bit is set:
280       //     ULong_t status =AliESDtrack::kITSpid;
281       //     status|=AliESDtrack::kTPCpid;
282       
283       if ( (track->GetStatus() & status) == status) {//Check if the bits we want are set
284         // Do something with the tracks which were successfully
285         // re-fitted 
286         Double_t en = 0; //track ->GetTPCsignal() ;
287         Double_t mom[3];
288         track->GetPxPyPz(mom) ;
289         Double_t px = mom[0];
290         Double_t py = mom[1];
291         Double_t pz = mom[2]; //Check with TPC people if this is correct.
292         Int_t pdg = 11; //Give any charged PDG code, in this case electron.
293         //I just want to tag the particle as charged
294         
295         //Check kinematics
296         Int_t label = TMath::Abs(track->GetLabel());
297         TParticle * pmother = new TParticle();
298         pmother = stack->Particle(label);
299         
300         TParticle * particle = new TParticle(pdg, 1, -1, -1, -1, -1, 
301                                              px, py, pz, en, v[0], v[1], v[2], 0);
302         
303         if(particle->Pt() > fChargedPtCut && TMath::Abs(particle->Eta())<fCTSEtaCut){
304           new((*plCTS)[indexCh])       TParticle(*particle) ;   
305           new((*plPrimCTS)[indexCh])       TParticle(*pmother) ;
306           indexCh++;    
307           
308         }//kinematic selection
309       }//select track from refit
310     }//track loop    
311   }//CTS
312
313   AliDebug(3,Form("Particle lists filled, tracks  %d , clusters: EMCAL %d, PHOS %d", indexCh,indexEM,indexPH));
314
315 }
316
317 TParticle * AliGammaMCDataReader:: GetMotherParticle(Int_t label, AliStack *stack, TString calo,  TLorentzVector momentum)
318 {
319   //Gets the primary particle and do some checks:
320   //Check if primary is inside calorimeter and look the mother outsie
321   //Check if mother is a decay photon, in which case check if decay was overlapped
322   
323   Float_t minangle = 0;
324   Float_t ipdist = 0;
325   TParticle * pmother = new TParticle();
326
327   if(calo == "PHOS"){
328     ipdist= fPHOSIPDistance;
329     minangle = fPHOSMinAngle; 
330   }
331   else if (calo == "EMCAL"){
332     ipdist = fEMCALIPDistance;
333     minangle = fEMCALMinAngle;
334   }
335
336
337   if(label>=0){
338     pmother = stack->Particle(label);
339     Int_t mostatus = pmother->GetStatusCode();
340     Int_t mopdg    = TMath::Abs(pmother->GetPdgCode());
341     
342     //Check if mother is a conversion inside the calorimeter
343     //In such case, return the mother before the calorimeter.
344     //First approximation.
345     Float_t vy = TMath::Abs(pmother->Vy()) ;
346
347     if( mostatus == 0 && vy >= ipdist){
348
349       //cout<<"Calo: "<<calo<<" vy "<<vy<<" E clus "<<momentum.E()<<" Emother "<<pmother->Energy()<<" "
350       //  <<pmother->GetName()<<endl;
351
352       while( vy >= ipdist){//inside calorimeter
353         AliDebug(4,Form("Conversion inside calorimeter, mother vertex %0.2f, IP distance %0.2f", vy, ipdist));
354         pmother =  stack->Particle(pmother->GetMother(0));
355         vy = TMath::Abs(pmother->Vy()) ;
356         //cout<<" label "<<label<<" Mother: "<<pmother->GetName()<<" E "<<pmother->Energy()<<" Status "<<pmother->GetStatusCode()<<"  and vertex "<<vy<<endl;
357         mostatus = pmother->GetStatusCode();
358         mopdg    = TMath::Abs(pmother->GetPdgCode());
359       }//while vertex is inside calorimeter
360       //cout<<"Calo: "<<calo<<" final vy "<<vy<<" E clus "<<momentum.E()<<" Emother "<<pmother->Energy()<<" "
361       //  <<pmother->GetName()<<endl;
362     }//check status and vertex
363
364     AliDebug(4,Form("%s, ESD E %2.2f, PID %d,  mother: E %2.2f, label %d, status %d,  vertex %3.2f, mother 2 %d, grandmother %d \n",
365                     calo.Data(),momentum.E(),pmother->Energy(), label, pmother->GetPdgCode(),
366                     pmother->GetStatusCode(), vy, pmother->GetMother(0), stack->GetPrimary(label)));
367     
368     //Check Decay photons
369     if(mopdg == 22){
370       
371       //his mother was a pi0?
372       TParticle * pmotherpi0 =  stack->Particle(pmother->GetMother(0));
373       if( pmotherpi0->GetPdgCode() == 111){
374
375         AliDebug(4,Form(" %s: E cluster %2.2f, E gamma %2.2f, Mother Pi0, E %0.2f, status %d, daughters %d\n",
376                         calo.Data(), momentum.E(),pmother->Energy(),pmotherpi0->Energy(), 
377                         pmotherpi0->GetStatusCode(), pmotherpi0->GetNDaughters()));
378         
379         if(pmotherpi0->GetNDaughters() == 1) mostatus = 2 ; //signal that this photon can only be decay, not overlapped.
380         else if(pmotherpi0->GetNDaughters() == 2){
381           
382           TParticle * pd1 = stack->Particle(pmotherpi0->GetDaughter(0));
383           TParticle * pd2 = stack->Particle(pmotherpi0->GetDaughter(1));
384           //if(pmotherpi0->Energy()> 10 ){
385 //        cout<<"Two "<<calo<<" daugthers, pi0 label "<<pmother->GetMother(0)<<" E :"<<pmotherpi0->Energy()<<endl;
386 //        cout<<" 1) label "<<pmotherpi0->GetDaughter(0)<<" pdg "<<pd1->GetPdgCode()<<" E  "<<pd1->Energy()
387 //            <<" phi "<<pd1->Phi()*TMath::RadToDeg()<<" eta "<<pd1->Eta()
388 //            <<" mother label "<<pd1->GetMother(0)<<" n daug "<<pd1->GetNDaughters() <<endl;
389 //          cout<<" 2) label "<<pmotherpi0->GetDaughter(1)<<" pdg "<<pd2->GetPdgCode()<<" E  "<<pd2->Energy()
390 //              <<" phi "<<pd2->Phi()*TMath::RadToDeg()<<" eta "<<pd2->Eta()<<" mother label "
391 //              <<pd2->GetMother(0)<<" n daug "<<pd2->GetNDaughters() <<endl;
392             //}
393           if(pd1->GetPdgCode() == 22 && pd2->GetPdgCode() == 22){
394             TLorentzVector lv1 , lv2 ;
395             pd1->Momentum(lv1);
396             pd2->Momentum(lv2);
397             Double_t angle = lv1.Angle(lv2.Vect());
398 //          if(pmotherpi0->Energy()> 10 )
399 //            cout<<"angle*ipdist "<<angle*ipdist<<" mindist "<< minangle <<endl;
400             if (angle < minangle){
401               //There is overlapping, pass the pi0 as mother
402               
403               AliDebug(4,Form(">>>> %s cluster with E %2.2f is a overlapped pi0, E %2.2f, angle %2.4f < anglemin %2.4f\n",
404                               calo.Data(), momentum.E(), pmotherpi0->Energy(), angle, minangle));           
405              
406               pmother = pmotherpi0 ;
407               
408             }
409             else mostatus = 2 ; // gamma decay not overlapped
410           }// daughters are photons
411           else mostatus = 2; // daughters are e-gamma or e-e, no overlapped, or charged cluster
412         }//2 daughters
413         else AliDebug(4,Form("pi0 has %d daughters",pmotherpi0->GetNDaughters()));
414       }//pi0 decay photon?
415     }//photon 
416
417     pmother->SetStatusCode(mostatus); // if status = 2, decay photon.
418
419   }//label >=0
420   else AliInfo(Form("Negative Kinematic label of PHOS cluster:  %d",label));
421
422   return pmother ;
423
424 }