]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG4/PartCorrBase/AliCaloPID.cxx
Cosmetics: one \n too much
[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 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 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 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   fDebug    =-1;
203         
204   if(fRecalculateBayesian){
205         if(fParticleFlux == kLow){
206                 printf("AliCaloPID::Init() - SetLOWFluxParam\n");
207                 fEMCALPIDUtils->SetLowFluxParam() ;
208         }
209         else if (fParticleFlux == kHigh){
210                 printf("AliCaloPID::Init() - SetHIGHFluxParam\n");
211                 fEMCALPIDUtils->SetHighFluxParam() ;
212         }
213   }
214 }
215
216 //_______________________________________________________________
217 Int_t AliCaloPID::GetIdentifiedParticleType(const TString calo, const Double_t * pid, const Float_t energy) {
218   //Return most probable identity of the particle.
219   
220   if(!pid){ 
221     printf("AliCaloPID::GetIdentifiedParticleType() - pid pointer not initialized!!!\n");
222     abort();
223   }
224   
225   Float_t wPh  =  fPHOSPhotonWeight ;
226   Float_t wPi0 =  fPHOSPi0Weight ;
227   Float_t wE   =  fPHOSElectronWeight ;
228   Float_t wCh  =  fPHOSChargeWeight ;
229   Float_t wNe  =  fPHOSNeutralWeight ;
230     
231   if(calo == "PHOS" && fPHOSWeightFormula){
232     wPh  = GetPHOSPhotonWeightFormula()->Eval(energy) ;
233     wPi0 = GetPHOSPi0WeightFormula()   ->Eval(energy);
234   }
235   
236   if(calo == "EMCAL"){
237     
238     wPh  =  fEMCALPhotonWeight ;
239     wPi0 =  fEMCALPi0Weight ;
240     wE   =  fEMCALElectronWeight ;
241     wCh  =  fEMCALChargeWeight ;
242     wNe  =  fEMCALNeutralWeight ;
243     
244   }
245   
246   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",
247                          calo.Data(),pid[AliVCluster::kPhoton], pid[AliVCluster::kPi0],
248                          pid[AliVCluster::kElectron], pid[AliVCluster::kEleCon],
249                          pid[AliVCluster::kPion], pid[AliVCluster::kKaon], pid[AliVCluster::kProton],
250                          pid[AliVCluster::kNeutron], pid[AliVCluster::kKaon0]);
251   
252   Int_t pdg = kNeutralUnknown ;
253   Float_t chargedHadronWeight = pid[AliVCluster::kProton]+pid[AliVCluster::kKaon]+
254     pid[AliVCluster::kPion]+pid[AliVCluster::kMuon];
255   Float_t neutralHadronWeight = pid[AliVCluster::kNeutron]+pid[AliVCluster::kKaon0];
256   Float_t allChargedWeight    = pid[AliVCluster::kElectron]+pid[AliVCluster::kEleCon]+ chargedHadronWeight;
257   Float_t allNeutralWeight    = pid[AliVCluster::kPhoton]+pid[AliVCluster::kPi0]+ neutralHadronWeight;
258   
259   //Select most probable ID
260   if(calo=="PHOS"){
261     if(pid[AliVCluster::kPhoton] > wPh)        pdg = kPhoton ;
262     else if(pid[AliVCluster::kPi0] > wPi0)     pdg = kPi0 ; 
263     else if(pid[AliVCluster::kElectron] > wE)  pdg = kElectron ;
264     else if(pid[AliVCluster::kEleCon] >  wE)   pdg = kEleCon ;
265     else if(chargedHadronWeight > wCh)         pdg = kChargedHadron ;  
266     else if(neutralHadronWeight > wNe)         pdg = kNeutralHadron ; 
267     else if(allChargedWeight >  allNeutralWeight)
268       pdg = kChargedUnknown ; 
269     else 
270       pdg = kNeutralUnknown ;
271   }
272   else{//EMCAL
273     
274     if(pid[AliVCluster::kPhoton]  > wPh)                     pdg = kPhoton ;
275     else if(pid[AliVCluster::kElectron]  > wE)               pdg = kElectron ;
276     else if(pid[AliVCluster::kPhoton]+pid[AliVCluster::kElectron]  > wPh) pdg = kPhoton ; //temporal sollution until track matching for electrons is considered
277     else if(pid[AliVCluster::kPi0] > wPi0)                   pdg = kPi0 ; 
278     else if(chargedHadronWeight + neutralHadronWeight > wCh) pdg = kChargedHadron ;  
279     else if(neutralHadronWeight + chargedHadronWeight > wNe) pdg = kNeutralHadron ; 
280     else                                                     pdg = kNeutralUnknown ;
281   }
282   
283   if(fDebug > 0)printf("AliCaloPID::GetIdentifiedParticleType:Final Pdg: %d, cluster energy %2.2f \n", pdg,energy);
284    //printf("PDG1\n");
285   return pdg ;
286   
287 }
288
289 //_______________________________________________________________
290 Int_t AliCaloPID::GetIdentifiedParticleType(const TString calo,const TLorentzVector mom, const AliVCluster * cluster) {
291   //Recalculated PID with all parameters
292   
293   Float_t lambda0 = cluster->GetM02();
294   Float_t lambda1 = cluster->GetM20();
295   Float_t energy  = mom.E();    
296   
297   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",
298                         calo.Data(),energy,lambda0,cluster->GetM20(),cluster->GetDispersion(),cluster->GetTOF(), 
299                         cluster->GetEmcCpvDistance(), cluster->GetDistanceToBadChannel(),cluster->GetNExMax());
300   
301   if(calo == "EMCAL") {
302           //Recalculate Bayesian
303           if(fRecalculateBayesian){       
304                   if(fDebug > 0)  {
305                           const Double_t  *pid0 = cluster->GetPID();
306                           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",
307                calo.Data(),pid0[AliVCluster::kPhoton], pid0[AliVCluster::kPi0],
308                pid0[AliVCluster::kElectron], pid0[AliVCluster::kEleCon],
309                pid0[AliVCluster::kPion], pid0[AliVCluster::kKaon], pid0[AliVCluster::kProton],
310                pid0[AliVCluster::kNeutron], pid0[AliVCluster::kKaon0]);
311                   }
312                   
313       fEMCALPIDUtils->ComputePID(energy, lambda0);
314       Double_t pid[AliPID::kSPECIESN];
315       for(Int_t i = 0; i < AliPID::kSPECIESN; i++) pid[i] = fEMCALPIDUtils->GetPIDFinal(i);
316       return GetIdentifiedParticleType(calo, pid, energy);
317                   
318     }
319     
320     // If no use of bayesian, simplest PID  
321     if(lambda0 < fL0CutMax && lambda0 > fL0CutMin) return kPhoton ;
322     else return  kPi0 ; // Wild guess, it can be hadron but not photon
323   
324   }//EMCAL
325   else {//PHOS
326     
327     // Do not use bayesian, cut based on shower ellipse
328     return IsPHOSPhoton(lambda0,lambda1);
329   
330   }
331     
332 }
333
334 //__________________________________________________
335 TString  AliCaloPID::GetPIDParametersList()  {
336   //Put data member values in string to keep in output container
337   
338   TString parList ; //this will be list of parameters used for this analysis.
339   const Int_t buffersize = 255;
340   char onePar[buffersize] ;
341   snprintf(onePar,buffersize,"--- AliCaloPID ---\n") ;
342   parList+=onePar ;     
343   snprintf(onePar,buffersize,"fL0CutMin =%2.2f, fL0CutMax =%2.2f  (Cut on Shower Shape, used in PID evaluation) \n",fL0CutMin, fL0CutMax) ;
344   parList+=onePar ;
345   snprintf(onePar,buffersize,"fTOFCut  =%e (Cut on TOF, used in PID evaluation) \n",fTOFCut) ;
346   parList+=onePar ;
347   snprintf(onePar,buffersize,"fEMCALPhotonWeight =%2.2f (EMCAL bayesian weight for photons)\n",fEMCALPhotonWeight) ;
348   parList+=onePar ;
349   snprintf(onePar,buffersize,"fEMCALPi0Weight =%2.2f (EMCAL bayesian weight for pi0)\n",fEMCALPi0Weight) ;
350   parList+=onePar ;
351   snprintf(onePar,buffersize,"fEMCALElectronWeight =%2.2f(EMCAL bayesian weight for electrons)\n",fEMCALElectronWeight) ;
352   parList+=onePar ;
353   snprintf(onePar,buffersize,"fEMCALChargeWeight =%2.2f (EMCAL bayesian weight for charged hadrons)\n",fEMCALChargeWeight) ;
354   parList+=onePar ;
355   snprintf(onePar,buffersize,"fEMCALNeutralWeight =%2.2f (EMCAL bayesian weight for neutral hadrons)\n",fEMCALNeutralWeight) ;
356   parList+=onePar ;
357   snprintf(onePar,buffersize,"fPHOSPhotonWeight =%2.2f (PHOS bayesian weight for photons)\n",fPHOSPhotonWeight) ;
358   parList+=onePar ;
359   snprintf(onePar,buffersize,"fPHOSPi0Weight =%2.2f (PHOS bayesian weight for pi0)\n",fPHOSPi0Weight) ;
360   parList+=onePar ;
361   snprintf(onePar,buffersize,"fPHOSElectronWeight =%2.2f(PHOS bayesian weight for electrons)\n",fPHOSElectronWeight) ;
362   parList+=onePar ;
363   snprintf(onePar,buffersize,"fPHOSChargeWeight =%2.2f (PHOS bayesian weight for charged hadrons)\n",fPHOSChargeWeight) ;
364   parList+=onePar ;
365   snprintf(onePar,buffersize,"fPHOSNeutralWeight =%2.2f (PHOS bayesian weight for neutral hadrons)\n",fPHOSNeutralWeight) ;
366   parList+=onePar ;
367   
368   if(fPHOSWeightFormula){
369     snprintf(onePar,buffersize,"PHOS Photon Weight Formula: %s\n",fPHOSPhotonWeightFormulaExpression.Data() ) ;
370     parList+=onePar;
371     snprintf(onePar,buffersize,"PHOS Pi0    Weight Formula: %s\n",fPHOSPi0WeightFormulaExpression.Data()    ) ;
372     parList+=onePar;      
373   }
374   
375   return parList; 
376   
377 }
378
379 //________________________________________________________________
380 void AliCaloPID::Print(const Option_t * opt) const
381 {
382   
383   //Print some relevant parameters set for the analysis
384   if(! opt)
385     return;
386   
387   printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
388   
389   printf("PHOS PID weight , photon %0.2f, pi0 %0.2f, e %0.2f, charge %0.2f, neutral %0.2f \n",  
390          fPHOSPhotonWeight,  fPHOSPi0Weight, 
391          fPHOSElectronWeight,  fPHOSChargeWeight,   fPHOSNeutralWeight) ; 
392   printf("EMCAL PID weight, photon %0.2f, pi0 %0.2f, e %0.2f, charge %0.2f, neutral %0.2f\n",   
393          fEMCALPhotonWeight,  fEMCALPi0Weight, 
394          fEMCALElectronWeight,  fEMCALChargeWeight,  fEMCALNeutralWeight) ; 
395   
396   printf("PHOS Parametrized weight on?  =     %d\n",  fPHOSWeightFormula) ; 
397   if(fPHOSWeightFormula){
398     printf("Photon weight formula = %s\n", fPHOSPhotonWeightFormulaExpression.Data());
399     printf("Pi0    weight formula = %s\n", fPHOSPi0WeightFormulaExpression   .Data());
400   }
401   
402   printf("TOF cut        = %e\n",fTOFCut);
403   printf("Lambda0 cut min = %2.2f; max = %2.2f\n",fL0CutMin, fL0CutMax);
404   printf("Debug level    = %d\n",fDebug);
405   printf("Recalculate Bayesian?    = %d\n",fRecalculateBayesian);
406  if(fRecalculateBayesian) printf("Particle Flux?    = %d\n",fParticleFlux);
407   printf(" \n");
408   
409
410
411 //_______________________________________________________________
412 void AliCaloPID::SetPIDBits(const TString calo, const AliVCluster * cluster, AliAODPWG4Particle * ph, const AliCalorimeterUtils* cu) {
413   //Set Bits for PID selection
414   
415   //Dispersion/lambdas
416   //Double_t disp= cluster->GetDispersion()  ;
417   Double_t l1  = cluster->GetM20() ;
418   Double_t l0  = cluster->GetM02() ; 
419   Bool_t isDispOK = kTRUE ;
420   if(cluster->IsPHOS()){ 
421     
422    isDispOK =  IsPHOSPhoton(l0,l1);
423     
424   }
425   else{//EMCAL
426     
427     if(l0 > fL0CutMin && l0 < fL0CutMax) isDispOK = kTRUE;
428     
429   }
430   
431   ph->SetDispBit(isDispOK) ;
432   
433   //TOF
434   Double_t tof=cluster->GetTOF()  ;
435   ph->SetTOFBit(TMath::Abs(tof)<fTOFCut) ; 
436   
437   //Charged veto  
438   //Bool_t isNeutral = kTRUE ;
439   //if(cluster->IsPHOS())  isNeutral = cluster->GetEmcCpvDistance() > 5. ;
440   //else 
441   Bool_t isNeutral = IsTrackMatched(cluster,cu);
442   
443   ph->SetChargedBit(isNeutral);
444   
445   //Set PID pdg
446   ph->SetIdentifiedParticleType(GetIdentifiedParticleType(calo,cluster->GetPID(),ph->E()));
447   
448   if(fDebug > 0){ 
449     printf("AliCaloPID::SetPIDBits: TOF %e, Lambda0 %2.2f, Lambda1 %2.2f\n",tof , l0, l1);      
450     printf("AliCaloPID::SetPIDBits: pdg %d, bits: TOF %d, Dispersion %d, Charge %d\n",
451              ph->GetIdentifiedParticleType(), ph->GetTOFBit() , ph->GetDispBit() , ph->GetChargedBit()); 
452   }
453 }
454
455 //__________________________________________________________________________
456 Bool_t AliCaloPID::IsTrackMatched(const AliVCluster* cluster, const AliCalorimeterUtils * cu) const {
457   //Check if there is any track attached to this cluster
458   
459   Int_t nMatches = cluster->GetNTracksMatched();
460 //  if(nMatches>0){
461 //    printf("N matches %d, first match (ESD) %d or (AOD) %d\n",nMatches,cluster->GetTrackMatchedIndex(), cluster->GetTrackMatched(0));
462 //    if     (cluster->GetTrackMatched(0))        printf("\t matched track id %d\n",((AliVTrack*)cluster->GetTrackMatched(0)) ->GetID() ) ;
463 //  }
464 //  else {
465 //    printf("Not Matched");
466 //  }
467
468   //If EMCAL track matching needs to be recalculated
469   if(cluster->IsEMCAL() && cu && cu->IsRecalculationOfClusterTrackMatchingOn()){
470     Float_t dR = 999., dZ = 999.;
471     cu->GetEMCALRecoUtils()->GetMatchedResiduals(cluster->GetID(),dR,dZ);
472
473     if(dR < 999) {     
474       
475       if(fhTrackMatchedDEta){
476         fhTrackMatchedDEta->Fill(cluster->E(),dZ);
477         fhTrackMatchedDPhi->Fill(cluster->E(),dR);
478         if(cluster->E() > 0.5)fhTrackMatchedDEtaDPhi->Fill(dZ,dR);
479       }
480       //printf("dR %f, dZ %f \n",dR,dZ);
481       return kTRUE;
482     }
483     else         
484       return kFALSE;
485   }//EMCAL cluster and recalculation of matching on
486   
487   if(fhTrackMatchedDEta){
488     fhTrackMatchedDEta->Fill(cluster->GetTrackDz(),cluster->E());
489     fhTrackMatchedDEta->Fill(cluster->GetTrackDx(),cluster->E());
490     if(cluster->E() > 0.5)fhTrackMatchedDEtaDPhi->Fill(cluster->GetTrackDz(),cluster->GetTrackDx());
491   }
492   
493   if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
494   {    
495     if (nMatches > 0) {
496       if (nMatches == 1 ) {
497         Int_t iESDtrack = cluster->GetTrackMatchedIndex();
498         //printf("Track Matched index %d\n",iESDtrack);
499         if(iESDtrack==-1) return kFALSE ;// Default value of array, there is no match
500         else              return kTRUE;
501       }//Just one, check
502       else return kTRUE ;//More than one, there is a match.
503     }// > 0
504     else return kFALSE; //It does not happen, but in case
505     
506   }//ESDs
507   else
508   {    
509     if(nMatches > 0) return kTRUE; //There is at least one match.
510     else             return kFALSE;
511     
512   }//AODs or MC (copy into AOD)
513   
514   return kFALSE;
515   
516 }
517
518 //__________________________________________________________________________
519 Bool_t IsPHOSPhoton(const Double_t l0, const Double_t l1) {
520   // Check the shape of the PHOS cluster
521   // Return true if photon like, from Dmitri P.
522   // TO DO, move parameters to data members
523   
524   Double_t l0Mean  = 1.22 ;
525   Double_t l1Mean  = 2.0  ;
526   Double_t l0Sigma = 0.42 ;
527   Double_t l1Sigma = 0.71 ;
528   Double_t c       =-0.59 ;
529   
530   Double_t R2=(l1-l1Mean)*(l0-l0Mean)/l0Sigma/l0Sigma+(l1-l1Mean)*(l1-l1Mean)/l1Sigma/l1Sigma-c*(l0-l0Mean)*(l1-l1Mean)/l0Sigma/l1Sigma ;
531   
532   return (R2<9.) ;
533   
534 }
535