1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////
32 #include <AliVTrack.h>
34 #include <AliExternalTrackParam.h>
35 #include <AliESDtrack.h>
36 #include <AliESDpid.h>
37 #include <AliAODpidUtil.h>
38 #include <AliAODPid.h>
40 #include "AliDielectronVarManager.h"
42 #include "AliDielectronPID.h"
44 ClassImp(AliDielectronPID)
46 TGraph *AliDielectronPID::fgFitCorr=0x0;
47 Double_t AliDielectronPID::fgCorr=0.0;
49 AliDielectronPID::AliDielectronPID() :
56 // Default Constructor
58 for (Int_t icut=0; icut<kNmaxPID; ++icut){
60 fPartType[icut]=AliPID::kPion;
65 fExclude[icut]=kFALSE;
66 fFunUpperCut[icut]=0x0;
67 fFunLowerCut[icut]=0x0;
68 fRequirePIDbit[icut]=0;
72 //______________________________________________
73 AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
74 AliAnalysisCuts(name, title),
82 for (Int_t icut=0; icut<kNmaxPID; ++icut){
84 fPartType[icut]=AliPID::kPion;
89 fExclude[icut]=kFALSE;
90 fFunUpperCut[icut]=0x0;
91 fFunLowerCut[icut]=0x0;
92 fRequirePIDbit[icut]=0;
96 //______________________________________________
97 AliDielectronPID::~AliDielectronPID()
100 // Default Destructor
104 //______________________________________________
105 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp/*=-99999.*/,
106 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
107 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
110 // Add a pid nsigma cut
111 // use response of detector 'det' in the momentum range ('pMin') to ['pMax']
112 // use a sigma band betwee 'nSigmaLow' and 'nSigmaUp'
113 // if nSigmaUp==-99999. then nSigmaLow will be uesd as a symmetric band +- nSigmaLow
114 // specify whether to 'exclude' the given band
117 if (fNcuts>=kNmaxPID){
118 AliError(Form("only %d pid cut ranges allowed",kNmaxPID));
121 if (TMath::Abs(nSigmaUp+99999.)<1e-20){
122 nSigmaUp=TMath::Abs(nSigmaLow);
123 nSigmaLow=-1.*nSigmaUp;
125 fDetType[fNcuts]=det;
126 fPartType[fNcuts]=type;
127 fNsigmaLow[fNcuts]=nSigmaLow;
128 fNsigmaUp[fNcuts]=nSigmaUp;
131 fExclude[fNcuts]=exclude;
132 fRequirePIDbit[fNcuts]=pidBitType;
137 //______________________________________________
138 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, TF1 * const funUp,
139 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
140 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
143 // cut using a TF1 as upper cut
146 AliError("A valid function is required for the upper cut. Not adding the cut!");
149 fFunUpperCut[fNcuts]=funUp;
150 AddCut(det,type,nSigmaLow,0.,pMin,pMax,exclude,pidBitType);
153 //______________________________________________
154 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, Double_t nSigmaUp,
155 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
156 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
159 // cut using a TF1 as lower cut
162 AliError("A valid function is required for the lower cut. Not adding the cut!");
165 fFunLowerCut[fNcuts]=funLow;
166 AddCut(det,type,0.,nSigmaUp,pMin,pMax,exclude,pidBitType);
169 //______________________________________________
170 void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, TF1 * const funUp,
171 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
172 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
175 // cut using a TF1 as lower and upper cut
177 if ( (funUp==0x0) || (funLow==0x0) ){
178 AliError("A valid function is required for upper and lower cut. Not adding the cut!");
181 fFunUpperCut[fNcuts]=funUp;
182 fFunLowerCut[fNcuts]=funLow;
183 AddCut(det,type,0.,0.,pMin,pMax,exclude,pidBitType);
186 //______________________________________________
187 Bool_t AliDielectronPID::IsSelected(TObject* track)
194 AliVTrack *part=static_cast<AliVTrack*>(track);
195 //TODO: Which momentum to use?
196 // Different momenta for different detectors?
197 Double_t mom=part->P();
199 Bool_t selected=kFALSE;
200 fESDpid=AliDielectronVarManager::GetESDpid();
201 fAODpidUtil=AliDielectronVarManager::GetAODpidUtil();
203 for (UChar_t icut=0; icut<fNcuts; ++icut){
204 Double_t pMin=fPmin[icut];
205 Double_t pMax=fPmax[icut];
207 // test momentum range. In case pMin==pMax use all momenta
208 if ( (TMath::Abs(pMin-pMax)>1e-20) && (mom<=pMin || mom>pMax) ) continue;
211 switch (fDetType[icut]){
213 selected = IsSelectedITS(part,icut);
216 selected = IsSelectedTPC(part,icut);
219 selected = IsSelectedTRD(part,icut);
222 selected = IsSelectedTOF(part,icut);
225 if (!selected) return kFALSE;
231 //______________________________________________
232 Bool_t AliDielectronPID::IsSelectedITS(AliVTrack * const part, Int_t icut)
235 // ITS part of the PID check
236 // Don't accept the track if there was no pid bit set
238 Float_t numberOfSigmas=-1000.;
240 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kITSpid)) return kFALSE;
241 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kITSpid)) return kTRUE;
243 Double_t mom=part->P();
245 if (part->IsA()==AliESDtrack::Class()){
246 // ESD case in case the PID bit is not set, don't use this track!
247 AliESDtrack *track=static_cast<AliESDtrack*>(part);
248 numberOfSigmas=fESDpid->NumberOfSigmasITS(track, fPartType[icut]);
249 }else if(part->IsA()==AliAODTrack::Class()){
251 // FIXME: Is there a place to check whether the PID is was set in ESD???
252 AliAODTrack *track=static_cast<AliAODTrack*>(part);
253 numberOfSigmas=fAODpidUtil->NumberOfSigmasITS(track, fPartType[icut]);
256 // test if we are supposed to use a function for the cut
257 if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
258 if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
260 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
264 //______________________________________________
265 Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut)
268 // TPC part of the PID check
269 // Don't accept the track if there was no pid bit set
271 Float_t numberOfSigmas=-1000.;
273 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kTPCpid)) return kFALSE;
274 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kTPCpid)) return kTRUE;
276 Double_t mom=part->P();
278 if (part->IsA()==AliESDtrack::Class()){
279 // ESD case in case the PID bit is not set, don't use this track!
280 AliESDtrack *track=static_cast<AliESDtrack*>(part);
281 const AliExternalTrackParam *in = track->GetInnerParam();
282 if (in) mom = in->GetP();
283 numberOfSigmas=fESDpid->NumberOfSigmasTPC(track, fPartType[icut]);
284 }else if(part->IsA()==AliAODTrack::Class()){
286 // FIXME: Is there a place to check whether the PID is was set in ESD???
287 AliAODTrack *track=static_cast<AliAODTrack*>(part);
288 const AliAODPid *pidObj = track->GetDetPid();
289 if (pidObj) mom = pidObj->GetTPCmomentum();
290 numberOfSigmas=fAODpidUtil->NumberOfSigmasTPC(track, fPartType[icut]);
292 if (fPartType[icut]==AliPID::kElectron){
293 numberOfSigmas-=fgCorr;
296 // test if we are supposed to use a function for the cut
297 if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
298 if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
300 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
304 //______________________________________________
305 Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const /*part*/, Int_t /*icut*/)
308 // TRD part of the pid check
313 //______________________________________________
314 Bool_t AliDielectronPID::IsSelectedTOF(AliVTrack * const part, Int_t icut)
317 // TOF part of the PID check
318 // Don't accept the track if there was no pid bit set
320 Float_t numberOfSigmas=-1000.;
322 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kTOFpid)) return kFALSE;
323 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kTOFpid)) return kTRUE;
325 if (part->IsA()==AliESDtrack::Class()){
326 // ESD case in case the PID bit is not set, don't use this track!
327 AliESDtrack *track=static_cast<AliESDtrack*>(part);
328 numberOfSigmas=fESDpid->NumberOfSigmasTOF(track, fPartType[icut], fESDpid->GetTOFResponse().GetTimeZero());
329 }else if(part->IsA()==AliAODTrack::Class()){
331 // FIXME: Is there a place to check whether the PID is was set in ESD???
332 AliAODTrack *track=static_cast<AliAODTrack*>(part);
333 numberOfSigmas=fAODpidUtil->NumberOfSigmasTOF(track, fPartType[icut]);
336 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
340 //______________________________________________
341 void AliDielectronPID::SetDefaults(Int_t def){
343 // initialise default pid strategies
349 // - exclude mu,K,pi,p
351 AddCut(kTPC,AliPID::kElectron,2);
352 AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,0.,kTRUE);
353 AddCut(kTPC,AliPID::kPion,-2.,2.,0.,0.,kTRUE);
354 AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,0.,kTRUE);
355 AddCut(kTPC,AliPID::kProton,-2.,2.,0.,0.,kTRUE);
358 // - include e 0<p<inf
359 // - exclude mu,K,pi,p 0<p<2
361 AddCut(kTPC,AliPID::kElectron,2.);
362 AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,2.,kTRUE);
363 AddCut(kTPC,AliPID::kPion,-2.,2.,0.,2.,kTRUE);
364 AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,2.,kTRUE);
365 AddCut(kTPC,AliPID::kProton,-2.,2.,0.,2.,kTRUE);
368 // include 2sigma e TPC
371 AddCut(kTPC,AliPID::kElectron,-3.,3.);
372 AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
373 AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
376 // include 2sigma e TPC
380 AddCut(kTPC,AliPID::kElectron,2);
381 AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
382 AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
383 AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
386 // include 2sigma e TPC
390 AddCut(kTPC,AliPID::kElectron,2.);
391 AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
392 AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
393 AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
395 AddCut(kTPC,AliPID::kElectron,-0.5,3);
396 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
398 // lower cut TPC: parametrisation by HFE
399 // upper cut TPC: 3 sigma
400 // TOF ele band 3sigma 0<p<1.5GeV
401 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
402 lowerCut->SetParameters(-2.7,-0.4357);
403 AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
404 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
407 // TOF ele band 3sigma 0<p<1.5GeV
408 AddCut(kTPC,AliPID::kElectron,10.);
409 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
411 // TOF 5 sigma inclusion if TOFpid available
412 // this should reduce K,p,Pi to a large extent
413 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
415 // lower cut TPC: parametrisation by HFE
416 // upper cut TPC: 3 sigma
417 // TOF 5 sigma inclusion if TOFpid available
418 // this should reduce K,p,Pi to a large extent
419 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
420 lowerCut->SetParameters(-2.65,-0.6757);
421 AddCut(kTPC,AliPID::kElectron,lowerCut,4.);
422 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
424 } else if (def==10) {
425 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
426 AddCut(kTPC,AliPID::kElectron,3.);
427 AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
428 AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
430 } else if (def==11) {
431 // lower cut TPC: parametrisation by HFE
432 // only use from period d on !!
433 // upper cut TPC: 3 sigma
434 // TOF ele band 3sigma 0<p<2.0GeV
435 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)+[2]", 0, 100);
436 lowerCut->SetParameters(-3.718,-0.4,0.27);
437 AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
438 AddCut(kTOF,AliPID::kElectron,-3,3,0,2.);
439 } else if (def==12) {
440 // lower cut TPC: parametrisation by HFE
441 // only use from period d on !!
442 // upper cut TPC: 3 sigma
443 // TOF 5 sigma inclusion if TOFpid available
444 // this should reduce K,p,Pi to a large extent
445 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)+[2]", 0, 100);
446 lowerCut->SetParameters(-3.718,-0.4,0.27);
447 AddCut(kTPC,AliPID::kElectron,lowerCut,4.);
448 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
453 //______________________________________________
454 void AliDielectronPID::SetCorrVal(Double_t run)
457 // set correction value for run
460 if (!fgFitCorr) return;
461 fgCorr=fgFitCorr->Eval(run);
462 if (run<fgFitCorr->GetX()[0]) fgCorr=fgFitCorr->GetY()[0];
463 if (run>fgFitCorr->GetX()[fgFitCorr->GetN()-1]) fgCorr=fgFitCorr->GetY()[fgFitCorr->GetN()-1];
464 // printf("Corr: %f\n",fgCorr);