]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/dielectron/AliDielectronPID.cxx
Major update of the framework
[u/mrichter/AliRoot.git] / PWG3 / dielectron / AliDielectronPID.cxx
CommitLineData
8df8e382 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/*
21Detailed description
22
23
24*/
25// //
26///////////////////////////////////////////////////////////////////////////
27
28#include <TMath.h>
29#include <TF1.h>
30
31#include <AliVParticle.h>
32#include <AliLog.h>
33#include <AliESDtrack.h>
34
35#include "AliDielectronVarManager.h"
36
37#include "AliDielectronPID.h"
38
39ClassImp(AliDielectronPID)
40
41AliDielectronPID::AliDielectronPID() :
42 AliAnalysisCuts(),
43 fNcuts(0),
8df8e382 44 fESDpid(0x0)
45{
46 //
47 // Default Constructor
48 //
49 for (Int_t icut=0; icut<kNmaxPID; ++icut){
50 fDetType[icut]=kTPC;
51 fPartType[icut]=AliPID::kPion;
52 fNsigmaLow[icut]=0;
53 fNsigmaUp[icut]=0;
54 fPmin[icut]=0;
55 fPmax[icut]=0;
56 fExclude[icut]=kFALSE;
57 fFunUpperCut[icut]=0x0;
58 fFunLowerCut[icut]=0x0;
61d106d3 59 fRequirePIDbit[icut]=0;
8df8e382 60 }
61}
62
63//______________________________________________
64AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
65 AliAnalysisCuts(name, title),
66 fNcuts(0),
8df8e382 67 fESDpid(0x0)
68{
69 //
70 // Named Constructor
71 //
72 for (Int_t icut=0; icut<kNmaxPID; ++icut){
73 fDetType[icut]=kTPC;
74 fPartType[icut]=AliPID::kPion;
75 fNsigmaLow[icut]=0;
76 fNsigmaUp[icut]=0;
77 fPmin[icut]=0;
78 fPmax[icut]=0;
79 fExclude[icut]=kFALSE;
80 fFunUpperCut[icut]=0x0;
81 fFunLowerCut[icut]=0x0;
61d106d3 82 fRequirePIDbit[icut]=0;
8df8e382 83 }
84}
85
86//______________________________________________
87AliDielectronPID::~AliDielectronPID()
88{
89 //
90 // Default Destructor
91 //
92}
93
94//______________________________________________
95void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp/*=-99999.*/,
61d106d3 96 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
97 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
8df8e382 98{
99 //
100 // Add a pid nsigma cut
101 // use response of detector 'det' in the momentum range ('pMin') to ['pMax']
102 // use a sigma band betwee 'nSigmaLow' and 'nSigmaUp'
103 // if nSigmaUp==-99999. then nSigmaLow will be uesd as a symmetric band +- nSigmaLow
104 // specify whether to 'exclude' the given band
105 //
106
107 if (fNcuts==kNmaxPID){
108 AliError(Form("only %d pid cut ranges allowed",kNmaxPID));
109 }
110 if (TMath::Abs(nSigmaUp+99999.)<1e-20){
111 nSigmaUp=TMath::Abs(nSigmaLow);
112 nSigmaLow=-1.*nSigmaUp;
113 }
114 fDetType[fNcuts]=det;
115 fPartType[fNcuts]=type;
116 fNsigmaLow[fNcuts]=nSigmaLow;
117 fNsigmaUp[fNcuts]=nSigmaUp;
118 fPmin[fNcuts]=pMin;
119 fPmax[fNcuts]=pMax;
120 fExclude[fNcuts]=exclude;
61d106d3 121 fRequirePIDbit[fNcuts]=pidBitType;
8df8e382 122 ++fNcuts;
123
124}
125
126//______________________________________________
127void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, TF1 * const funUp,
61d106d3 128 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
129 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
8df8e382 130{
131 //
132 // cut using a TF1 as upper cut
133 //
134 if (funUp==0x0){
135 AliError("A valid function is required for the upper cut. Not adding the cut!");
136 return;
137 }
138 fFunUpperCut[fNcuts]=funUp;
61d106d3 139 AddCut(det,type,nSigmaLow,0.,pMin,pMax,exclude,pidBitType);
8df8e382 140}
141
142//______________________________________________
143void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, Double_t nSigmaUp,
61d106d3 144 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
145 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
8df8e382 146{
147 //
148 // cut using a TF1 as lower cut
149 //
150 if (funLow==0x0){
151 AliError("A valid function is required for the lower cut. Not adding the cut!");
152 return;
153 }
154 fFunLowerCut[fNcuts]=funLow;
61d106d3 155 AddCut(det,type,0.,nSigmaUp,pMin,pMax,exclude,pidBitType);
8df8e382 156}
157
158//______________________________________________
159void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, TF1 * const funUp,
61d106d3 160 Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
161 UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
8df8e382 162{
163 //
164 // cut using a TF1 as lower and upper cut
165 //
166 if ( (funUp==0x0) || (funLow==0x0) ){
167 AliError("A valid function is required for upper and lower cut. Not adding the cut!");
168 return;
169 }
170 fFunUpperCut[fNcuts]=funUp;
171 fFunLowerCut[fNcuts]=funLow;
61d106d3 172 AddCut(det,type,0.,0.,pMin,pMax,exclude,pidBitType);
8df8e382 173}
174
175//______________________________________________
176Bool_t AliDielectronPID::IsSelected(TObject* track)
177{
178 //
179 // perform PID cuts
180 //
181
182 //loop over all cuts
183 AliVParticle *part=static_cast<AliVParticle*>(track);
184 //TODO: Which momentum to use?
185 // Different momenta for different detectors?
186 Double_t mom=part->P();
187
188 Bool_t selected=kFALSE;
189 fESDpid=AliDielectronVarManager::GetESDpid();
190
191 for (UChar_t icut=0; icut<fNcuts; ++icut){
192 Double_t pMin=fPmin[icut];
193 Double_t pMax=fPmax[icut];
194
195 // test momentum range. In case pMin==pMax use all momenta
196 if ( (TMath::Abs(pMin-pMax)>1e-20) && (mom<=pMin || mom>pMax) ) continue;
197
198 // test if we are supposed to use a function for the cut
199 if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
200 if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
201
202 switch (fDetType[icut]){
203 case kITS:
204 selected = IsSelectedITS(part,icut);
205 break;
206 case kTPC:
207 selected = IsSelectedTPC(part,icut);
208 break;
209 case kTRD:
210 selected = IsSelectedTRD(part,icut);
211 break;
212 case kTOF:
213 selected = IsSelectedTOF(part,icut);
214 break;
215 }
216 if (!selected) return kFALSE;
217 }
218
219 return selected;
220}
221
222//______________________________________________
223Bool_t AliDielectronPID::IsSelectedITS(AliVParticle * const part, Int_t icut) const
224{
225 //
226 // ITS part of the PID check
227 // Don't accept the track if there was no pid bit set
228 //
229 Float_t numberOfSigmas=-1000.;
230
231 if (part->IsA()==AliESDtrack::Class()){
232 // ESD case in case the PID bit is not set, don't use this track!
233 AliESDtrack *track=static_cast<AliESDtrack*>(part);
61d106d3 234 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(track->GetStatus()&AliESDtrack::kITSpid)) return kFALSE;
235 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(track->GetStatus()&AliESDtrack::kITSpid)) return kTRUE;
8df8e382 236
237 numberOfSigmas=fESDpid->NumberOfSigmasITS(track, fPartType[icut]);
238 }else{
239 // AOD case
240 // FIXME: Is there a place to check whether the PID is was set in ESD???
241 AliAODTrack *track=static_cast<AliAODTrack*>(part);
242 numberOfSigmas=NumberOfSigmasITS(track, fPartType[icut]);
243 }
244 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
245 return selected;
246}
247
248//______________________________________________
249Bool_t AliDielectronPID::IsSelectedTPC(AliVParticle * const part, Int_t icut) const
250{
251 //
252 // TPC part of the PID check
253 // Don't accept the track if there was no pid bit set
254 //
255 Float_t numberOfSigmas=-1000.;
256
257 if (part->IsA()==AliESDtrack::Class()){
258 // ESD case in case the PID bit is not set, don't use this track!
259 AliESDtrack *track=static_cast<AliESDtrack*>(part);
61d106d3 260 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(track->GetStatus()&AliESDtrack::kTPCpid)) return kFALSE;
261 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(track->GetStatus()&AliESDtrack::kTPCpid)) return kTRUE;
8df8e382 262
263 numberOfSigmas=fESDpid->NumberOfSigmasTPC(track, fPartType[icut]);
264 }else{
265 // AOD case
266 // FIXME: Is there a place to check whether the PID is was set in ESD???
267 AliAODTrack *track=static_cast<AliAODTrack*>(part);
268 numberOfSigmas=NumberOfSigmasTPC(track, fPartType[icut]);
269 }
270
271 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
272 return selected;
273}
274
275//______________________________________________
276Bool_t AliDielectronPID::IsSelectedTRD(AliVParticle * const /*part*/, Int_t /*icut*/) const
277{
278 //
279 // TRD part of the pid check
280 //
281 return kFALSE;
282}
283
284//______________________________________________
285Bool_t AliDielectronPID::IsSelectedTOF(AliVParticle * const part, Int_t icut) const
286{
287 //
288 // TOF part of the PID check
289 // Don't accept the track if there was no pid bit set
290 //
291 Float_t numberOfSigmas=-1000.;
292
293 if (part->IsA()==AliESDtrack::Class()){
294 // ESD case in case the PID bit is not set, don't use this track!
295 AliESDtrack *track=static_cast<AliESDtrack*>(part);
61d106d3 296 if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(track->GetStatus()&AliESDtrack::kTOFpid)) return kFALSE;
297 if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(track->GetStatus()&AliESDtrack::kTOFpid)) return kTRUE;
8df8e382 298
299 numberOfSigmas=fESDpid->NumberOfSigmasTOF(track, fPartType[icut], fESDpid->GetTOFResponse().GetTimeZero());
300 }else{
301 // AOD case
302 // FIXME: Is there a place to check whether the PID is was set in ESD???
303 AliAODTrack *track=static_cast<AliAODTrack*>(part);
304 numberOfSigmas=NumberOfSigmasTOF(track, fPartType[icut]);
305 }
306
307 Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
308 return selected;
309}
310
311//______________________________________________
312void AliDielectronPID::SetDefaults(Int_t def){
313 //
314 // initialise default pid strategies
315 //
316
317 if (def==0){
318 // 2sigma bands TPC:
319 // - include e
320 // - exclude mu,K,pi,p
321 // -complete p range
322 AddCut(kTPC,AliPID::kElectron,2);
323 AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,0.,kTRUE);
324 AddCut(kTPC,AliPID::kPion,-2.,2.,0.,0.,kTRUE);
325 AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,0.,kTRUE);
326 AddCut(kTPC,AliPID::kProton,-2.,2.,0.,0.,kTRUE);
327 } else if (def==1) {
328 // 2sigma bands TPC:
329 // - include e 0<p<inf
330 // - exclude mu,K,pi,p 0<p<2
331
332 AddCut(kTPC,AliPID::kElectron,2.);
333 AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,2.,kTRUE);
334 AddCut(kTPC,AliPID::kPion,-2.,2.,0.,2.,kTRUE);
335 AddCut(kTPC,AliPID::kKaon,-2.,2.,0.,2.,kTRUE);
336 AddCut(kTPC,AliPID::kProton,-2.,2.,0.,2.,kTRUE);
337
338 } else if (def==2) {
339 // include 2sigma e TPC
340 // 3sigma bands TOF
341 // - exclude K,P
342 AddCut(kTPC,AliPID::kElectron,2.);
343 AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,0.,kTRUE);
344 AddCut(kTOF,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
345
346 } else if (def==3) {
347 // include 2sigma e TPC
348 // 3sigma bands TOF
349 // - exclude K 0<p<1
350 // - exclude P 0<p<2
351 AddCut(kTPC,AliPID::kElectron,2);
352 AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
353 AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
354 AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
355
356 } else if (def==4) {
357 // include 2sigma e TPC
358 // 3sigma bands TOF
359 // - exclude K 0<p<1
360 // - exclude P 0<p<2
361 AddCut(kTPC,AliPID::kElectron,2.);
362 AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
363 AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
364 AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
8df8e382 365 } else if (def==5) {
366 AddCut(kTPC,AliPID::kElectron,-0.5,3);
367 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
368 } else if (def==6) {
369 // lower cut TPC: parametrisation by HFE
370 // upper cut TPC: 3 sigma
371 // TOF ele band 3sigma 0<p<1.5GeV
372 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
373 lowerCut->SetParameters(-2.7,-0.4357);
374 AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
375 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
376 } else if (def==7) {
61d106d3 377 // wide TPC cut
8df8e382 378 // TOF ele band 3sigma 0<p<1.5GeV
379 AddCut(kTPC,AliPID::kElectron,10.);
380 AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
61d106d3 381 } else if (def==8) {
382 // TOF 5 sigma inclusion if TOFpid available
383 // this should reduce K,p,Pi to a large extent
384 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
385 } else if (def==9) {
386 // lower cut TPC: parametrisation by HFE
387 // upper cut TPC: 3 sigma
388 // TOF 5 sigma inclusion if TOFpid available
389 // this should reduce K,p,Pi to a large extent
390 TF1 *lowerCut=new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 100);
391 lowerCut->SetParameters(-2.7,-0.4357);
392 AddCut(kTPC,AliPID::kElectron,lowerCut,3.);
393 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
394 } else if (def==10) {
395 AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
396 AddCut(kTPC,AliPID::kElectron,3.);
397 AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
398 AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
399
8df8e382 400 }
401}
402