2 // Class AliRsnCutTrackQuality
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()]
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.
15 // authors: Martin Vala (martin.vala@cern.ch)
16 // Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
19 #include <Riostream.h>
24 #include "AliESDtrackCuts.h"
26 #include "AliRsnEvent.h"
27 #include "AliRsnDaughter.h"
28 #include "AliRsnCutTrackQuality.h"
30 ClassImp(AliRsnCutTrackQuality)
32 //_________________________________________________________________________________________________
33 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const char *name) :
34 AliRsnCut(name, AliRsnTarget::kDaughter, 0.0, 0.0),
37 fRejectKinkDaughters(kTRUE),
41 fDCARptFormulaMin(""),
52 fCutMaxChi2TPCConstrainedVsGlobal(1E20),
53 fIsUseCrossedRowsCut(kFALSE),
54 fTPCminNCrossedRows(0),
55 fTPCminCrossedRowsOverFindableCls(0),
56 fIsUseLengthActiveVolumeTPCCut(kFALSE),
57 fCutMinLengthActiveVolumeTPC(0),
58 fAODTestFilterBit(-1),
59 fCheckOnlyFilterBit(kTRUE),
63 // Default constructor.
64 // Initializes all cuts in such a way that all of them are disabled.
66 SetPtRange(0.0, 1E20);
67 SetEtaRange(-1E20, 1E20);
70 //_________________________________________________________________________________________________
71 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const AliRsnCutTrackQuality ©) :
73 fFlagsOn(copy.fFlagsOn),
74 fFlagsOff(copy.fFlagsOff),
75 fRejectKinkDaughters(copy.fRejectKinkDaughters),
76 fDCARmaxfixed(copy.fDCARmaxfixed),
77 fDCARminfixed(copy.fDCARminfixed),
78 fDCARptFormula(copy.fDCARptFormula),
79 fDCARptFormulaMin(copy.fDCARptFormulaMin),
80 fDCARmax(copy.fDCARmax),
81 fDCARmin(copy.fDCARmin),
82 fDCAZfixed(copy.fDCAZfixed),
83 fDCAZptFormula(copy.fDCAZptFormula),
84 fDCAZmax(copy.fDCAZmax),
85 fSPDminNClusters(copy.fSPDminNClusters),
86 fITSminNClusters(copy.fITSminNClusters),
87 fITSmaxChi2(copy.fITSmaxChi2),
88 fTPCminNClusters(copy.fTPCminNClusters),
89 fTPCmaxChi2(copy.fTPCmaxChi2),
90 fCutMaxChi2TPCConstrainedVsGlobal(copy.fCutMaxChi2TPCConstrainedVsGlobal),
91 fIsUseCrossedRowsCut(copy.fIsUseCrossedRowsCut),
92 fTPCminNCrossedRows(copy.fTPCminNCrossedRows),
93 fTPCminCrossedRowsOverFindableCls(copy.fTPCminCrossedRowsOverFindableCls),
94 fIsUseLengthActiveVolumeTPCCut(copy.fIsUseLengthActiveVolumeTPCCut),
95 fCutMinLengthActiveVolumeTPC(copy.fCutMinLengthActiveVolumeTPC),
96 fAODTestFilterBit(copy.fAODTestFilterBit),
97 fCheckOnlyFilterBit(copy.fCheckOnlyFilterBit),
98 fESDtrackCuts(copy.fESDtrackCuts)
102 // Just copy all data member values.
105 SetPtRange(copy.fPt[0], copy.fPt[1]);
106 SetEtaRange(copy.fEta[0], copy.fEta[1]);
109 //_________________________________________________________________________________________________
110 AliRsnCutTrackQuality &AliRsnCutTrackQuality::operator=(const AliRsnCutTrackQuality ©)
113 // Assignment operator.
114 // Just copy all data member values.
120 fFlagsOn = copy.fFlagsOn;
121 fFlagsOff = copy.fFlagsOff;
122 fRejectKinkDaughters = copy.fRejectKinkDaughters;
123 fDCARmaxfixed = copy.fDCARmaxfixed;
124 fDCARminfixed = copy.fDCARminfixed;
125 fDCARptFormula = copy.fDCARptFormula;
126 fDCARptFormulaMin = copy.fDCARptFormulaMin;
127 fDCARmax = copy.fDCARmax;
128 fDCARmin = copy.fDCARmin;
129 fDCAZfixed = copy.fDCAZfixed;
130 fDCAZptFormula = copy.fDCAZptFormula;
131 fDCAZmax = copy.fDCAZmax;
132 fSPDminNClusters = copy.fSPDminNClusters;
133 fITSminNClusters = copy.fITSminNClusters;
134 fITSmaxChi2 = copy.fITSmaxChi2;
135 fTPCminNClusters = copy.fTPCminNClusters;
136 fTPCmaxChi2 = copy.fTPCmaxChi2;
137 fCutMaxChi2TPCConstrainedVsGlobal = copy.fCutMaxChi2TPCConstrainedVsGlobal;
138 fIsUseCrossedRowsCut=copy.fIsUseCrossedRowsCut;
139 fTPCminNCrossedRows = copy.fTPCminNCrossedRows;
140 fTPCminCrossedRowsOverFindableCls = copy.fTPCminCrossedRowsOverFindableCls;
141 fIsUseLengthActiveVolumeTPCCut=copy.fIsUseLengthActiveVolumeTPCCut;
142 fCutMinLengthActiveVolumeTPC = copy.fCutMinLengthActiveVolumeTPC;
144 fAODTestFilterBit = copy.fAODTestFilterBit;
145 fCheckOnlyFilterBit = copy.fCheckOnlyFilterBit;
146 fESDtrackCuts = copy.fESDtrackCuts;
147 SetPtRange(copy.fPt[0], copy.fPt[1]);
148 SetEtaRange(copy.fEta[0], copy.fEta[1]);
153 //_________________________________________________________________________________________________
154 void AliRsnCutTrackQuality::DisableAll()
162 fRejectKinkDaughters = kFALSE;
163 fDCARmaxfixed = kTRUE;
164 fDCARminfixed = kTRUE;
166 fDCARptFormulaMin = "";
172 fSPDminNClusters = 0;
173 fITSminNClusters = 0;
175 fTPCminNClusters = 0;
177 fAODTestFilterBit = -1;
178 fCutMaxChi2TPCConstrainedVsGlobal = 1E20;
179 fIsUseCrossedRowsCut = 0;
180 fTPCminNCrossedRows = 0;
181 fTPCminCrossedRowsOverFindableCls = 0;
182 fIsUseLengthActiveVolumeTPCCut = 0;
183 fCutMinLengthActiveVolumeTPC = 0.0;
186 const char *cutsName = fESDtrackCuts->GetName();
187 const char *cutsTitle = fESDtrackCuts->GetTitle();
188 delete fESDtrackCuts;
189 fESDtrackCuts = new AliESDtrackCuts(cutsName,cutsTitle);
191 SetPtRange(0.0, 1E20);
192 SetEtaRange(-1E20, 1E20);
195 //_________________________________________________________________________________________________
196 Bool_t AliRsnCutTrackQuality::IsSelected(TObject *object)
200 // Checks the type of object being evaluated
201 // and then calls the appropriate sub-function (for ESD or AOD)
205 if (!TargetOK(object)) return kFALSE;
207 // status is checked in the same way for all tracks, using AliVTrack
208 // as a convention, if a the collection of 'on' flags is '0x0', it
209 // is assumed that no flags are required, and this check is skipped;
210 // for the collection of 'off' flags this is not needed
211 AliVTrack *vtrack = fDaughter->Ref2Vtrack();
213 AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
216 ULong_t status = (ULong_t)vtrack->GetStatus();
217 ULong_t checkOn = status & fFlagsOn;
218 ULong_t checkOff = status & fFlagsOff;
219 if (fFlagsOn != 0x0 && checkOn != fFlagsOn) {
220 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: required %s", Binary(fFlagsOn)));
221 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
225 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
226 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
229 AliDebug(AliLog::kDebug + 3, Form("Flag check OK: required %s", Binary(fFlagsOn)));
230 AliDebug(AliLog::kDebug + 3, Form(" forbidden %s", Binary(fFlagsOff)));
231 AliDebug(AliLog::kDebug + 3, Form(" track has %s", Binary(status )));
233 // retrieve real object type
234 AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
235 AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
237 AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
239 return fESDtrackCuts->IsSelected(esdTrack);
241 return CheckESD(esdTrack);
242 } else if (aodTrack) {
243 AliDebug(AliLog::kDebug + 2, "Checking an AOD track");
244 return CheckAOD(aodTrack);
246 AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
251 //_________________________________________________________________________________________________
252 Bool_t AliRsnCutTrackQuality::CheckESD(AliESDtrack *track)
255 // Check an ESD track.
256 // This is done using the default track checker for ESD.
257 // It is declared static, not to recreate it every time.
259 //static AliESDtrackCuts cuts;
260 AliESDtrackCuts cuts;
262 // general acceptance/pt cuts
263 cuts.SetPtRange(fPt[0], fPt[1]);
264 cuts.SetEtaRange(fEta[0], fEta[1]);
266 // transverse DCA cuts
268 cuts.SetMaxDCAToVertexXY(fDCARmax);
270 cuts.SetMaxDCAToVertexXYPtDep(fDCARptFormula.Data());
273 cuts.SetMinDCAToVertexXY(fDCARmin);
275 cuts.SetMinDCAToVertexXYPtDep(fDCARptFormulaMin.Data());
277 // longitudinal DCA cuts
279 cuts.SetMaxDCAToVertexZ(fDCAZmax);
281 cuts.SetMaxDCAToVertexZPtDep(fDCAZptFormula.Data());
283 // these options are always disabled in current version
284 cuts.SetDCAToVertex2D(kFALSE);
285 cuts.SetRequireSigmaToVertex(kFALSE);
287 // TPC related cuts for TPC+ITS tracks
288 if (fIsUseCrossedRowsCut) {
289 cuts.SetMinNCrossedRowsTPC(fTPCminNCrossedRows);
290 cuts.SetMinRatioCrossedRowsOverFindableClustersTPC(fTPCminCrossedRowsOverFindableCls);
292 cuts.SetMinNClustersTPC(fTPCminNClusters);
294 cuts.SetMaxChi2PerClusterTPC(fTPCmaxChi2);
295 cuts.SetAcceptKinkDaughters(!fRejectKinkDaughters);
296 cuts.SetMaxChi2TPCConstrainedGlobal(fCutMaxChi2TPCConstrainedVsGlobal);
298 if (fIsUseLengthActiveVolumeTPCCut)
299 cuts.SetMinLengthActiveVolumeTPC(fCutMinLengthActiveVolumeTPC);
301 // ITS related cuts for TPC+ITS tracks
302 if (fSPDminNClusters > 0)
303 cuts.SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
304 cuts.SetMaxChi2PerClusterITS(fITSmaxChi2);
306 // now that all is initialized, do the check
307 return cuts.IsSelected(track);
310 //_________________________________________________________________________________________________
311 Bool_t AliRsnCutTrackQuality::CheckAOD(AliAODTrack *track)
314 // Check an AOD track.
315 // This is done doing directly all checks, since there is not
316 // an equivalend checker for AOD tracks
319 // if a test bit is used, check it and skip the following
320 if (fAODTestFilterBit >= 0) {
321 UInt_t bit = 1 << fAODTestFilterBit;
322 AliDebugClass(2, Form("Required a test filter bit for AOD check: %u (result: %s)", bit, (track->TestFilterBit(bit) ? "accept" : "reject")));
323 if (!track->TestFilterBit(bit))
326 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) return kFALSE;
327 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) return kFALSE;
328 if (fCheckOnlyFilterBit) return kTRUE;
332 // try to retrieve the reference AOD event
333 AliAODEvent *aodEvent = 0x0;
334 if (fEvent) aodEvent = fEvent->GetRefAOD();
336 AliError("AOD reference event is not initialized!");
340 // step #0: check SPD and ITS clusters
342 nSPD = TESTBIT(track->GetITSClusterMap(), 0);
343 nSPD += TESTBIT(track->GetITSClusterMap(), 1);
344 if (nSPD < fSPDminNClusters) {
345 AliDebug(AliLog::kDebug + 2, "Not enough SPD clusters in this track. Rejected");
350 //step #1: check number of clusters
351 if ((!fIsUseCrossedRowsCut) && (track->GetTPCNcls() < fTPCminNClusters)) {
352 AliDebug(AliLog::kDebug + 2, "Too few TPC clusters. Rejected");
356 if (track->GetITSNcls() < fITSminNClusters) {
357 AliDebug(AliLog::kDebug + 2, "Too few ITS clusters. Rejected");
362 if (track->Chi2perNDF() > fTPCmaxChi2) {
363 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
366 if (track->Chi2perNDF() > fITSmaxChi2) {
367 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
371 //step #2a: check number of crossed rows in TPC
372 if (fIsUseCrossedRowsCut) {
373 Float_t nCrossedRowsTPC = track->GetTPCNCrossedRows();
374 if (nCrossedRowsTPC < fTPCminNCrossedRows) {
375 AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows. Rejected");
378 if (track->GetTPCNclsF()>0) {
379 Float_t ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC / track->GetTPCNclsF();
380 if (ratioCrossedRowsOverFindableClustersTPC < fTPCminCrossedRowsOverFindableCls){
381 AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows/findable clusters. Rejected");
385 AliDebug(AliLog::kDebug + 2, "Negative value for TPC crossed rows/findable clusters. Rejected");
389 //step #2b: check on track length in active volume of TPC implemented only for ESD tracks
390 //if (fIsUseLengthActiveVolumeTPCCut) { // not yet implemented in AODs}
392 //step #3: reject kink daughters
393 AliAODVertex *vertex = track->GetProdVertex();
394 if (vertex && fRejectKinkDaughters) {
395 if (vertex->GetType() == AliAODVertex::kKink) {
396 AliDebug(AliLog::kDebug + 2, "Kink daughter. Rejected");
401 // step #4: DCA cut (transverse)
402 // --> reject all tracks not ITS refitted
403 Double_t b[2], cov[3];
404 vertex = aodEvent->GetPrimaryVertex();
406 AliDebug(AliLog::kDebug + 2, "NULL vertex");
409 if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) {
410 AliDebug(AliLog::kDebug + 2, "Not ITS refitted");
413 if (!track->PropagateToDCA(vertex, aodEvent->GetMagneticField(), kVeryBig, b, cov)) {
414 AliDebug(AliLog::kDebug + 2, "Failed propagation to vertex");
417 // if the DCA cut is not fixed, compute current value
418 if (!fDCARmaxfixed) {
419 TString str(fDCARptFormula);
420 str.ReplaceAll("pt", "x");
421 TFormula dcaXY(Form("%s_dcaXY", GetName()), str.Data());
422 fDCARmax = dcaXY.Eval(track->Pt());
424 if (!fDCARminfixed) {
425 TString str2(fDCARptFormulaMin);
426 str2.ReplaceAll("pt", "x");
427 TFormula dcaXY_2(Form("%s_dcaXY_2", GetName()), str2.Data());
428 fDCARmin = dcaXY_2.Eval(track->Pt());
431 if (TMath::Abs(b[0]) > fDCARmax) {
432 AliDebug(AliLog::kDebug + 2, "Too large transverse DCA");
436 if (TMath::Abs(b[0]) < fDCARmin) {
437 AliDebug(AliLog::kDebug + 2, "Too short transverse DCA");
441 // step #5: DCA cut (longitudinal)
442 // the DCA has already been computed above
443 // if the DCA cut is not fixed, compute current value
445 TString str(fDCAZptFormula);
446 str.ReplaceAll("pt", "x");
447 TFormula dcaZ(Form("%s_dcaXY", GetName()), str.Data());
448 fDCAZmax = dcaZ.Eval(track->Pt());
451 if (TMath::Abs(b[1]) > fDCAZmax) {
452 AliDebug(AliLog::kDebug + 2, "Too large longitudinal DCA");
456 // step #6: check eta/pt range
457 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) {
458 AliDebug(AliLog::kDebug + 2, "Outside ETA acceptance");
461 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) {
462 AliDebug(AliLog::kDebug + 2, "Outside PT acceptance");
466 // if we are here, all cuts were passed and no exit point was got
467 AliDebug(AliLog::kDebug + 2, "============================= ACCEPTED TRACK =====================================================");
471 //_________________________________________________________________________________________________
472 void AliRsnCutTrackQuality::Print(const Option_t *) const
475 // Print information on this cut
478 AliInfo(Form("Cut name : %s", GetName()));
479 AliInfo(Form("Required flags (off, on): %lx %lx", fFlagsOn, fFlagsOff));
480 AliInfo(Form("Ranges in eta, pt : %.2f - %.2f, %.2f - %.2f", fEta[0], fEta[1], fPt[0], fPt[1]));
481 AliInfo(Form("Kink daughters are : %s", (fRejectKinkDaughters ? "rejected" : "accepted")));
482 AliInfo(Form("TPC requirements (clusters) : min. cluster = %i, max chi2 = %f", fTPCminNClusters, fTPCmaxChi2));
483 AliInfo(Form("TPC requirements (crossed rows) : min. crossed rows = %f, min. crossed rows/findable clusters = %f", fTPCminNCrossedRows, fTPCminCrossedRowsOverFindableCls));
484 AliInfo(Form("TPC requirements (track length) : min. track length in active volume TPC = %f", fCutMinLengthActiveVolumeTPC));
486 AliInfo(Form("ITS requirements : min. cluster = %d (all), %d (SPD), max chi2 = %f", fITSminNClusters, fSPDminNClusters, fITSmaxChi2));
489 AliInfo(Form("Max DCA r cut : fixed to %f cm", fDCARmax));
491 AliInfo(Form("Max DCA r cut formula : %s", fDCARptFormula.Data()));
495 AliInfo(Form("Min DCA r cut : fixed to %f cm", fDCARmin));
497 AliInfo(Form("Min DCA r cut formula : %s", fDCARptFormulaMin.Data()));
501 AliInfo(Form("DCA z cut : fixed to %f cm", fDCAZmax));
503 AliInfo(Form("DCA z cut formula : %s", fDCAZptFormula.Data()));
506 AliInfo(Form("fAODTestFilterBit : filter bit %i",fAODTestFilterBit));
507 AliInfo(Form("fCheckOnlyFilterBit : %i",((int) fCheckOnlyFilterBit)));
509 //__________________________________________________________________________________________________
510 void AliRsnCutTrackQuality::SetDefaults2010()
513 // Default settings for cuts used in 2010
515 AddStatusFlag(AliESDtrack::kTPCin , kTRUE);
516 AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);
517 AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);
518 SetPtRange(0.15, 1E+20);
519 SetEtaRange(-0.8, 0.8);
520 SetDCARPtFormula("0.0182+0.0350/pt^1.01");
522 SetSPDminNClusters(1);
523 SetITSminNClusters(0);
524 // SetITSmaxChi2(36);
525 // SetMaxChi2TPCConstrainedGlobal(36);
526 SetTPCminNClusters(70);
528 SetRejectKinkDaughters();
529 SetAODTestFilterBit(5);
532 //__________________________________________________________________________________________________
533 void AliRsnCutTrackQuality::SetDefaultsHighPt2011(Bool_t useTPCCrossedRows)
536 // Default settings for cuts used in 2011 (for high-pT)
538 fIsUseCrossedRowsCut=useTPCCrossedRows;
539 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE, useTPCCrossedRows);
540 fESDtrackCuts->SetMinNCrossedRowsTPC(120); //default is min 70 crossed rows -> use 120 to go to higher pt
541 fESDtrackCuts->SetMaxFractionSharedTPCClusters(0.4);//default is not set --> use to go to higher pt
542 //fESDtrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);//already in 2011 std
543 //fESDtrackCuts->SetMaxChi2PerClusterITS(36);//already in 2011 std
544 //fESDtrackCuts->SetMaxChi2TPCConstrainedGlobal(36);//already in 2011 std
545 // AddStatusFlag(AliESDtrack::kTPCin , kTRUE); //already in 2011 std
546 // AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);//already in 2011 std
547 // AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);//already in 2011 std
548 SetPtRange(0.15, 1E+20);
549 SetEtaRange(-0.8, 0.8);
550 SetAODTestFilterBit(10);
554 //__________________________________________________________________________________________________
555 void AliRsnCutTrackQuality::SetDefaults2011(Bool_t useTPCCrossedRows)
558 // Default std cuts 2011 with crossed rows (=70)
560 fIsUseCrossedRowsCut=useTPCCrossedRows;
561 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,useTPCCrossedRows);
562 SetPtRange(0.15, 1E+20);
563 SetEtaRange(-0.8, 0.8);
564 SetAODTestFilterBit(5);
567 //__________________________________________________________________________________________________
568 const char *AliRsnCutTrackQuality::Binary(UInt_t number)
571 // Convert an integer in binary
578 for (z = 512; z > 0; z >>= 1)
579 strncat(b, ((number & z) == z) ? "1" : "0", 1);