]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG4/PartCorrBase/AliCaloPID.cxx
4dfd254a9965b7018211b09e703bd5981c14e562
[u/mrichter/AliRoot.git] / PWG4 / PartCorrBase / AliCaloPID.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 /* $Id: AliCaloPID.cxx 21839 2007-10-29 13:49:42Z gustavo $ */
16
17 //_________________________________________________________________________
18 // Class for PID selection with calorimeters
19 // The Output of the 2 main methods GetIdentifiedParticleType is a PDG number identifying the cluster, 
20 // being kPhoton, kElectron, kPi0 ... as defined in the header file
21 //   - GetIdentifiedParticleType(const TString calo, const Double_t * pid, const Float_t energy)
22 //      Reads the PID weights array of the ESDs and depending on its magnitude identifies the particle
23 //   - GetIdentifiedParticleType(const TString calo,const TLorentzVector mom, const AliVCluster * cluster)
24 //      Recalcultes PID, the bayesian or any new one to be implemented in the future
25 //      Right now only the possibility to recalculate EMCAL with bayesian and simple PID.
26 //      In order to recalculate Bayesian, it is necessary to load the EMCALUtils library
27 //      and do SwitchOnBayesianRecalculation().
28 //      To change the PID parameters from Low to High like the ones by default, use the constructor 
29 //      AliCaloPID(flux)
30 //      where flux is AliCaloPID::kLow or AliCaloPID::kHigh
31 //      If it is necessary to change the parameters use the constructor 
32 //      AliCaloPID(AliEMCALPIDUtils *utils) and set the parameters before.
33 //   - SetPIDBits: Simple PID, depending on the thresholds fL0Cut fTOFCut and even the
34 //     result of the PID bayesian a different PID bit is set. 
35 //
36 //  All these methods can be called in the analysis you are interested.
37 //
38 //*-- Author: Gustavo Conesa (LNF-INFN) 
39 //////////////////////////////////////////////////////////////////////////////
40
41
42 // --- ROOT system ---
43 #include <TMath.h>
44 #include <TString.h>
45
46 //---- ANALYSIS system ----
47 #include "AliCaloPID.h"
48 #include "AliVCluster.h"
49 #include "AliVTrack.h"
50 #include "AliAODPWG4Particle.h"
51 #include "AliCalorimeterUtils.h"
52
53 ClassImp(AliCaloPID)
54
55
56 //________________________________________________
57 AliCaloPID::AliCaloPID() : 
58 TObject(), 
59 fEMCALPhotonWeight(0.),   fEMCALPi0Weight(0.),  
60 fEMCALElectronWeight(0.), fEMCALChargeWeight(0.),      fEMCALNeutralWeight(0.),
61 fPHOSPhotonWeight(0.),    fPHOSPi0Weight(0.),  
62 fPHOSElectronWeight(0.),  fPHOSChargeWeight(0.) ,      fPHOSNeutralWeight(0.), 
63 fPHOSWeightFormula(0),    fPHOSPhotonWeightFormula(0), fPHOSPi0WeightFormula(0),
64 fPHOSPhotonWeightFormulaExpression(""), fPHOSPi0WeightFormulaExpression(""),
65 fL0CutMax(100.),          fL0CutMin(0),                fTOFCut(0.), 
66 fRcutPHOS(0),             fDebug(-1), 
67 fRecalculateBayesian(kFALSE), fParticleFlux(kLow),     fEMCALPIDUtils(),
68 fHistoNEBins(100),        fHistoEMax(100.),            fHistoEMin(0.),
69 fHistoNDEtaBins(100),     fHistoDEtaMax(0.15),         fHistoDEtaMin(-0.15),
70 fHistoNDPhiBins(100),     fHistoDPhiMax(0.15),         fHistoDPhiMin(-0.15),
71 fhTrackMatchedDEta(0x0),  fhTrackMatchedDPhi(0x0),     fhTrackMatchedDEtaDPhi(0x0)
72 {
73   //Ctor
74   
75   //Initialize parameters
76   InitParameters();
77 }
78
79 //________________________________________________
80 AliCaloPID::AliCaloPID(const Int_t flux) : 
81 TObject(), 
82 fEMCALPhotonWeight(0.),   fEMCALPi0Weight(0.),  
83 fEMCALElectronWeight(0.), fEMCALChargeWeight(0.),      fEMCALNeutralWeight(0.),
84 fPHOSPhotonWeight(0.),    fPHOSPi0Weight(0.),  
85 fPHOSElectronWeight(0.),  fPHOSChargeWeight(0.) ,      fPHOSNeutralWeight(0.), 
86 fPHOSWeightFormula(0),    fPHOSPhotonWeightFormula(0), fPHOSPi0WeightFormula(0),
87 fPHOSPhotonWeightFormulaExpression(""), fPHOSPi0WeightFormulaExpression(""),
88 fL0CutMax(100.),          fL0CutMin(0),                fTOFCut(0.), 
89 fRcutPHOS(0),             fDebug(-1), 
90 fRecalculateBayesian(kFALSE), fParticleFlux(flux),     fEMCALPIDUtils(),
91 fHistoNEBins(100),        fHistoEMax(100.),            fHistoEMin(0.),
92 fHistoNDEtaBins(100),     fHistoDEtaMax(0.15),         fHistoDEtaMin(-0.15),
93 fHistoNDPhiBins(100),     fHistoDPhiMax(0.15),         fHistoDPhiMin(-0.15),
94 fhTrackMatchedDEta(0x0),  fhTrackMatchedDPhi(0x0),     fhTrackMatchedDEtaDPhi(0x0)
95 {
96   //Ctor
97         
98   //Initialize parameters
99   InitParameters();
100
101 }
102
103 //________________________________________________
104 AliCaloPID::AliCaloPID(const TTask * emcalpid) : 
105 TObject(), 
106 fEMCALPhotonWeight(0.),   fEMCALPi0Weight(0.),  
107 fEMCALElectronWeight(0.), fEMCALChargeWeight(0.),      fEMCALNeutralWeight(0.),
108 fPHOSPhotonWeight(0.),    fPHOSPi0Weight(0.),  
109 fPHOSElectronWeight(0.),  fPHOSChargeWeight(0.) ,      fPHOSNeutralWeight(0.), 
110 fPHOSWeightFormula(0),    fPHOSPhotonWeightFormula(0), fPHOSPi0WeightFormula(0),
111 fPHOSPhotonWeightFormulaExpression(""), fPHOSPi0WeightFormulaExpression(""),
112 fL0CutMax(100.),          fL0CutMin(0),                fTOFCut(0.), 
113 fRcutPHOS(0),             fDebug(-1), 
114 fRecalculateBayesian(kFALSE), fParticleFlux(kLow),     fEMCALPIDUtils((AliEMCALPIDUtils*) emcalpid),
115 fHistoNEBins(100),        fHistoEMax(100.),            fHistoEMin(0.),
116 fHistoNDEtaBins(100),     fHistoDEtaMax(0.15),         fHistoDEtaMin(-0.15),
117 fHistoNDPhiBins(100),     fHistoDPhiMax(0.15),         fHistoDPhiMin(-0.15),
118 fhTrackMatchedDEta(0x0),  fhTrackMatchedDPhi(0x0),     fhTrackMatchedDEtaDPhi(0x0)
119 {
120   //Ctor
121         
122   //Initialize parameters
123   InitParameters();
124 }
125
126 //_________________________________
127 AliCaloPID::~AliCaloPID() {
128   //Dtor
129   
130   delete fPHOSPhotonWeightFormula ;
131   delete fPHOSPi0WeightFormula ;
132   delete fEMCALPIDUtils ;
133
134 }
135
136 //________________________________________________________________________
137 TList *  AliCaloPID::GetCreateOutputObjects()
138 {  
139   // Create histograms to be saved in output file and 
140   // store them in outputContainer of the analysis class that calls this class.
141   
142   TList * outputContainer = new TList() ; 
143   outputContainer->SetName("CaloPIDHistos") ; 
144   
145   outputContainer->SetOwner(kFALSE);
146   
147   fhTrackMatchedDEta  = new TH2F
148   ("TrackMatchedDEta",
149    "d#eta of cluster-track vs cluster energy",
150    fHistoNEBins,fHistoEMin,fHistoEMax,fHistoNDEtaBins,fHistoDEtaMin,fHistoDEtaMax); 
151   fhTrackMatchedDEta->SetYTitle("d#eta");
152   fhTrackMatchedDEta->SetXTitle("E_{cluster} (GeV)");
153   
154   fhTrackMatchedDPhi  = new TH2F
155   ("TrackMatchedDPhi",
156    "d#phi of cluster-track vs cluster energy"
157    ,fHistoNEBins,fHistoEMin,fHistoEMax,fHistoNDPhiBins,fHistoDPhiMin,fHistoDPhiMax); 
158   fhTrackMatchedDPhi->SetYTitle("d#phi (rad)");
159   fhTrackMatchedDPhi->SetXTitle("E_{cluster} (GeV)");
160   
161   fhTrackMatchedDEtaDPhi  = new TH2F
162   ("TrackMatchedDEtaDPhi",
163    "d#eta vs d#phi of cluster-track vs cluster energy"
164    ,fHistoNDEtaBins,fHistoDEtaMin,fHistoDEtaMax,fHistoNDPhiBins,fHistoDPhiMin,fHistoDPhiMax); 
165   fhTrackMatchedDEtaDPhi->SetYTitle("d#phi (rad)");
166   fhTrackMatchedDEtaDPhi->SetXTitle("d#eta");   
167   
168   outputContainer->Add(fhTrackMatchedDEta) ; 
169   outputContainer->Add(fhTrackMatchedDPhi) ;
170   outputContainer->Add(fhTrackMatchedDEtaDPhi) ; 
171   
172   return outputContainer;
173 }
174
175
176
177 //_______________________________________________________________
178 void AliCaloPID::InitParameters()
179 {
180   //Initialize the parameters of the PID.
181   
182   fEMCALPhotonWeight   = 0.6 ;
183   fEMCALPi0Weight      = 0.6 ;
184   fEMCALElectronWeight = 0.6 ;
185   fEMCALChargeWeight   = 0.6 ;
186   fEMCALNeutralWeight  = 0.6 ;
187   
188   fPHOSPhotonWeight    = 0.6 ;
189   fPHOSPi0Weight       = 0.6 ;
190   fPHOSElectronWeight  = 0.6 ;
191   fPHOSChargeWeight    = 0.6 ;
192   fPHOSNeutralWeight   = 0.6 ;
193   
194   //Formula to set the PID weight threshold for photon or pi0
195   fPHOSWeightFormula       = kFALSE;
196   fPHOSPhotonWeightFormulaExpression = "0.98*(x<40)+ 0.68*(x>=100)+(x>=40 && x<100)*(0.98+x*(6e-3)-x*x*(2e-04)+x*x*x*(1.1e-06))";
197   fPHOSPi0WeightFormulaExpression    = "0.98*(x<65)+ 0.915*(x>=100)+(x>=65 && x-x*(1.95e-3)-x*x*(4.31e-05)+x*x*x*(3.61e-07))"   ;
198   
199   fL0CutMax = 0.3;
200   fL0CutMin = 0.01;
201   fTOFCut   = 5.e-9;
202   fRcutPHOS = 10.;
203   
204   fDebug    =-1;
205         
206   if(fRecalculateBayesian){
207         if(fParticleFlux == kLow){
208                 printf("AliCaloPID::Init() - SetLOWFluxParam\n");
209                 fEMCALPIDUtils->SetLowFluxParam() ;
210         }
211         else if (fParticleFlux == kHigh){
212                 printf("AliCaloPID::Init() - SetHIGHFluxParam\n");
213                 fEMCALPIDUtils->SetHighFluxParam() ;
214         }
215   }
216 }
217
218 //_______________________________________________________________
219 Int_t AliCaloPID::GetIdentifiedParticleType(const TString calo, const Double_t * pid, const Float_t energy) {
220   //Return most probable identity of the particle.
221   
222   if(!pid){ 
223     printf("AliCaloPID::GetIdentifiedParticleType() - pid pointer not initialized!!!\n");
224     abort();
225   }
226   
227   Float_t wPh  =  fPHOSPhotonWeight ;
228   Float_t wPi0 =  fPHOSPi0Weight ;
229   Float_t wE   =  fPHOSElectronWeight ;
230   Float_t wCh  =  fPHOSChargeWeight ;
231   Float_t wNe  =  fPHOSNeutralWeight ;
232     
233   if(calo == "PHOS" && fPHOSWeightFormula){
234     wPh  = GetPHOSPhotonWeightFormula()->Eval(energy) ;
235     wPi0 = GetPHOSPi0WeightFormula()   ->Eval(energy);
236   }
237   
238   if(calo == "EMCAL"){
239     
240     wPh  =  fEMCALPhotonWeight ;
241     wPi0 =  fEMCALPi0Weight ;
242     wE   =  fEMCALElectronWeight ;
243     wCh  =  fEMCALChargeWeight ;
244     wNe  =  fEMCALNeutralWeight ;
245     
246   }
247   
248   if(fDebug > 0)  printf("AliCaloPID::GetIdentifiedParticleType: calo %s, ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f, hadrons: pion %0.2f, kaon %0.2f, proton %0.2f , neutron %0.2f, kaon %0.2f \n",
249                          calo.Data(),pid[AliVCluster::kPhoton], pid[AliVCluster::kPi0],
250                          pid[AliVCluster::kElectron], pid[AliVCluster::kEleCon],
251                          pid[AliVCluster::kPion], pid[AliVCluster::kKaon], pid[AliVCluster::kProton],
252                          pid[AliVCluster::kNeutron], pid[AliVCluster::kKaon0]);
253   
254   Int_t pdg = kNeutralUnknown ;
255   Float_t chargedHadronWeight = pid[AliVCluster::kProton]+pid[AliVCluster::kKaon]+
256     pid[AliVCluster::kPion]+pid[AliVCluster::kMuon];
257   Float_t neutralHadronWeight = pid[AliVCluster::kNeutron]+pid[AliVCluster::kKaon0];
258   Float_t allChargedWeight    = pid[AliVCluster::kElectron]+pid[AliVCluster::kEleCon]+ chargedHadronWeight;
259   Float_t allNeutralWeight    = pid[AliVCluster::kPhoton]+pid[AliVCluster::kPi0]+ neutralHadronWeight;
260   
261   //Select most probable ID
262   if(calo=="PHOS"){
263     if(pid[AliVCluster::kPhoton] > wPh)        pdg = kPhoton ;
264     else if(pid[AliVCluster::kPi0] > wPi0)     pdg = kPi0 ; 
265     else if(pid[AliVCluster::kElectron] > wE)  pdg = kElectron ;
266     else if(pid[AliVCluster::kEleCon] >  wE)   pdg = kEleCon ;
267     else if(chargedHadronWeight > wCh)         pdg = kChargedHadron ;  
268     else if(neutralHadronWeight > wNe)         pdg = kNeutralHadron ; 
269     else if(allChargedWeight >  allNeutralWeight)
270       pdg = kChargedUnknown ; 
271     else 
272       pdg = kNeutralUnknown ;
273   }
274   else{//EMCAL
275     
276     if(pid[AliVCluster::kPhoton]  > wPh)                     pdg = kPhoton ;
277     else if(pid[AliVCluster::kElectron]  > wE)               pdg = kElectron ;
278     else if(pid[AliVCluster::kPhoton]+pid[AliVCluster::kElectron]  > wPh) pdg = kPhoton ; //temporal sollution until track matching for electrons is considered
279     else if(pid[AliVCluster::kPi0] > wPi0)                   pdg = kPi0 ; 
280     else if(chargedHadronWeight + neutralHadronWeight > wCh) pdg = kChargedHadron ;  
281     else if(neutralHadronWeight + chargedHadronWeight > wNe) pdg = kNeutralHadron ; 
282     else                                                     pdg = kNeutralUnknown ;
283   }
284   
285   if(fDebug > 0)printf("AliCaloPID::GetIdentifiedParticleType:Final Pdg: %d, cluster energy %2.2f \n", pdg,energy);
286    //printf("PDG1\n");
287   return pdg ;
288   
289 }
290
291 //_______________________________________________________________
292 Int_t AliCaloPID::GetIdentifiedParticleType(const TString calo,const TLorentzVector mom, const AliVCluster * cluster) {
293   //Recalculated PID with all parameters
294   
295   Float_t lambda0 = cluster->GetM02();
296   Float_t lambda1 = cluster->GetM20();
297   Float_t energy  = mom.E();    
298   
299   if(fDebug > 0) printf("AliCaloPID::GetIdentifiedParticleType: Calorimeter %s, E %3.2f, l0 %3.2f, l1 %3.2f, disp %3.2f, tof %1.11f, distCPV %3.2f, distToBC %1.1f, NMax %d\n",
300                         calo.Data(),energy,lambda0,cluster->GetM20(),cluster->GetDispersion(),cluster->GetTOF(), 
301                         cluster->GetEmcCpvDistance(), cluster->GetDistanceToBadChannel(),cluster->GetNExMax());
302   
303   if(calo == "EMCAL") {
304           //Recalculate Bayesian
305           if(fRecalculateBayesian){       
306                   if(fDebug > 0)  {
307                           const Double_t  *pid0 = cluster->GetPID();
308                           printf("AliCaloPID::GetIdentifiedParticleType: BEFORE calo %s, ph %0.2f, pi0 %0.2f, el %0.2f, conv el %0.2f, hadrons: pion %0.2f, kaon %0.2f, proton %0.2f , neutron %0.2f, kaon %0.2f \n",
309                calo.Data(),pid0[AliVCluster::kPhoton], pid0[AliVCluster::kPi0],
310                pid0[AliVCluster::kElectron], pid0[AliVCluster::kEleCon],
311                pid0[AliVCluster::kPion], pid0[AliVCluster::kKaon], pid0[AliVCluster::kProton],
312                pid0[AliVCluster::kNeutron], pid0[AliVCluster::kKaon0]);
313                   }
314                   
315       fEMCALPIDUtils->ComputePID(energy, lambda0);
316       Double_t pid[AliPID::kSPECIESN];
317       for(Int_t i = 0; i < AliPID::kSPECIESN; i++) pid[i] = fEMCALPIDUtils->GetPIDFinal(i);
318       return GetIdentifiedParticleType(calo, pid, energy);
319                   
320     }
321     
322     // If no use of bayesian, simplest PID  
323     if(lambda0 < fL0CutMax && lambda0 > fL0CutMin) return kPhoton ;
324     else return  kPi0 ; // Wild guess, it can be hadron but not photon
325   
326   }//EMCAL
327   else {//PHOS
328     
329     // Do not use bayesian, cut based on shower ellipse
330     return IsPHOSPhoton(lambda0,lambda1);
331   
332   }
333     
334 }
335
336 //__________________________________________________
337 TString  AliCaloPID::GetPIDParametersList()  {
338   //Put data member values in string to keep in output container
339   
340   TString parList ; //this will be list of parameters used for this analysis.
341   const Int_t buffersize = 255;
342   char onePar[buffersize] ;
343   snprintf(onePar,buffersize,"--- AliCaloPID ---\n") ;
344   parList+=onePar ;     
345   snprintf(onePar,buffersize,"fL0CutMin =%2.2f, fL0CutMax =%2.2f  (Cut on Shower Shape, used in PID evaluation) \n",fL0CutMin, fL0CutMax) ;
346   parList+=onePar ;
347   snprintf(onePar,buffersize,"fTOFCut  =%e (Cut on TOF, used in PID evaluation) \n",fTOFCut) ;
348   parList+=onePar ;
349   snprintf(onePar,buffersize,"fEMCALPhotonWeight =%2.2f (EMCAL bayesian weight for photons)\n",fEMCALPhotonWeight) ;
350   parList+=onePar ;
351   snprintf(onePar,buffersize,"fEMCALPi0Weight =%2.2f (EMCAL bayesian weight for pi0)\n",fEMCALPi0Weight) ;
352   parList+=onePar ;
353   snprintf(onePar,buffersize,"fEMCALElectronWeight =%2.2f(EMCAL bayesian weight for electrons)\n",fEMCALElectronWeight) ;
354   parList+=onePar ;
355   snprintf(onePar,buffersize,"fEMCALChargeWeight =%2.2f (EMCAL bayesian weight for charged hadrons)\n",fEMCALChargeWeight) ;
356   parList+=onePar ;
357   snprintf(onePar,buffersize,"fEMCALNeutralWeight =%2.2f (EMCAL bayesian weight for neutral hadrons)\n",fEMCALNeutralWeight) ;
358   parList+=onePar ;
359   snprintf(onePar,buffersize,"fPHOSPhotonWeight =%2.2f (PHOS bayesian weight for photons)\n",fPHOSPhotonWeight) ;
360   parList+=onePar ;
361   snprintf(onePar,buffersize,"fPHOSPi0Weight =%2.2f (PHOS bayesian weight for pi0)\n",fPHOSPi0Weight) ;
362   parList+=onePar ;
363   snprintf(onePar,buffersize,"fPHOSElectronWeight =%2.2f(PHOS bayesian weight for electrons)\n",fPHOSElectronWeight) ;
364   parList+=onePar ;
365   snprintf(onePar,buffersize,"fPHOSChargeWeight =%2.2f (PHOS bayesian weight for charged hadrons)\n",fPHOSChargeWeight) ;
366   parList+=onePar ;
367   snprintf(onePar,buffersize,"fPHOSNeutralWeight =%2.2f (PHOS bayesian weight for neutral hadrons)\n",fPHOSNeutralWeight) ;
368   parList+=onePar ;
369   
370   if(fPHOSWeightFormula){
371     snprintf(onePar,buffersize,"PHOS Photon Weight Formula: %s\n",fPHOSPhotonWeightFormulaExpression.Data() ) ;
372     parList+=onePar;
373     snprintf(onePar,buffersize,"PHOS Pi0    Weight Formula: %s\n",fPHOSPi0WeightFormulaExpression.Data()    ) ;
374     parList+=onePar;      
375   }
376   
377   return parList; 
378   
379 }
380
381 //________________________________________________________________
382 void AliCaloPID::Print(const Option_t * opt) const
383 {
384   
385   //Print some relevant parameters set for the analysis
386   if(! opt)
387     return;
388   
389   printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
390   
391   printf("PHOS PID weight , photon %0.2f, pi0 %0.2f, e %0.2f, charge %0.2f, neutral %0.2f \n",  
392          fPHOSPhotonWeight,  fPHOSPi0Weight, 
393          fPHOSElectronWeight,  fPHOSChargeWeight,   fPHOSNeutralWeight) ; 
394   printf("EMCAL PID weight, photon %0.2f, pi0 %0.2f, e %0.2f, charge %0.2f, neutral %0.2f\n",   
395          fEMCALPhotonWeight,  fEMCALPi0Weight, 
396          fEMCALElectronWeight,  fEMCALChargeWeight,  fEMCALNeutralWeight) ; 
397   
398   printf("PHOS Parametrized weight on?  =     %d\n",  fPHOSWeightFormula) ; 
399   if(fPHOSWeightFormula){
400     printf("Photon weight formula = %s\n", fPHOSPhotonWeightFormulaExpression.Data());
401     printf("Pi0    weight formula = %s\n", fPHOSPi0WeightFormulaExpression   .Data());
402   }
403   
404   printf("TOF cut        = %e\n",fTOFCut);
405   printf("Lambda0 cut min = %2.2f; max = %2.2f\n",fL0CutMin, fL0CutMax);
406   printf("Debug level    = %d\n",fDebug);
407   printf("Recalculate Bayesian?    = %d\n",fRecalculateBayesian);
408  if(fRecalculateBayesian) printf("Particle Flux?    = %d\n",fParticleFlux);
409   printf(" \n");
410   
411
412
413 //_______________________________________________________________
414 void AliCaloPID::SetPIDBits(const TString calo, const AliVCluster * cluster, AliAODPWG4Particle * ph, const AliCalorimeterUtils* cu) {
415   //Set Bits for PID selection
416   
417   //Dispersion/lambdas
418   //Double_t disp= cluster->GetDispersion()  ;
419   Double_t l1  = cluster->GetM20() ;
420   Double_t l0  = cluster->GetM02() ; 
421   Bool_t isDispOK = kTRUE ;
422   if(cluster->IsPHOS()){ 
423     
424    isDispOK =  IsPHOSPhoton(l0,l1);
425     
426   }
427   else{//EMCAL
428     
429     if(l0 > fL0CutMin && l0 < fL0CutMax) isDispOK = kTRUE;
430     
431   }
432   
433   ph->SetDispBit(isDispOK) ;
434   
435   //TOF
436   Double_t tof=cluster->GetTOF()  ;
437   ph->SetTOFBit(TMath::Abs(tof)<fTOFCut) ; 
438   
439   //Charged veto  
440   //Bool_t isNeutral = kTRUE ;
441   //if(cluster->IsPHOS())  isNeutral = cluster->GetEmcCpvDistance() > 5. ;
442   //else 
443   Bool_t isNeutral = IsTrackMatched(cluster,cu);
444   
445   ph->SetChargedBit(isNeutral);
446   
447   //Set PID pdg
448   ph->SetIdentifiedParticleType(GetIdentifiedParticleType(calo,cluster->GetPID(),ph->E()));
449   
450   if(fDebug > 0){ 
451     printf("AliCaloPID::SetPIDBits: TOF %e, Lambda0 %2.2f, Lambda1 %2.2f\n",tof , l0, l1);      
452     printf("AliCaloPID::SetPIDBits: pdg %d, bits: TOF %d, Dispersion %d, Charge %d\n",
453              ph->GetIdentifiedParticleType(), ph->GetTOFBit() , ph->GetDispBit() , ph->GetChargedBit()); 
454   }
455 }
456
457 //__________________________________________________________________________
458 Bool_t AliCaloPID::IsTrackMatched(const AliVCluster* cluster, const AliCalorimeterUtils * cu) const {
459   //Check if there is any track attached to this cluster
460   
461   Int_t nMatches = cluster->GetNTracksMatched();
462   
463   //  if(nMatches>0){
464   //    printf("N matches %d, first match (ESD) %d or (AOD) %d\n",nMatches,cluster->GetTrackMatchedIndex(), cluster->GetTrackMatched(0));
465   //    if     (cluster->GetTrackMatched(0))        printf("\t matched track id %d\n",((AliVTrack*)cluster->GetTrackMatched(0)) ->GetID() ) ;
466   //  }
467   //  else {
468   //    printf("Not Matched");
469   //  }
470   
471   //If EMCAL track matching needs to be recalculated
472   if(cluster->IsEMCAL() && cu && cu->IsRecalculationOfClusterTrackMatchingOn()){
473     Float_t dR = 999., dZ = 999.;
474     cu->GetEMCALRecoUtils()->GetMatchedResiduals(cluster->GetID(),dR,dZ);
475     
476     if(dR < 999) {     
477       
478       if(fhTrackMatchedDEta){
479         fhTrackMatchedDEta->Fill(cluster->E(),dZ);
480         fhTrackMatchedDPhi->Fill(cluster->E(),dR);
481         if(cluster->E() > 0.5)fhTrackMatchedDEtaDPhi->Fill(dZ,dR);
482       }
483       //printf("dR %f, dZ %f \n",dR,dZ);
484       return kTRUE;
485     }
486     else         
487       return kFALSE;
488   }//EMCAL cluster and recalculation of matching on
489   
490   if(fhTrackMatchedDEta){
491     fhTrackMatchedDEta->Fill(cluster->GetTrackDz(),cluster->E());
492     fhTrackMatchedDPhi->Fill(cluster->GetTrackDx(),cluster->E());
493     if(cluster->E() > 0.5)fhTrackMatchedDEtaDPhi->Fill(cluster->GetTrackDz(),cluster->GetTrackDx());
494   }
495   
496   if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
497   {    
498     if (nMatches > 0) {
499       if (nMatches == 1 ) {
500         Int_t iESDtrack = cluster->GetTrackMatchedIndex();
501         //printf("Track Matched index %d\n",iESDtrack);
502         if(iESDtrack==-1) return kFALSE ;// Default value of array, there is no match
503         else  {
504           if(cluster->IsPHOS()) {
505             Double_t r = TMath::Sqrt(cluster->GetTrackDx()*cluster->GetTrackDx()+cluster->GetTrackDz()*cluster->GetTrackDz());
506             if( r < fRcutPHOS) return kTRUE ;// Default value of array, there is no match
507             else               return kFALSE;
508           }//PHOS
509           else return kTRUE; // EMCAL and not default
510         }
511       }//Just one, check
512       else return kTRUE ;//More than one, there is a match.
513     }// > 0
514     else return kFALSE; //It does not happen, but in case
515     
516   }//ESDs
517   else
518   {    
519     if(nMatches > 0) return kTRUE; //There is at least one match.
520     else             return kFALSE;
521     
522   }//AODs or MC (copy into AOD)
523   
524   return kFALSE;
525   
526 }
527
528 //__________________________________________________________________________
529 Bool_t AliCaloPID::IsPHOSPhoton(const Double_t l0, const Double_t l1) {
530   // Check the shape of the PHOS cluster
531   // Return true if photon like, from Dmitri P.
532   // TO DO, move parameters to data members
533   
534   Double_t l0Mean  = 1.22 ;
535   Double_t l1Mean  = 2.0  ;
536   Double_t l0Sigma = 0.42 ;
537   Double_t l1Sigma = 0.71 ;
538   Double_t c       =-0.59 ;
539   
540   Double_t R2=(l1-l1Mean)*(l0-l0Mean)/l0Sigma/l0Sigma+(l1-l1Mean)*(l1-l1Mean)/l1Sigma/l1Sigma-c*(l0-l0Mean)*(l1-l1Mean)/l0Sigma/l1Sigma ;
541   
542   return (R2<9.) ;
543   
544 }
545