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