]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/RESONANCES/AliRsnCutTrackQuality.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / AliRsnCutTrackQuality.cxx
1 //
2 // Class AliRsnCutTrackQuality
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: Martin Vala (martin.vala@cern.ch)
16 //          Alberto Pulvirenti (alberto.pulvirenti@ct.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 "AliRsnCutTrackQuality.h"
29
30 ClassImp(AliRsnCutTrackQuality)
31
32 //_________________________________________________________________________________________________
33 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const char *name) :
34    AliRsnCut(name, AliRsnTarget::kDaughter, 0.0, 0.0),
35    fFlagsOn(0x0),
36    fFlagsOff(0x0),
37    fRejectKinkDaughters(kTRUE),
38    fDCARfixed(kTRUE),
39    fDCARptFormula(""),
40    fDCARmax(1E20),
41    fDCAZfixed(kTRUE),
42    fDCAZptFormula(""),
43    fDCAZmax(1E20),
44    fSPDminNClusters(0),
45    fITSminNClusters(0),
46    fITSmaxChi2(1E20),
47    fTPCminNClusters(0),
48    fTPCmaxChi2(1E20),
49    fCutMaxChi2TPCConstrainedVsGlobal(1E20),
50    fTPCminNCrossedRows(0),
51    fTPCminCrossedRowsOverFindableCls(0),
52    fCutMinLengthActiveVolumeTPC(0),
53    fAODTestFilterBit(-1),
54    fCheckOnlyFilterBit(kTRUE),
55    fESDtrackCuts(0x0)
56 {
57 //
58 // Default constructor.
59 // Initializes all cuts in such a way that all of them are disabled.
60 //
61
62    SetPtRange(0.0, 1E20);
63    SetEtaRange(-1E20, 1E20);
64 }
65
66 //_________________________________________________________________________________________________
67 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const AliRsnCutTrackQuality &copy) :
68    AliRsnCut(copy),
69    fFlagsOn(copy.fFlagsOn),
70    fFlagsOff(copy.fFlagsOff),
71    fRejectKinkDaughters(copy.fRejectKinkDaughters),
72    fDCARfixed(copy.fDCARfixed),
73    fDCARptFormula(copy.fDCARptFormula),
74    fDCARmax(copy.fDCARmax),
75    fDCAZfixed(copy.fDCAZfixed),
76    fDCAZptFormula(copy.fDCAZptFormula),
77    fDCAZmax(copy.fDCAZmax),
78    fSPDminNClusters(copy.fSPDminNClusters),
79    fITSminNClusters(copy.fITSminNClusters),
80    fITSmaxChi2(copy.fITSmaxChi2),
81    fTPCminNClusters(copy.fTPCminNClusters),
82    fTPCmaxChi2(copy.fTPCmaxChi2),
83    fCutMaxChi2TPCConstrainedVsGlobal(copy.fCutMaxChi2TPCConstrainedVsGlobal),
84    fTPCminNCrossedRows(copy.fTPCminNCrossedRows),
85    fTPCminCrossedRowsOverFindableCls(copy.fTPCminCrossedRowsOverFindableCls),
86    fCutMinLengthActiveVolumeTPC(copy.fCutMinLengthActiveVolumeTPC),
87    fAODTestFilterBit(copy.fAODTestFilterBit),
88    fCheckOnlyFilterBit(copy.fCheckOnlyFilterBit),
89    fESDtrackCuts(copy.fESDtrackCuts)
90 {
91 //
92 // Copy constructor.
93 // Just copy all data member values.
94 //
95
96    SetPtRange(copy.fPt[0], copy.fPt[1]);
97    SetEtaRange(copy.fEta[0], copy.fEta[1]);
98 }
99
100 //_________________________________________________________________________________________________
101 AliRsnCutTrackQuality &AliRsnCutTrackQuality::operator=(const AliRsnCutTrackQuality &copy)
102 {
103 //
104 // Assignment operator.
105 // Just copy all data member values.
106 //
107
108    if (this == &copy)
109       return *this;
110
111    fFlagsOn = copy.fFlagsOn;
112    fFlagsOff = copy.fFlagsOff;
113    fRejectKinkDaughters = copy.fRejectKinkDaughters;
114    fDCARfixed = copy.fDCARfixed;
115    fDCARptFormula = copy.fDCARptFormula;
116    fDCARmax = copy.fDCARmax;
117    fDCAZfixed = copy.fDCAZfixed;
118    fDCAZptFormula = copy.fDCAZptFormula;
119    fDCAZmax = copy.fDCAZmax;
120    fSPDminNClusters = copy.fSPDminNClusters;
121    fITSminNClusters = copy.fITSminNClusters;
122    fITSmaxChi2 = copy.fITSmaxChi2;
123    fTPCminNClusters = copy.fTPCminNClusters;
124    fTPCmaxChi2 = copy.fTPCmaxChi2;
125    fCutMaxChi2TPCConstrainedVsGlobal = copy.fCutMaxChi2TPCConstrainedVsGlobal;
126    fTPCminNCrossedRows = copy.fTPCminNCrossedRows;
127    fTPCminCrossedRowsOverFindableCls = copy.fTPCminCrossedRowsOverFindableCls;
128    fCutMinLengthActiveVolumeTPC = copy.fCutMinLengthActiveVolumeTPC;
129    
130    fAODTestFilterBit = copy.fAODTestFilterBit;
131    fCheckOnlyFilterBit = copy.fCheckOnlyFilterBit;
132    fESDtrackCuts = copy.fESDtrackCuts;
133    SetPtRange(copy.fPt[0], copy.fPt[1]);
134    SetEtaRange(copy.fEta[0], copy.fEta[1]);
135
136    return (*this);
137 }
138
139 //_________________________________________________________________________________________________
140 void AliRsnCutTrackQuality::DisableAll()
141 {
142 //
143 // Disable all cuts
144 //
145
146    fFlagsOn = 0x0;
147    fFlagsOff = 0x0;
148    fRejectKinkDaughters = kFALSE;
149    fDCARfixed = kTRUE;
150    fDCARptFormula = "";
151    fDCARmax = 1E20;
152    fDCAZfixed = kTRUE;
153    fDCAZptFormula = "";
154    fDCAZmax = 1E20;
155    fSPDminNClusters = 0;
156    fITSminNClusters = 0;
157    fITSmaxChi2 = 1E20;
158    fTPCminNClusters = 0;
159    fTPCmaxChi2 = 1E20;
160    fAODTestFilterBit = -1;
161    fCutMaxChi2TPCConstrainedVsGlobal = 1E20;
162    fTPCminNCrossedRows = 0;
163    fTPCminCrossedRowsOverFindableCls = 0;
164    fCutMinLengthActiveVolumeTPC = 0.0;
165  
166    if (fESDtrackCuts) {
167       const char *cutsName = fESDtrackCuts->GetName();
168       const char *cutsTitle = fESDtrackCuts->GetTitle();
169       delete fESDtrackCuts;
170       fESDtrackCuts = new AliESDtrackCuts(cutsName,cutsTitle);
171    }
172    SetPtRange(0.0, 1E20);
173    SetEtaRange(-1E20, 1E20);
174 }
175
176 //_________________________________________________________________________________________________
177 Bool_t AliRsnCutTrackQuality::IsSelected(TObject *object)
178 {
179 //
180 // Cut checker.
181 // Checks the type of object being evaluated
182 // and then calls the appropriate sub-function (for ESD or AOD)
183 //
184
185    // coherence check
186    if (!TargetOK(object)) return kFALSE;
187
188    // status is checked in the same way for all tracks, using AliVTrack
189    // as a convention, if a the collection of 'on' flags is '0x0', it
190    // is assumed that no flags are required, and this check is skipped;
191    // for the collection of 'off' flags this is not needed
192    AliVTrack *vtrack = fDaughter->Ref2Vtrack();
193    if (!vtrack) {
194       AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
195       return kFALSE;
196    }
197    ULong_t status   = (ULong_t)vtrack->GetStatus();
198    ULong_t checkOn  = status & fFlagsOn;
199    ULong_t checkOff = status & fFlagsOff;
200    if (fFlagsOn != 0x0 && checkOn != fFlagsOn) {
201       AliDebug(AliLog::kDebug + 2, Form("Failed flag check: required  %s", Binary(fFlagsOn)));
202       AliDebug(AliLog::kDebug + 2, Form("                   track has %s", Binary(status  )));
203       return kFALSE;
204    }
205    if (checkOff != 0) {
206       AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
207       AliDebug(AliLog::kDebug + 2, Form("                   track has %s", Binary(status  )));
208       return kFALSE;
209    }
210    AliDebug(AliLog::kDebug + 3, Form("Flag check OK: required  %s", Binary(fFlagsOn)));
211    AliDebug(AliLog::kDebug + 3, Form("               forbidden %s", Binary(fFlagsOff)));
212    AliDebug(AliLog::kDebug + 3, Form("               track has %s", Binary(status  )));
213
214    // retrieve real object type
215    AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
216    AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
217    if (esdTrack) {
218       AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
219       if (fESDtrackCuts)
220          return fESDtrackCuts->IsSelected(esdTrack);
221       else
222          return CheckESD(esdTrack);
223    } else if (aodTrack) {
224       AliDebug(AliLog::kDebug + 2, "Checking an AOD track");
225       return CheckAOD(aodTrack);
226    } else {
227       AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
228       return kFALSE;
229    }
230 }
231
232 //_________________________________________________________________________________________________
233 Bool_t AliRsnCutTrackQuality::CheckESD(AliESDtrack *track)
234 {
235 //
236 // Check an ESD track.
237 // This is done using the default track checker for ESD.
238 // It is declared static, not to recreate it every time.
239 //
240   //static AliESDtrackCuts cuts;
241   AliESDtrackCuts cuts;
242
243    // general acceptance/pt cuts
244    cuts.SetPtRange(fPt[0], fPt[1]);
245    cuts.SetEtaRange(fEta[0], fEta[1]);
246
247    // transverse DCA cuts
248    if (fDCARfixed)
249       cuts.SetMaxDCAToVertexXY(fDCARmax);
250    else
251       cuts.SetMaxDCAToVertexXYPtDep(fDCARptFormula.Data());
252
253    // longitudinal DCA cuts
254    if (fDCAZfixed)
255       cuts.SetMaxDCAToVertexZ(fDCAZmax);
256    else
257       cuts.SetMaxDCAToVertexZPtDep(fDCAZptFormula.Data());
258
259    // these options are always disabled in current version
260    cuts.SetDCAToVertex2D(kFALSE);
261    cuts.SetRequireSigmaToVertex(kFALSE);
262
263    // TPC related cuts for TPC+ITS tracks
264    cuts.SetMinNClustersTPC(fTPCminNClusters);
265    cuts.SetMaxChi2PerClusterTPC(fTPCmaxChi2);
266    cuts.SetAcceptKinkDaughters(!fRejectKinkDaughters);
267    cuts.SetMaxChi2TPCConstrainedGlobal(fCutMaxChi2TPCConstrainedVsGlobal);
268    cuts.SetMinNCrossedRowsTPC(fTPCminNCrossedRows);
269    cuts.SetMinRatioCrossedRowsOverFindableClustersTPC(fTPCminCrossedRowsOverFindableCls);
270    cuts.SetMinLengthActiveVolumeTPC(fCutMinLengthActiveVolumeTPC);
271
272    // ITS related cuts for TPC+ITS tracks
273    if (fSPDminNClusters > 0)
274       cuts.SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
275    cuts.SetMaxChi2PerClusterITS(fITSmaxChi2);
276
277    // now that all is initialized, do the check
278    return cuts.IsSelected(track);
279 }
280
281 //_________________________________________________________________________________________________
282 Bool_t AliRsnCutTrackQuality::CheckAOD(AliAODTrack *track)
283 {
284 //
285 // Check an AOD track.
286 // This is done doing directly all checks, since there is not
287 // an equivalend checker for AOD tracks
288 //
289
290    // if a test bit is used, check it and skip the following
291    if (fAODTestFilterBit >= 0) {
292       UInt_t bit = 1 << fAODTestFilterBit;
293       AliDebugClass(2, Form("Required a test filter bit for AOD check: %u (result: %s)", bit, (track->TestFilterBit(bit) ? "accept" : "reject")));
294       if (!track->TestFilterBit(bit))
295          return kFALSE;
296       else {
297          if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) return kFALSE;
298          if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) return kFALSE;
299          if (fCheckOnlyFilterBit) return kTRUE;
300       }
301    }
302
303    // try to retrieve the reference AOD event
304    AliAODEvent *aodEvent = 0x0;
305    if (fEvent) aodEvent = fEvent->GetRefAOD();
306    if (!aodEvent) {
307       AliError("AOD reference event is not initialized!");
308       return kFALSE;
309    }
310
311    // step #0: check SPD and ITS clusters
312    Int_t nSPD = 0;
313    nSPD  = TESTBIT(track->GetITSClusterMap(), 0);
314    nSPD += TESTBIT(track->GetITSClusterMap(), 1);
315    if (nSPD < fSPDminNClusters) {
316       AliDebug(AliLog::kDebug + 2, "Not enough SPD clusters in this track. Rejected");
317       return kFALSE;
318    }
319
320
321    //step #1: check number of clusters 
322    if (track->GetTPCNcls() < fTPCminNClusters) {
323       AliDebug(AliLog::kDebug + 2, "Too few TPC clusters. Rejected");
324       return kFALSE;
325    }
326    if (track->GetITSNcls() < fITSminNClusters) {
327       AliDebug(AliLog::kDebug + 2, "Too few ITS clusters. Rejected");
328       return kFALSE;
329    }
330
331    //check chi square
332    if (track->Chi2perNDF() > fTPCmaxChi2) {
333       AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
334       return kFALSE;
335    }
336    if (track->Chi2perNDF() > fITSmaxChi2) {
337       AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
338       return kFALSE;
339    }
340
341    //step #2a: check number of crossed rows in TPC
342    Float_t nCrossedRowsTPC = track->GetTPCNCrossedRows();
343    if (nCrossedRowsTPC < fTPCminNCrossedRows) {
344      AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows. Rejected");
345      return kFALSE;
346    }
347    if (track->GetTPCNclsF()>0) {
348      Float_t ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC / track->GetTPCNclsF();
349      if (ratioCrossedRowsOverFindableClustersTPC < fTPCminCrossedRowsOverFindableCls){
350        AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows/findable clusters. Rejected");
351        return kFALSE;
352      }
353    } else {
354      AliDebug(AliLog::kDebug + 2, "Negative value for TPC crossed rows/findable clusters. Rejected");
355      return kFALSE;
356    }
357    //step #2b: check on track length in active volume of TPC implemented only for ESD tracks
358      
359    //step #3: reject kink daughters
360    AliAODVertex *vertex = track->GetProdVertex();
361    if (vertex && fRejectKinkDaughters) {
362       if (vertex->GetType() == AliAODVertex::kKink) {
363          AliDebug(AliLog::kDebug + 2, "Kink daughter. Rejected");
364          return kFALSE;
365       }
366    }
367
368    // step #4: DCA cut (transverse)
369    // --> reject all tracks not ITS refitted
370    Double_t b[2], cov[3];
371    vertex = aodEvent->GetPrimaryVertex();
372    if (!vertex) {
373       AliDebug(AliLog::kDebug + 2, "NULL vertex");
374       return kFALSE;
375    }
376    if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) {
377       AliDebug(AliLog::kDebug + 2, "Not ITS refitted");
378       return kFALSE;
379    }
380    if (!track->PropagateToDCA(vertex, aodEvent->GetMagneticField(), kVeryBig, b, cov)) {
381       AliDebug(AliLog::kDebug + 2, "Failed propagation to vertex");
382       return kFALSE;
383    }
384    // if the DCA cut is not fixed, compute current value
385    if (!fDCARfixed) {
386       TString str(fDCARptFormula);
387       str.ReplaceAll("pt", "x");
388       TFormula dcaXY(Form("%s_dcaXY", GetName()), str.Data());
389       fDCARmax = dcaXY.Eval(track->Pt());
390    }
391    // check the cut
392    if (TMath::Abs(b[0]) > fDCARmax) {
393       AliDebug(AliLog::kDebug + 2, "Too large transverse DCA");
394       return kFALSE;
395    }
396
397    // step #5: DCA cut (longitudinal)
398    // the DCA has already been computed above
399    // if the DCA cut is not fixed, compute current value
400    if (!fDCAZfixed) {
401       TString str(fDCAZptFormula);
402       str.ReplaceAll("pt", "x");
403       TFormula dcaZ(Form("%s_dcaXY", GetName()), str.Data());
404       fDCAZmax = dcaZ.Eval(track->Pt());
405    }
406    // check the cut
407    if (TMath::Abs(b[1]) > fDCAZmax) {
408       AliDebug(AliLog::kDebug + 2, "Too large longitudinal DCA");
409       return kFALSE;
410    }
411
412    // step #6: check eta/pt range
413    if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) {
414       AliDebug(AliLog::kDebug + 2, "Outside ETA acceptance");
415       return kFALSE;
416    }
417    if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) {
418       AliDebug(AliLog::kDebug + 2, "Outside PT acceptance");
419       return kFALSE;
420    }
421
422    // if we are here, all cuts were passed and no exit point was got
423    AliDebug(AliLog::kDebug + 2, "============================= ACCEPTED TRACK =====================================================");
424    return kTRUE;
425 }
426
427 //_________________________________________________________________________________________________
428 void AliRsnCutTrackQuality::Print(const Option_t *) const
429 {
430 //
431 // Print information on this cut
432 //
433
434    AliInfo(Form("Cut name                : %s", GetName()));
435    AliInfo(Form("Required flags (off, on): %lx %lx", fFlagsOn, fFlagsOff));
436    AliInfo(Form("Ranges in eta, pt       : %.2f - %.2f, %.2f - %.2f", fEta[0], fEta[1], fPt[0], fPt[1]));
437    AliInfo(Form("Kink daughters are      : %s", (fRejectKinkDaughters ? "rejected" : "accepted")));
438    AliInfo(Form("TPC requirements (clusters)       : min. cluster = %i, max chi2 = %f", fTPCminNClusters, fTPCmaxChi2));
439    AliInfo(Form("TPC requirements (crossed rows)   : min. crossed rows = %f, min. crossed rows/findable clusters = %f", fTPCminNCrossedRows, fTPCminCrossedRowsOverFindableCls));
440    AliInfo(Form("TPC requirements (track length)   : min. track length in active volume TPC = %f", fCutMinLengthActiveVolumeTPC));
441
442    AliInfo(Form("ITS requirements        : min. cluster = %d (all), %d (SPD), max chi2 = %f", fITSminNClusters, fSPDminNClusters, fITSmaxChi2));
443
444    if (fDCARfixed) {
445       AliInfo(Form("DCA r cut               : fixed to %f cm", fDCARmax));
446    } else {
447       AliInfo(Form("DCA r cut formula       : %s", fDCARptFormula.Data()));
448    }
449
450    if (fDCAZfixed) {
451       AliInfo(Form("DCA z cut               : fixed to %f cm", fDCAZmax));
452    } else {
453       AliInfo(Form("DCA z cut formula       : %s", fDCAZptFormula.Data()));
454    }
455
456    AliInfo(Form("fAODTestFilterBit       : filter bit %i",fAODTestFilterBit));
457    AliInfo(Form("fCheckOnlyFilterBit     : %i",((int) fCheckOnlyFilterBit)));
458 }
459 //__________________________________________________________________________________________________
460 void AliRsnCutTrackQuality::SetDefaults2010()
461 {
462 //
463 // Default settings for cuts used in 2010
464 //
465    AddStatusFlag(AliESDtrack::kTPCin   , kTRUE);
466    AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);
467    AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);
468    SetPtRange(0.15, 1E+20);
469    SetEtaRange(-0.8, 0.8);
470    SetDCARPtFormula("0.0182+0.0350/pt^1.01");
471    SetDCAZmax(2.0);
472    SetSPDminNClusters(1);
473    SetITSminNClusters(0);
474    // SetITSmaxChi2(36);
475    // SetMaxChi2TPCConstrainedGlobal(36);
476    SetTPCminNClusters(70);
477    SetTPCmaxChi2(4.0);
478    SetRejectKinkDaughters();
479    SetAODTestFilterBit(5);
480 }
481
482 //__________________________________________________________________________________________________
483 void AliRsnCutTrackQuality::SetDefaults2011()
484 {
485 //
486 // Default settings for cuts used in 2011 (for high-pT)
487 //
488    fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
489    fESDtrackCuts->SetMinNCrossedRowsTPC(120); //default is min 70 crossed rows -> use 120 to go to higher pt
490    fESDtrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
491    fESDtrackCuts->SetMaxChi2PerClusterITS(36);
492    fESDtrackCuts->SetMaxFractionSharedTPCClusters(0.4);//default is not set --> use to go to higher pt
493    fESDtrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
494  
495    AddStatusFlag(AliESDtrack::kTPCin   , kTRUE);
496    AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);
497    AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);
498    SetPtRange(0.15, 1E+20);
499    SetEtaRange(-0.8, 0.8);
500    SetAODTestFilterBit(10);
501 }
502
503 //__________________________________________________________________________________________________
504 const char *AliRsnCutTrackQuality::Binary(UInt_t number)
505 {
506 //
507 // Convert an integer in binary
508 //
509
510    static char b[50];
511    b[0] = '\0';
512
513    UInt_t z;
514    for (z = 512; z > 0; z >>= 1)
515       strncat(b, ((number & z) == z) ? "1" : "0", 1);
516
517    return b;
518 }