]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/RESONANCES/AliRsnCutV0.cxx
Updated cut classes and macro for Sigma* analysis (M. Venaruzzo)
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / AliRsnCutV0.cxx
1 //
2 // Class AliRsnCutV0
3 //
4 // General implementation of a single cut strategy, which can be:
5 // - a value contained in a given interval  [--> IsBetween()   ]
6 // - a value equal to a given reference     [--> MatchesValue()]
7 //
8 // In all cases, the reference value(s) is (are) given as data members
9 // and each kind of cut requires a given value type (Int, UInt, Double),
10 // but the cut check procedure is then automatized and chosen thanks to
11 // an enumeration of the implemented cut types.
12 // At the end, the user (or any other point which uses this object) has
13 // to use the method IsSelected() to check if this cut has been passed.
14 //
15 // authors: Massimo Venaruzzo (massimo.venaruzzo@ts.infn.it)
16 // modified: Enrico Fragiacomo (enrico.fragiacomo@ts.infn.it)
17 //
18
19 #include <Riostream.h>
20 #include <TFormula.h>
21 #include <TBits.h>
22
23 #include "AliLog.h"
24 #include "AliESDtrackCuts.h"
25
26 #include "AliRsnEvent.h"
27 #include "AliRsnDaughter.h"
28 #include "AliRsnCutV0.h"
29
30 ClassImp(AliRsnCutV0)
31
32 //_________________________________________________________________________________________________
33 //AliRsnCutV0::AliRsnCutV0(const char *name, Int_t hypothesis) :
34 AliRsnCutV0::AliRsnCutV0(const char *name, Int_t hypothesis, AliPID::EParticleType pid, AliPID::EParticleType pid2) :
35    AliRsnCut(name, AliRsnTarget::kDaughter),
36    fHypothesis(0),
37    fMass(0.0),
38    fTolerance(0.01),
39    fMaxDCAVertex(0.3),
40    fMinCosPointAngle(0.95),
41    fMaxDaughtersDCA(0.5),
42    fMaxRapidity(0.8),
43    fPID(pid),
44    fPID2(pid2),
45    fPIDCut1(0),
46    fPIDCut2(0),
47    fPIDCut3(0),
48    fESDtrackCuts(0x0),
49    fCutQuality(Form("%sDaughtersQuality", name)),
50    fAODTestFilterBit(5)
51 {
52 //
53 // Default constructor.
54 // Initializes all cuts in such a way that all of them are disabled.
55 //
56
57    SetHypothesis(hypothesis);
58 }
59
60 //_________________________________________________________________________________________________
61 AliRsnCutV0::AliRsnCutV0(const AliRsnCutV0 &copy) :
62    AliRsnCut(copy),
63    fHypothesis(copy.fHypothesis),
64    fMass(copy.fMass),
65    fTolerance(copy.fTolerance),
66    fMaxDCAVertex(copy.fMaxDCAVertex),
67    fMinCosPointAngle(copy.fMinCosPointAngle),
68    fMaxDaughtersDCA(copy.fMaxDaughtersDCA),
69    fMaxRapidity(copy.fMaxRapidity),  
70    fPID(copy.fPID),
71    fPID2(copy.fPID2),
72    fPIDCut1(copy.fPIDCut1),
73    fPIDCut2(copy.fPIDCut2),
74    fPIDCut3(copy.fPIDCut3),
75    fESDtrackCuts(copy.fESDtrackCuts),
76    fCutQuality(copy.fCutQuality),
77    fAODTestFilterBit(copy.fAODTestFilterBit)
78 {
79 //
80 // Copy constructor.
81 // Just copy all data member values.:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
82
83 //
84    fCutQuality.SetPtRange(0.15, 1E+20);
85    fCutQuality.SetEtaRange(-0.8, 0.8);
86    fCutQuality.SetDCARmax(0.05);
87    //fCutQuality.SetDCARPtFormula("0.0182+0.0350/pt^1.01");
88    fCutQuality.SetDCAZmax(2.0);
89    fCutQuality.SetSPDminNClusters(1);
90    fCutQuality.SetITSminNClusters(0);
91    fCutQuality.SetITSmaxChi2(1E+20);
92    fCutQuality.SetTPCminNClusters(70);
93    fCutQuality.SetTPCmaxChi2(4.0);
94    fCutQuality.SetRejectKinkDaughters();
95    fCutQuality.SetAODTestFilterBit(5);
96
97 }
98
99 //_________________________________________________________________________________________________
100 AliRsnCutV0& AliRsnCutV0::operator=(const AliRsnCutV0 &copy)
101 {
102 //
103 // Assignment operator.
104 // Just copy all data member values.
105 //
106    fHypothesis = copy.fHypothesis;
107    fMass = copy.fMass;
108    fTolerance = copy.fTolerance;
109    fMaxDCAVertex = copy.fMaxDCAVertex;
110    fMinCosPointAngle = copy.fMinCosPointAngle;
111    fMaxDaughtersDCA = copy.fMaxDaughtersDCA;
112    fMaxRapidity = copy.fMaxRapidity;
113    fPID = copy.fPID;
114    fPID2 = copy.fPID2;
115    fPIDCut1 = copy.fPIDCut1;
116    fPIDCut2 = copy.fPIDCut2;
117    fPIDCut3 = copy.fPIDCut3;
118    fESDtrackCuts = copy.fESDtrackCuts;
119    fCutQuality = copy.fCutQuality;
120    fAODTestFilterBit = copy.fAODTestFilterBit;
121
122    return (*this);
123  }
124
125 //_________________________________________________________________________________________________
126 Bool_t AliRsnCutV0::IsSelected(TObject *object)
127 {
128 //:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
129
130 // Cut checker.
131 // Checks the type of object being evaluated
132 // and then calls the appropriate sub-function (for ESD or AOD)
133 //
134
135    // coherence check
136    if (!TargetOK(object)) return kFALSE;
137    
138    // check cast
139    AliESDv0 *v0esd = fDaughter->Ref2ESDv0();
140    AliAODv0 *v0aod = fDaughter->Ref2AODv0();
141    //cout << fDaughter->GetRef()->ClassName() << ' ' << v0esd << ' ' << v0aod << endl;
142    
143    // operate depending on cast:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
144
145    if (v0esd) {
146       return CheckESD(v0esd);
147    } else if (v0aod) {
148       return CheckAOD(v0aod);
149    } else {
150       AliDebugClass(1, "Object is not a V0");
151       return kFALSE;
152    }
153 }
154
155 //_________________________________________________________________________________________________
156 Bool_t AliRsnCutV0::CheckESD(AliESDv0 *v0)
157 {
158 //
159 // Check an ESD V0.
160 // This is done using the default track checker for ESD.
161 // It is declared static, not to recreate it every time.
162 //
163
164    AliDebugClass(1, "Check ESD");
165    if (v0->GetOnFlyStatus()) {
166       AliDebugClass(1, "Rejecting V0 in 'on fly' status");
167       return kFALSE; // if kTRUE, then this V0 is recontructed
168    }
169    
170    // retrieve pointer to owner event
171    AliESDEvent *lESDEvent = fEvent->GetRefESD();
172    Double_t xPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetX();
173    Double_t yPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetY();
174    Double_t zPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetZ();
175    AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
176    
177    // retrieve the V0 daughters
178    UInt_t lIdxPos      = (UInt_t) TMath::Abs(v0->GetPindex());
179    UInt_t lIdxNeg      = (UInt_t) TMath::Abs(v0->GetNindex());
180    AliESDtrack *pTrack = lESDEvent->GetTrack(lIdxPos);
181    AliESDtrack *nTrack = lESDEvent->GetTrack(lIdxNeg);
182    
183    // check quality cuts
184    if (fESDtrackCuts) {
185       AliDebugClass(2, "Checking quality cuts");
186       if (!fESDtrackCuts->IsSelected(pTrack)) {
187          AliDebugClass(2, "Positive daughter failed quality cuts");
188          return kFALSE;
189       }
190       if (!fESDtrackCuts->IsSelected(nTrack)) {
191          AliDebugClass(2, "Negative daughter failed quality cuts");
192          return kFALSE;
193       }
194    }
195    
196    // filter like-sign V0
197   if ( TMath::Abs( ((pTrack->GetSign()) - (nTrack->GetSign())) ) < 0.1) {
198      AliDebugClass(2, "Failed like-sign V0 check");
199      return kFALSE;
200   }
201
202    
203    // check compatibility with expected species hypothesis
204    v0->ChangeMassHypothesis(fHypothesis);
205    if ((TMath::Abs(v0->GetEffMass() - fMass)) > fTolerance) {
206       AliDebugClass(2, "V0 is not in the expected inv mass range");
207       return kFALSE;
208    }
209    
210    // topological checks
211    if (TMath::Abs(v0->GetD(xPrimaryVertex, yPrimaryVertex, zPrimaryVertex)) > fMaxDCAVertex) {
212       AliDebugClass(2, "Failed check on DCA to primary vertes");
213       return kFALSE;
214    }
215    if (TMath::Abs(v0->GetV0CosineOfPointingAngle()) < fMinCosPointAngle) {
216       AliDebugClass(2, "Failed check on cosine of pointing angle");
217       return kFALSE;
218    }
219    if (TMath::Abs(v0->GetDcaV0Daughters()) > fMaxDaughtersDCA) {
220       AliDebugClass(2, "Failed check on DCA between daughters");
221       return kFALSE;
222    }
223    if (TMath::Abs(v0->Y(fHypothesis)) > fMaxRapidity) {
224    AliDebugClass(2, "Failed check on V0 rapidity");
225    return kFALSE;
226    }
227    
228    
229    // check PID on proton or antiproton from V0
230   
231         // check initialization of PID object
232         AliPIDResponse *pid = fEvent->GetPIDResponse();
233         if (!pid) {
234         AliFatal("NULL PID response");
235               return kFALSE;
236         }
237    
238         // check if TOF is matched
239            // and computes all values used in the PID cut
240            //Bool_t   isTOFpos  = MatchTOF(ptrack);
241            //Bool_t   isTOFneg  = MatchTOF(ntrack);
242            Double_t pospTPC   = pTrack->GetTPCmomentum();
243            Double_t negpTPC   = nTrack->GetTPCmomentum();
244            //Double_t posp      = pTrack->P();
245            //Double_t negp      = nTrack->P();
246            Double_t posnsTPC   = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
247            Double_t posnsTPC2  = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
248            //Double_t posnsTOF  = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
249            Double_t negnsTPC   = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
250            Double_t negnsTPC2  = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
251            //Double_t negnsTOF  = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
252            Double_t maxTPC = 1E20;
253            Double_t maxTPC2 = 1E20;
254            //Double_t maxTOF = 1E20;
255    
256         // applies the cut differently depending on the PID and the momentum
257         
258         if(fHypothesis==kLambda0){
259            //if (isTOFpos) {
260               // TPC: 5sigma cut for all
261               //if (posnsTPC > 5.0) return kFALSE;
262               // TOF: 3sigma
263              // maxTOF = 3.0;
264                 //return (posnsTOF <= maxTOF);
265               //} else {
266               // TPC: 
267               // below 600 MeV: 4sigma
268               // above 600 MeV: 3sigma
269               
270               if (pospTPC <= 0.6 && fPID==AliPID::kProton) 
271               maxTPC = fPIDCut1;
272               else if (pospTPC > 0.6 && fPID==AliPID::kProton)
273               maxTPC = fPIDCut2;
274               else
275               return kFALSE; 
276               
277               maxTPC2 = fPIDCut3;           
278               
279               if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
280               AliDebugClass(2, "Failed check on V0 PID");
281               return kFALSE;
282              } 
283            }
284            
285            //}
286             
287          if(fHypothesis==kLambda0Bar){
288            //if (isTOFneg) {
289               // TPC: 5sigma cut for all
290               //if (negnsTPC > 5.0) return kFALSE;
291               // TOF: 3sigma 
292              // maxTOF = 3.0;
293                 //return (negnsTOF <= maxTOF);
294               //} else {
295               // TPC: 
296               // below 600 MeV: 4sigma
297               // above 600 MeV: 3sigma
298               
299               if (negpTPC <= 0.6 && fPID==AliPID::kProton) 
300               maxTPC = fPIDCut1;
301               else if (negpTPC > 0.6 && fPID==AliPID::kProton)
302               maxTPC = fPIDCut2;
303               else
304               return kFALSE; 
305               
306               maxTPC2 = fPIDCut3;            
307
308               if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ){
309               AliDebugClass(2, "Failed check on V0 PID");
310               return kFALSE;
311               }
312            }
313           //}
314         
315    
316    // if we reach this point, all checks were successful
317    AliDebugClass(2, "Good V0 (hallelujah)");
318    return kTRUE;   
319 }
320
321 //_________________________________________________________________________________________________
322 Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
323 {
324 //
325 // Check an AOD V0.
326 // This is done doing directly all checks, since there is not
327 // an equivalend checker for AOD tracks
328 //
329
330    AliDebugClass(2, "Check AOD");
331    if (v0->GetOnFlyStatus()) {
332       AliDebugClass(2, "Rejecting V0 in 'on fly' status");
333       return kFALSE; // if kTRUE, then this V0 is recontructed
334    }
335
336  
337    
338    // retrieve pointer to owner event
339    AliAODEvent *lAODEvent = fEvent->GetRefAOD();
340    Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
341    Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
342    Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
343    AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
344
345    // retrieve the V0 daughters
346    AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
347    AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
348
349
350    // check quality cuts
351    UInt_t  filtermapP = 9999;
352    UInt_t  filtermapN = 9999;
353    filtermapP = pTrack->GetFilterMap();
354    filtermapN = nTrack->GetFilterMap();
355    
356    
357    if ( !pTrack->TestFilterBit(fAODTestFilterBit)   ) {
358      AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
359      return kFALSE;
360    }
361    if ( !nTrack->TestFilterBit(fAODTestFilterBit)   ) {
362      AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
363      return kFALSE;
364    }
365    
366    
367
368    AliDebugClass(1, Form("fESDtrackCuts=%p",fESDtrackCuts));
369    if (fESDtrackCuts) { // use fESDtrackCuts to retrieve cuts values
370
371     
372      AliDebugClass(2, "Checking quality cuts");
373
374
375      
376      const Bool_t  CutAcceptKinkDaughters  = fESDtrackCuts->GetAcceptKinkDaughters(); // 0 = kFalse
377      const Float_t CutMaxChi2PerClusterTPC = fESDtrackCuts->GetMaxChi2PerClusterTPC();
378      const Int_t   CutMinNClusterTPC       = fESDtrackCuts->GetMinNClusterTPC();
379      const Bool_t  CutRequireTPCRefit      = fESDtrackCuts->GetRequireTPCRefit();
380      //AliDebugClass(2, Form("accept kink=%d maxchi2=%f minnclSTPC=%d requireTPCrefit=%d", CutAcceptKinkDaughters,
381      //            CutMaxChi2PerClusterTPC, CutMinNClusterTPC, CutRequireTPCRefit));
382      //AliDebugClass(2, Form("pTrack->TPCNcls=%d", pTrack->GetTPCNcls() ));
383      //AliDebugClass(2, Form("nTrack->TPCNcls=%d", nTrack->GetTPCNcls() ));
384      
385      
386       if(pTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Positive daughter not MinNclsTPC"); return kFALSE;}
387       if(nTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Negative daughter not MinNclsTPC"); return kFALSE;}
388
389    }
390
391    // filter like-sign V0
392   if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
393      AliDebugClass(2, "Failed like-sign V0 check");
394      return kFALSE;
395   }
396
397    // check compatibility with expected species hypothesis
398   Double_t mass = 0.0;
399   if(fHypothesis==kLambda0) {
400     mass = v0->MassLambda();
401   }
402   else if (fHypothesis==kLambda0Bar) {
403     mass = v0->MassAntiLambda();   
404   }
405   if ((TMath::Abs(mass - fMass)) > fTolerance) {
406     AliDebugClass(2, Form("V0 is not in the expected inv mass range  Mass: %d %f %f", fHypothesis, fMass, mass));
407     return kFALSE;
408   }
409    AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
410   
411
412   // topological checks
413   if (TMath::Abs(v0->DcaV0ToPrimVertex()) > fMaxDCAVertex) {
414     AliDebugClass(2, Form("Failed check on DCA to primary vertes dca=%f maxdca=%f",TMath::Abs(v0->DcaV0ToPrimVertex()),fMaxDCAVertex));
415     return kFALSE;
416   }
417   if (TMath::Abs( TMath::Cos(v0->OpenAngleV0()) ) < fMinCosPointAngle) {
418       AliDebugClass(2, "Failed check on cosine of pointing angle");
419       return kFALSE;
420    }
421    if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
422       AliDebugClass(2, "Failed check on DCA between daughters");
423       return kFALSE;
424    }
425    if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
426    AliDebugClass(2, "Failed check on V0 rapidity");
427    return kFALSE;
428    }
429
430
431
432    
433
434    // check initialization of PID object
435    AliPIDResponse *pid = fEvent->GetPIDResponse();
436    if (!pid) {
437      AliFatal("NULL PID response");
438      return kFALSE;
439    }
440
441    // check if TOF is matched
442    // and computes all values used in the PID cut
443    //Bool_t   isTOFpos  = MatchTOF(ptrack);
444    //Bool_t   isTOFneg  = MatchTOF(ntrack);
445    Double_t pospTPC   = pTrack->GetTPCmomentum();
446    Double_t negpTPC   = nTrack->GetTPCmomentum();
447    //Double_t posp      = pTrack->P();
448    //Double_t negp      = nTrack->P();
449    Double_t posnsTPC   = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
450    Double_t posnsTPC2  = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
451    //Double_t posnsTOF  = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
452    Double_t negnsTPC   = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
453    Double_t negnsTPC2  = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
454    //Double_t negnsTOF  = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
455    Double_t maxTPC = 1E20;
456    Double_t maxTPC2 = 1E20;
457    //Double_t maxTOF = 1E20;
458    
459    // applies the cut differently depending on the PID and the momentum
460    
461    if(fHypothesis==kLambda0){
462
463
464      //if (isTOFpos) {
465      // TPC: 5sigma cut for all
466      //if (posnsTPC > 5.0) return kFALSE;
467      // TOF: 3sigma
468      // maxTOF = 3.0;
469      //return (posnsTOF <= maxTOF);
470      //} else {
471      // TPC: 
472      // below 600 MeV: 4sigma
473      // above 600 MeV: 3sigma
474      
475      if (pospTPC <= 0.6 && fPID==AliPID::kProton) 
476        maxTPC = fPIDCut1; // EF safer value to run on MC
477      else if (pospTPC > 0.6 && fPID==AliPID::kProton)
478        maxTPC = fPIDCut2; // EF safer value to run on MC
479      else
480        return kFALSE; 
481                 
482      maxTPC2 = fPIDCut3; // EF safer value to run on MC
483      
484      if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
485        AliDebugClass(2, "Failed check on V0 PID");
486        return kFALSE;
487      } 
488    }
489       
490    if(fHypothesis==kLambda0Bar){
491
492      //if (isTOFneg) {
493      // TPC: 5sigma cut for all
494      //if (negnsTPC > 5.0) return kFALSE;
495      // TOF: 3sigma 
496      // maxTOF = 3.0;
497      //return (negnsTOF <= maxTOF);
498      //} else {
499      // TPC: 
500      // below 600 MeV: 4sigma
501      // above 600 MeV: 3sigma
502      
503      if (negpTPC <= 0.6 && fPID==AliPID::kProton) 
504        maxTPC = fPIDCut1; // EF safer value to run on MC
505      else if (negpTPC > 0.6 && fPID==AliPID::kProton)
506        maxTPC = fPIDCut2; // EF safer value to run on MC
507      else
508        return kFALSE; 
509            
510      maxTPC2 = fPIDCut3; // EF safer value to run on MC
511      
512      if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ){
513        AliDebugClass(2, "Failed check on V0 PID");
514        return kFALSE;
515      }
516    }
517    
518    
519
520    // if we reach this point, all checks were successful
521    AliDebugClass(1, "Good AOD V0 (hallelujah)");
522    AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
523    return kTRUE;   
524
525 }
526
527 //_________________________________________________________________________________________________
528 void AliRsnCutV0::Print(const Option_t *) const
529 {
530 //
531 // Print information on this cut
532 //
533 }