]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronPID.cxx
afa188f412a22cea447add154097f3ace9abbb12
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronPID.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, 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 ///////////////////////////////////////////////////////////////////////////
17 //                Dielectron PID                                  //
18 //                                                                       //
19 //                                                                       //
20 /*
21 Detailed description
22
23
24 */
25 //                                                                       //
26 ///////////////////////////////////////////////////////////////////////////
27
28 #include <TMath.h>
29 #include <TF1.h>
30 #include <TGraph.h>
31
32 #include <AliVTrack.h>
33 #include <AliVCluster.h>
34 #include <AliLog.h>
35 #include <AliExternalTrackParam.h>
36 #include <AliPIDResponse.h>
37 #include <AliESDtrack.h> //!!!!! Remove once Eta correction is treated in the tender
38
39 #include "AliDielectronVarManager.h"
40
41 #include "AliDielectronPID.h"
42
43 ClassImp(AliDielectronPID)
44
45 TGraph *AliDielectronPID::fgFitCorr=0x0;
46 Double_t AliDielectronPID::fgCorr=0.0;
47 Double_t AliDielectronPID::fgCorrdEdx=1.0;
48 TF1 *AliDielectronPID::fgFunEtaCorr=0x0;
49 TGraph *AliDielectronPID::fgdEdxRunCorr=0x0;
50
51 AliDielectronPID::AliDielectronPID() :
52   AliAnalysisCuts(),
53   fNcuts(0),
54   fPIDResponse(0x0)
55 {
56   //
57   // Default Constructor
58   //
59   for (Int_t icut=0; icut<kNmaxPID; ++icut){
60     fDetType[icut]=kTPC;
61     fPartType[icut]=AliPID::kPion;
62     fNsigmaLow[icut]=0;
63     fNsigmaUp[icut]=0;
64     fmin[icut]=0;
65     fmax[icut]=0;
66     fExclude[icut]=kFALSE;
67     fFunUpperCut[icut]=0x0;
68     fFunLowerCut[icut]=0x0;
69     fRequirePIDbit[icut]=0;
70     fActiveCuts[icut]=-1;
71   }
72 }
73
74 //______________________________________________
75 AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
76   AliAnalysisCuts(name, title),
77   fNcuts(0),
78   fPIDResponse(0x0)
79 {
80   //
81   // Named Constructor
82   //
83   for (Int_t icut=0; icut<kNmaxPID; ++icut){
84     fDetType[icut]=kTPC;
85     fPartType[icut]=AliPID::kPion;
86     fNsigmaLow[icut]=0;
87     fNsigmaUp[icut]=0;
88     fmin[icut]=0;
89     fmax[icut]=0;
90     fExclude[icut]=kFALSE;
91     fFunUpperCut[icut]=0x0;
92     fFunLowerCut[icut]=0x0;
93     fRequirePIDbit[icut]=0;
94     fActiveCuts[icut]=0;
95   }
96 }
97
98 //______________________________________________
99 AliDielectronPID::~AliDielectronPID()
100 {
101   //
102   // Default Destructor
103   //
104 }
105
106 //______________________________________________
107 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp/*=-99999.*/,
108                               Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
109                               UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
110 {
111   //
112   // Add a pid nsigma cut
113   // use response of detector 'det' in the range ['min'] to ['max'] for var
114   // use a sigma band between 'nSigmaLow' and 'nSigmaUp'
115   // if nSigmaUp==-99999. then nSigmaLow will be uesd as a symmetric band +- nSigmaLow
116   // specify whether to 'exclude' the given band
117   //
118
119   if (fNcuts>=kNmaxPID){
120     AliError(Form("only %d pid cut ranges allowed",kNmaxPID));
121     return;
122   }
123   if (TMath::Abs(nSigmaUp+99999.)<1e-20){
124     nSigmaUp=TMath::Abs(nSigmaLow);
125     nSigmaLow=-1.*nSigmaUp;
126   }
127   fDetType[fNcuts]=det;
128   fPartType[fNcuts]=type;
129   fNsigmaLow[fNcuts]=nSigmaLow;
130   fNsigmaUp[fNcuts]=nSigmaUp;
131   fmin[fNcuts]=min;
132   fmax[fNcuts]=max;
133   fExclude[fNcuts]=exclude;
134   fRequirePIDbit[fNcuts]=pidBitType;
135   fActiveCuts[fNcuts]=(var==-1 ? AliDielectronVarManager::kP : var);
136
137   AliInfo(Form("Add PID cut %d: sigma [% .1f,% .1f] \t cut [% .1f,% .f] \t var %d->%s \n",
138                fNcuts,nSigmaLow,nSigmaUp,min,max,fActiveCuts[fNcuts],AliDielectronVarManager::GetValueName(fActiveCuts[fNcuts])));  
139   
140   ++fNcuts;
141
142 }
143
144 //______________________________________________
145 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, TF1 * const funUp,
146                               Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
147                               UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
148 {
149   //
150   // cut using a TF1 as upper cut
151   //
152   if (funUp==0x0){
153     AliError("A valid function is required for the upper cut. Not adding the cut!");
154     return;
155   }
156   fFunUpperCut[fNcuts]=funUp;
157   AddCut(det,type,nSigmaLow,0.,min,max,exclude,pidBitType,var);
158 }
159
160 //______________________________________________
161 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, Double_t nSigmaUp,
162                               Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
163                               UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
164 {
165   //
166   // cut using a TF1 as lower cut
167   //
168   if (funLow==0x0){
169     AliError("A valid function is required for the lower cut. Not adding the cut!");
170     return;
171   }
172   fFunLowerCut[fNcuts]=funLow;
173   AddCut(det,type,0.,nSigmaUp,min,max,exclude,pidBitType,var);
174 }
175
176 //______________________________________________
177 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, TF1 * const funUp,
178                               Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
179                               UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
180 {
181   //
182   // cut using a TF1 as lower and upper cut
183   //
184   if ( (funUp==0x0) || (funLow==0x0) ){
185     AliError("A valid function is required for upper and lower cut. Not adding the cut!");
186     return;
187   }
188   fFunUpperCut[fNcuts]=funUp;
189   fFunLowerCut[fNcuts]=funLow;
190   AddCut(det,type,0.,0.,min,max,exclude,pidBitType,var);
191 }
192
193 //______________________________________________
194 Bool_t AliDielectronPID::IsSelected(TObject* track)
195 {
196   //
197   // perform PID cuts
198   //
199
200   //loop over all cuts
201   AliVTrack *part=static_cast<AliVTrack*>(track);
202   AliESDtrack *esdTrack=0x0;
203   Double_t origdEdx=-1;
204   
205   // apply ETa correction, remove once this is in the tender
206   if( (part->IsA() == AliESDtrack::Class()) && fgFunEtaCorr ){
207     esdTrack=static_cast<AliESDtrack*>(part);
208     origdEdx=esdTrack->GetTPCsignal();
209     esdTrack->SetTPCsignal(origdEdx/GetEtaCorr(esdTrack)/fgCorrdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
210   }
211
212   
213   //Fill values
214   Double_t values[AliDielectronVarManager::kNMaxValues];
215   AliDielectronVarManager::Fill(track,values);
216
217   Bool_t selected=kFALSE;
218   fPIDResponse=AliDielectronVarManager::GetPIDResponse();
219   for (UChar_t icut=0; icut<fNcuts; ++icut){
220     Double_t min=fmin[icut];
221     Double_t max=fmax[icut];
222     Double_t val=values[fActiveCuts[icut]];
223     
224     // test var range. In case min==max do not cut
225     if ( (TMath::Abs(min-max)>1e-20) && (val<min || val>=max) ) continue;
226     
227     switch (fDetType[icut]){
228     case kITS:
229       selected = IsSelectedITS(part,icut);
230       break;
231     case kTPC:
232       selected = IsSelectedTPC(part,icut);
233       break;
234     case kTRD:
235       selected = IsSelectedTRD(part,icut);
236       break;
237     case kTRDeleEff:
238       selected = IsSelectedTRDeleEff(part,icut);
239       break;
240     case kTOF:
241       selected = IsSelectedTOF(part,icut);
242       break;
243     case kEMCAL:
244       selected = IsSelectedEMCAL(part,icut);
245       break;
246     }
247     if (!selected) {
248       if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
249
250       return kFALSE;
251     }
252   }
253
254   if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
255   return selected;
256 }
257
258 //______________________________________________
259 Bool_t AliDielectronPID::IsSelectedITS(AliVTrack * const part, Int_t icut)
260 {
261   //
262   // ITS part of the PID check
263   // Don't accept the track if there was no pid bit set
264   //
265   
266   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kITSpid)) return kFALSE;
267   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kITSpid)) return kTRUE;
268
269   Double_t mom=part->P();
270   
271   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasITS(part, fPartType[icut]);
272   
273   // test if we are supposed to use a function for the cut
274   if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
275   if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
276   
277   Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
278   return selected;
279 }
280
281 //______________________________________________
282 Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut)
283 {
284   //
285   // TPC part of the PID check
286   // Don't accept the track if there was no pid bit set
287   //
288   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kFALSE;
289   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kTRUE;
290
291   Double_t mom=part->GetTPCmomentum();
292   
293   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTPC(part, fPartType[icut]);
294
295   if (fPartType[icut]==AliPID::kElectron){
296     numberOfSigmas-=fgCorr;
297   }
298   
299   // test if we are supposed to use a function for the cut
300   if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
301   if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
302   
303   Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
304   return selected;
305 }
306
307 //______________________________________________
308 Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const part, Int_t icut)
309 {
310   //   
311   // TRD part of the pid check
312   // the TRD checks on the probabilities.
313   //
314
315   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
316   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
317   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable && (part->GetTRDntrackletsPID()<4)) return kTRUE;
318
319   Double_t p[AliPID::kSPECIES]={0.};
320   fPIDResponse->ComputeTRDProbability(part,AliPID::kSPECIES,p);
321   Float_t particleProb=p[fPartType[icut]];
322
323   Bool_t selected=((particleProb>=fNsigmaLow[icut])&&(particleProb<=fNsigmaUp[icut]))^fExclude[icut];
324   return selected;
325 }
326
327 //______________________________________________
328 Bool_t AliDielectronPID::IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut)
329 {
330   //
331   // TRD part of the pid check using electron efficiency requirement
332   // in this case the upper limit as well as the particle specie is ignored 
333   //   and the lower limit regarded as the requested electron efficiency
334   //
335
336   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
337   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
338
339   Bool_t selected=fPIDResponse->IdentifiedAsElectronTRD(part,fNsigmaLow[icut])^fExclude[icut];
340   return selected;
341 }
342
343 //______________________________________________
344 Bool_t AliDielectronPID::IsSelectedTOF(AliVTrack * const part, Int_t icut)
345 {
346   //
347   // TOF part of the PID check
348   // Don't accept the track if there was no pid bit set
349   //
350   
351   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kFALSE;
352   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kTRUE;
353
354   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTOF(part, fPartType[icut]);
355   
356   Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
357   return selected;
358 }
359
360 //______________________________________________
361 Bool_t AliDielectronPID::IsSelectedEMCAL(AliVTrack * const part, Int_t icut)
362 {
363   //
364   // emcal pid selecttion
365   //
366
367   //TODO: correct way to check for emcal pid?
368   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasEMCAL(part, fPartType[icut]);
369
370   Bool_t hasPID=numberOfSigmas>-998.;
371
372   if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!hasPID) return kFALSE;
373   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!hasPID) return kTRUE;
374
375
376   Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
377   return selected;
378 }
379
380 //______________________________________________
381 void AliDielectronPID::SetDefaults(Int_t def){
382   //
383   // initialise default pid strategies
384   //
385
386   if (def==0){
387     // 2sigma bands TPC:
388     // - include e
389     // - exclude mu,K,pi,p
390     // -complete p range
391     AddCut(kTPC,AliPID::kElectron,2);
392     AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,0.,kTRUE);
393     AddCut(kTPC,AliPID::kPion,-2.,2.,0.,0.,kTRUE);
394     AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,0.,kTRUE);
395     AddCut(kTPC,AliPID::kProton,-2.,2.,0.,0.,kTRUE);
396   } else if (def==1) {
397     // 2sigma bands TPC:
398     // - include e 0<p<inf
399     // - exclude mu,K,pi,p 0<p<2
400     AddCut(kTPC,AliPID::kElectron,2.);
401     AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,2.,kTRUE);
402     AddCut(kTPC,AliPID::kPion,-2.,2.,0.,2.,kTRUE);
403     AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,2.,kTRUE);
404     AddCut(kTPC,AliPID::kProton,-2.,2.,0.,2.,kTRUE);
405     
406   } else if (def==2) {
407     // include 2sigma e TPC
408     // 3sigma bands TOF
409     // - exclude K,P
410     AddCut(kTPC,AliPID::kElectron,-3.,3.);
411     AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
412     AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
413
414   } else if (def==3 || def==4) { // def3 and def4 are the same??
415     // include 2sigma e TPC
416     // 3sigma bands TOF
417     // - exclude K 0<p<1
418     // - exclude P 0<p<2
419     AddCut(kTPC,AliPID::kElectron,2);
420     AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
421     AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
422     AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
423     
424   } else if (def==5) {
425     AddCut(kTPC,AliPID::kElectron,-0.5,3);
426     AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
427   } else if (def==6) {
428     // lower cut TPC: parametrisation by HFE
429     // upper cut TPC: 3 sigma
430     // TOF ele band 3sigma 0<p<1.5GeV
431     TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
432     lowerCut->SetParameters(-2.7,-0.4357);
433     AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
434     AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
435   } else if (def==7) {
436     // wide TPC cut
437     // TOF ele band 3sigma 0<p<1.5GeV
438     AddCut(kTPC,AliPID::kElectron,10.);
439     AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
440   } else if (def==8) {
441     // TOF 5 sigma inclusion if TOFpid available
442     // this should reduce K,p,Pi to a large extent
443     AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
444   } else if (def==9) {
445     // lower cut TPC: parametrisation by HFE
446     // upper cut TPC: 3 sigma
447     // TOF 5 sigma inclusion if TOFpid available
448     // this should reduce K,p,Pi to a large extent
449     TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
450     lowerCut->SetParameters(-2.65,-0.6757);
451     AddCut(kTPC,AliPID::kElectron,lowerCut,4.);
452     AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
453
454   } else if (def==10) {
455     AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
456     AddCut(kTPC,AliPID::kElectron,3.);
457     AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
458     AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
459     
460   } else if (def==11) {
461     // lower cut TPC: parametrisation by HFE
462     // only use from period d on !!
463     // upper cut TPC: 3 sigma
464     // TOF ele band 3sigma 0<p<2.0GeV
465     TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)+[2]", 0, 100);
466     lowerCut->SetParameters(-3.718,-0.4,0.27);
467     AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
468     AddCut(kTOF,AliPID::kElectron,-3,3,0,2.);
469   } else if (def==12) {
470     // lower cut TPC: parametrisation by HFE
471     // only use from period d on !!
472     // upper cut TPC: 3 sigma
473     // TOF 5 sigma inclusion if TOFpid available
474     // this should reduce K,p,Pi to a large extent
475     TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)+[2]", 0, 100);
476     lowerCut->SetParameters(-3.718,-0.4,0.27);
477     AddCut(kTPC,AliPID::kElectron,lowerCut,4.);
478     AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
479   }
480
481 }
482
483 //______________________________________________
484 void AliDielectronPID::SetCorrVal(Double_t run)
485 {
486   //
487   // set correction value for run
488   //
489   fgCorr=0.;
490   fgCorrdEdx=1.;
491   
492   if (fgFitCorr){
493     fgCorr=fgFitCorr->Eval(run);
494     if (run<fgFitCorr->GetX()[0]) fgCorr=fgFitCorr->GetY()[0];
495     if (run>fgFitCorr->GetX()[fgFitCorr->GetN()-1]) fgCorr=fgFitCorr->GetY()[fgFitCorr->GetN()-1];
496   }
497
498   if (fgdEdxRunCorr){
499     fgCorrdEdx=fgdEdxRunCorr->Eval(run);
500     if (run<fgdEdxRunCorr->GetX()[0]) fgCorrdEdx=fgdEdxRunCorr->GetY()[0];
501     if (run>fgdEdxRunCorr->GetX()[fgFitCorr->GetN()-1]) fgCorrdEdx=fgdEdxRunCorr->GetY()[fgdEdxRunCorr->GetN()-1];
502   }
503 }
504
505 //______________________________________________
506 Double_t AliDielectronPID::GetEtaCorr(AliVTrack *track)
507 {
508   //
509   // return eta correction
510   //
511   if (!fgFunEtaCorr) return 1;
512   return fgFunEtaCorr->Eval(track->Eta());
513 }