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),
54 fIsUseCrossedRowsCut(kFALSE),
55 fTPCminNCrossedRows(0),
56 fTPCminCrossedRowsOverFindableCls(0),
57 fIsUseLengthActiveVolumeTPCCut(kFALSE),
58 fCutMinLengthActiveVolumeTPC(0),
59 fAODTestFilterBit(-1),
60 fCheckOnlyFilterBit(kTRUE),
64 // Default constructor.
65 // Initializes all cuts in such a way that all of them are disabled.
67 SetPtRange(0.0, 1E20);
68 SetEtaRange(-1E20, 1E20);
71 //_________________________________________________________________________________________________
72 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const AliRsnCutTrackQuality ©) :
74 fFlagsOn(copy.fFlagsOn),
75 fFlagsOff(copy.fFlagsOff),
76 fRejectKinkDaughters(copy.fRejectKinkDaughters),
77 fDCARmaxfixed(copy.fDCARmaxfixed),
78 fDCARminfixed(copy.fDCARminfixed),
79 fDCARptFormula(copy.fDCARptFormula),
80 fDCARptFormulaMin(copy.fDCARptFormulaMin),
81 fDCARmax(copy.fDCARmax),
82 fDCARmin(copy.fDCARmin),
83 fDCAZfixed(copy.fDCAZfixed),
84 fDCAZptFormula(copy.fDCAZptFormula),
85 fDCAZmax(copy.fDCAZmax),
86 fSPDminNClusters(copy.fSPDminNClusters),
87 fITSminNClusters(copy.fITSminNClusters),
88 fITSmaxChi2(copy.fITSmaxChi2),
89 fTPCminNClusters(copy.fTPCminNClusters),
90 fTPCmaxChi2(copy.fTPCmaxChi2),
91 fCutMaxChi2TPCConstrainedVsGlobal(copy.fCutMaxChi2TPCConstrainedVsGlobal),
92 fTrackMaxChi2(copy.fTrackMaxChi2),
93 fIsUseCrossedRowsCut(copy.fIsUseCrossedRowsCut),
94 fTPCminNCrossedRows(copy.fTPCminNCrossedRows),
95 fTPCminCrossedRowsOverFindableCls(copy.fTPCminCrossedRowsOverFindableCls),
96 fIsUseLengthActiveVolumeTPCCut(copy.fIsUseLengthActiveVolumeTPCCut),
97 fCutMinLengthActiveVolumeTPC(copy.fCutMinLengthActiveVolumeTPC),
98 fAODTestFilterBit(copy.fAODTestFilterBit),
99 fCheckOnlyFilterBit(copy.fCheckOnlyFilterBit),
100 fESDtrackCuts(copy.fESDtrackCuts)
104 // Just copy all data member values.
107 SetPtRange(copy.fPt[0], copy.fPt[1]);
108 SetEtaRange(copy.fEta[0], copy.fEta[1]);
111 //_________________________________________________________________________________________________
112 AliRsnCutTrackQuality &AliRsnCutTrackQuality::operator=(const AliRsnCutTrackQuality ©)
115 // Assignment operator.
116 // Just copy all data member values.
122 fFlagsOn = copy.fFlagsOn;
123 fFlagsOff = copy.fFlagsOff;
124 fRejectKinkDaughters = copy.fRejectKinkDaughters;
125 fDCARmaxfixed = copy.fDCARmaxfixed;
126 fDCARminfixed = copy.fDCARminfixed;
127 fDCARptFormula = copy.fDCARptFormula;
128 fDCARptFormulaMin = copy.fDCARptFormulaMin;
129 fDCARmax = copy.fDCARmax;
130 fDCARmin = copy.fDCARmin;
131 fDCAZfixed = copy.fDCAZfixed;
132 fDCAZptFormula = copy.fDCAZptFormula;
133 fDCAZmax = copy.fDCAZmax;
134 fSPDminNClusters = copy.fSPDminNClusters;
135 fITSminNClusters = copy.fITSminNClusters;
136 fITSmaxChi2 = copy.fITSmaxChi2;
137 fTPCminNClusters = copy.fTPCminNClusters;
138 fTPCmaxChi2 = copy.fTPCmaxChi2;
139 fCutMaxChi2TPCConstrainedVsGlobal = copy.fCutMaxChi2TPCConstrainedVsGlobal;
140 fTrackMaxChi2 = copy.fTrackMaxChi2;
141 fIsUseCrossedRowsCut=copy.fIsUseCrossedRowsCut;
142 fTPCminNCrossedRows = copy.fTPCminNCrossedRows;
143 fTPCminCrossedRowsOverFindableCls = copy.fTPCminCrossedRowsOverFindableCls;
144 fIsUseLengthActiveVolumeTPCCut=copy.fIsUseLengthActiveVolumeTPCCut;
145 fCutMinLengthActiveVolumeTPC = copy.fCutMinLengthActiveVolumeTPC;
147 fAODTestFilterBit = copy.fAODTestFilterBit;
148 fCheckOnlyFilterBit = copy.fCheckOnlyFilterBit;
149 fESDtrackCuts = copy.fESDtrackCuts;
150 SetPtRange(copy.fPt[0], copy.fPt[1]);
151 SetEtaRange(copy.fEta[0], copy.fEta[1]);
156 //_________________________________________________________________________________________________
157 void AliRsnCutTrackQuality::DisableAll()
165 fRejectKinkDaughters = kFALSE;
166 fDCARmaxfixed = kTRUE;
167 fDCARminfixed = kTRUE;
169 fDCARptFormulaMin = "";
175 fSPDminNClusters = 0;
176 fITSminNClusters = 0;
178 fTPCminNClusters = 0;
180 fAODTestFilterBit = -1;
181 fCutMaxChi2TPCConstrainedVsGlobal = 1E20;
182 fTrackMaxChi2 = 1E20;
183 fIsUseCrossedRowsCut = 0;
184 fTPCminNCrossedRows = 0;
185 fTPCminCrossedRowsOverFindableCls = 0;
186 fIsUseLengthActiveVolumeTPCCut = 0;
187 fCutMinLengthActiveVolumeTPC = 0.0;
190 const char *cutsName = fESDtrackCuts->GetName();
191 const char *cutsTitle = fESDtrackCuts->GetTitle();
192 delete fESDtrackCuts;
193 fESDtrackCuts = new AliESDtrackCuts(cutsName,cutsTitle);
195 SetPtRange(0.0, 1E20);
196 SetEtaRange(-1E20, 1E20);
199 //_________________________________________________________________________________________________
200 void AliRsnCutTrackQuality::SetPtRange(Double_t a, Double_t b)
203 fPt[0] = TMath::Min(a, b);
204 fPt[1] = TMath::Max(a, b);
205 if (fESDtrackCuts) fESDtrackCuts->SetPtRange(fPt[0], fPt[1]);
209 //_________________________________________________________________________________________________
210 void AliRsnCutTrackQuality::SetEtaRange(Double_t a, Double_t b)
213 fEta[0] = TMath::Min(a, b);
214 fEta[1] = TMath::Max(a, b);
215 if (fESDtrackCuts) fESDtrackCuts->SetEtaRange(fEta[0], fEta[1]);
219 //_________________________________________________________________________________________________
220 Bool_t AliRsnCutTrackQuality::IsSelected(TObject *object)
224 // Checks the type of object being evaluated
225 // and then calls the appropriate sub-function (for ESD or AOD)
229 if (!TargetOK(object)) return kFALSE;
231 // status is checked in the same way for all tracks, using AliVTrack
232 // as a convention, if a the collection of 'on' flags is '0x0', it
233 // is assumed that no flags are required, and this check is skipped;
234 // for the collection of 'off' flags this is not needed
235 AliVTrack *vtrack = fDaughter->Ref2Vtrack();
237 AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
240 ULong_t status = (ULong_t)vtrack->GetStatus();
241 ULong_t checkOn = status & fFlagsOn;
242 ULong_t checkOff = status & fFlagsOff;
243 if (fFlagsOn != 0x0 && checkOn != fFlagsOn) {
244 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: required %s", Binary(fFlagsOn)));
245 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
249 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
250 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
253 AliDebug(AliLog::kDebug + 3, Form("Flag check OK: required %s", Binary(fFlagsOn)));
254 AliDebug(AliLog::kDebug + 3, Form(" forbidden %s", Binary(fFlagsOff)));
255 AliDebug(AliLog::kDebug + 3, Form(" track has %s", Binary(status )));
257 // retrieve real object type
258 AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
259 AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
261 AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
263 return fESDtrackCuts->IsSelected(esdTrack);
265 return CheckESD(esdTrack);
266 } else if (aodTrack) {
267 AliDebug(AliLog::kDebug + 2, "Checking an AOD track");
268 return CheckAOD(aodTrack);
270 AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
275 //_________________________________________________________________________________________________
276 Bool_t AliRsnCutTrackQuality::CheckESD(AliESDtrack *track)
279 // Check an ESD track.
280 // This is done using the default track checker for ESD.
281 // It is declared static, not to recreate it every time.
283 //static AliESDtrackCuts cuts;
284 AliESDtrackCuts cuts;
286 // general acceptance/pt cuts
287 cuts.SetPtRange(fPt[0], fPt[1]);
288 cuts.SetEtaRange(fEta[0], fEta[1]);
290 // transverse DCA cuts
292 cuts.SetMaxDCAToVertexXY(fDCARmax);
294 cuts.SetMaxDCAToVertexXYPtDep(fDCARptFormula.Data());
297 cuts.SetMinDCAToVertexXY(fDCARmin);
299 cuts.SetMinDCAToVertexXYPtDep(fDCARptFormulaMin.Data());
301 // longitudinal DCA cuts
303 cuts.SetMaxDCAToVertexZ(fDCAZmax);
305 cuts.SetMaxDCAToVertexZPtDep(fDCAZptFormula.Data());
307 // these options are always disabled in current version
308 cuts.SetDCAToVertex2D(kFALSE);
309 cuts.SetRequireSigmaToVertex(kFALSE);
311 // TPC related cuts for TPC+ITS tracks
312 if (fIsUseCrossedRowsCut) {
313 cuts.SetMinNCrossedRowsTPC(fTPCminNCrossedRows);
314 cuts.SetMinRatioCrossedRowsOverFindableClustersTPC(fTPCminCrossedRowsOverFindableCls);
316 cuts.SetMinNClustersTPC(fTPCminNClusters);
318 cuts.SetMaxChi2PerClusterTPC(fTPCmaxChi2);
319 cuts.SetAcceptKinkDaughters(!fRejectKinkDaughters);
320 cuts.SetMaxChi2TPCConstrainedGlobal(fCutMaxChi2TPCConstrainedVsGlobal);
322 if (fIsUseLengthActiveVolumeTPCCut)
323 cuts.SetMinLengthActiveVolumeTPC(fCutMinLengthActiveVolumeTPC);
325 // ITS related cuts for TPC+ITS tracks
326 if (fSPDminNClusters > 0)
327 cuts.SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
328 cuts.SetMaxChi2PerClusterITS(fITSmaxChi2);
330 // now that all is initialized, do the check
332 AliError("Invalid track object. Rejected.");
335 return cuts.IsSelected(track);
338 //_________________________________________________________________________________________________
339 Bool_t AliRsnCutTrackQuality::CheckAOD(AliAODTrack *track)
342 // Check an AOD track.
343 // This is done doing directly all checks, since there is not
344 // an equivalend checker for AOD tracks
347 // if a test bit is used, check it and skip the following
348 if (fAODTestFilterBit >= 0) {
349 UInt_t bit = 1 << fAODTestFilterBit;
350 AliDebugClass(2, Form("Required a test filter bit for AOD check: %u (result: %s)", bit, (track->TestFilterBit(bit) ? "accept" : "reject")));
351 if (!track->TestFilterBit(bit))
354 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) return kFALSE;
355 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) return kFALSE;
356 if (fCheckOnlyFilterBit) return kTRUE;
360 // try to retrieve the reference AOD event
361 AliAODEvent *aodEvent = 0x0;
362 if (fEvent) aodEvent = fEvent->GetRefAOD();
364 AliError("AOD reference event is not initialized!");
368 // step #0: check SPD and ITS clusters
370 nSPD = TESTBIT(track->GetITSClusterMap(), 0);
371 nSPD += TESTBIT(track->GetITSClusterMap(), 1);
372 if (nSPD < fSPDminNClusters) {
373 AliDebug(AliLog::kDebug + 2, "Not enough SPD clusters in this track. Rejected");
378 //step #1: check number of clusters
379 if ((!fIsUseCrossedRowsCut) && (track->GetTPCNcls() < fTPCminNClusters)) {
380 AliDebug(AliLog::kDebug + 2, "Too few TPC clusters. Rejected");
384 if (track->GetITSNcls() < fITSminNClusters) {
385 AliDebug(AliLog::kDebug + 2, "Too few ITS clusters. Rejected");
389 //check track chi square
390 if (track->Chi2perNDF() > fTrackMaxChi2) {
391 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
395 //step #2a: check number of crossed rows in TPC
396 if (fIsUseCrossedRowsCut) {
397 Float_t nCrossedRowsTPC = track->GetTPCNCrossedRows();
398 if (nCrossedRowsTPC < fTPCminNCrossedRows) {
399 AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows. Rejected");
402 if (track->GetTPCNclsF()>0) {
403 Float_t ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC / track->GetTPCNclsF();
404 if (ratioCrossedRowsOverFindableClustersTPC < fTPCminCrossedRowsOverFindableCls){
405 AliDebug(AliLog::kDebug + 2, "Too few TPC crossed rows/findable clusters. Rejected");
409 AliDebug(AliLog::kDebug + 2, "Negative value for TPC crossed rows/findable clusters. Rejected");
413 //step #2b: check on track length in active volume of TPC implemented only for ESD tracks
414 //if (fIsUseLengthActiveVolumeTPCCut) { // not yet implemented in AODs}
416 //step #3: reject kink daughters
417 AliAODVertex *vertex = track->GetProdVertex();
418 if (vertex && fRejectKinkDaughters) {
419 if (vertex->GetType() == AliAODVertex::kKink) {
420 AliDebug(AliLog::kDebug + 2, "Kink daughter. Rejected");
425 // step #4: DCA cut (transverse)
426 // --> reject all tracks not ITS refitted
427 Double_t b[2], cov[3];
428 vertex = aodEvent->GetPrimaryVertex();
430 AliDebug(AliLog::kDebug + 2, "NULL vertex");
433 if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) {
434 AliDebug(AliLog::kDebug + 2, "Not ITS refitted");
437 if (!track->PropagateToDCA(vertex, aodEvent->GetMagneticField(), kVeryBig, b, cov)) {
438 AliDebug(AliLog::kDebug + 2, "Failed propagation to vertex");
441 // if the DCA cut is not fixed, compute current value
442 if (!fDCARmaxfixed) {
443 TString str(fDCARptFormula);
444 str.ReplaceAll("pt", "x");
445 TFormula dcaXY(Form("%s_dcaXY", GetName()), str.Data());
446 fDCARmax = dcaXY.Eval(track->Pt());
448 if (!fDCARminfixed) {
449 TString str2(fDCARptFormulaMin);
450 str2.ReplaceAll("pt", "x");
451 TFormula dcaXY_2(Form("%s_dcaXY_2", GetName()), str2.Data());
452 fDCARmin = dcaXY_2.Eval(track->Pt());
455 if (TMath::Abs(b[0]) > fDCARmax) {
456 AliDebug(AliLog::kDebug + 2, "Too large transverse DCA");
460 if (TMath::Abs(b[0]) < fDCARmin) {
461 AliDebug(AliLog::kDebug + 2, "Too short transverse DCA");
465 // step #5: DCA cut (longitudinal)
466 // the DCA has already been computed above
467 // if the DCA cut is not fixed, compute current value
469 TString str(fDCAZptFormula);
470 str.ReplaceAll("pt", "x");
471 TFormula dcaZ(Form("%s_dcaXY", GetName()), str.Data());
472 fDCAZmax = dcaZ.Eval(track->Pt());
475 if (TMath::Abs(b[1]) > fDCAZmax) {
476 AliDebug(AliLog::kDebug + 2, "Too large longitudinal DCA");
480 // step #6: check eta/pt range
481 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) {
482 AliDebug(AliLog::kDebug + 2, "Outside ETA acceptance");
485 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) {
486 AliDebug(AliLog::kDebug + 2, "Outside PT acceptance");
490 // if we are here, all cuts were passed and no exit point was got
491 AliDebug(AliLog::kDebug + 2, "============================= ACCEPTED TRACK =====================================================");
495 //_________________________________________________________________________________________________
496 void AliRsnCutTrackQuality::Print(const Option_t *) const
499 // Print information on this cut
502 AliInfo(Form("Cut name : %s", GetName()));
503 AliInfo(Form("Required flags (off, on): %lx %lx", fFlagsOn, fFlagsOff));
504 AliInfo(Form("Ranges in eta, pt : %.2f - %.2f, %.2f - %.2f", fEta[0], fEta[1], fPt[0], fPt[1]));
505 AliInfo(Form("Kink daughters are : %s", (fRejectKinkDaughters ? "rejected" : "accepted")));
506 AliInfo(Form("TPC requirements (clusters) : min. cluster = %i, max chi2 = %f", fTPCminNClusters, fTPCmaxChi2));
507 AliInfo(Form("TPC requirements (crossed rows) : min. crossed rows = %f, min. crossed rows/findable clusters = %f", fTPCminNCrossedRows, fTPCminCrossedRowsOverFindableCls));
508 AliInfo(Form("TPC requirements (track length) : min. track length in active volume TPC = %f", fCutMinLengthActiveVolumeTPC));
510 AliInfo(Form("ITS requirements : min. cluster = %d (all), %d (SPD), max chi2 = %f", fITSminNClusters, fSPDminNClusters, fITSmaxChi2));
513 AliInfo(Form("Max DCA r cut : fixed to %f cm", fDCARmax));
515 AliInfo(Form("Max DCA r cut formula : %s", fDCARptFormula.Data()));
519 AliInfo(Form("Min DCA r cut : fixed to %f cm", fDCARmin));
521 AliInfo(Form("Min DCA r cut formula : %s", fDCARptFormulaMin.Data()));
525 AliInfo(Form("DCA z cut : fixed to %f cm", fDCAZmax));
527 AliInfo(Form("DCA z cut formula : %s", fDCAZptFormula.Data()));
530 AliInfo(Form("fAODTestFilterBit : filter bit %i",fAODTestFilterBit));
531 AliInfo(Form("fCheckOnlyFilterBit : %i",((int) fCheckOnlyFilterBit)));
533 //__________________________________________________________________________________________________
534 void AliRsnCutTrackQuality::SetDefaults2010(Bool_t useTPCCrossedRows, Bool_t useDefaultKinematicCuts)
537 // Default settings for cuts used in 2010
540 fIsUseCrossedRowsCut=useTPCCrossedRows;
541 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE, fIsUseCrossedRowsCut);
542 if (useDefaultKinematicCuts) {
543 SetPtRange(0.15, 1E+20);
544 SetEtaRange(-0.8, 0.8);
546 SetAODTestFilterBit(5);
550 //__________________________________________________________________________________________________
551 void AliRsnCutTrackQuality::SetDefaultsHighPt2011(Bool_t useTPCCrossedRows, Bool_t useDefaultKinematicCuts)
554 // Default settings for cuts used in 2011 (for high-pT)
556 fIsUseCrossedRowsCut=useTPCCrossedRows;
557 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE, fIsUseCrossedRowsCut);
558 fESDtrackCuts->SetMinNCrossedRowsTPC(120); //default is min 70 crossed rows -> use 120 to go to higher pt
559 fESDtrackCuts->SetMaxFractionSharedTPCClusters(0.4);//default is not set --> use to go to higher pt
560 if (useDefaultKinematicCuts) {
561 SetPtRange(0.15, 1E+20);
562 SetEtaRange(-0.8, 0.8);
564 SetAODTestFilterBit(10);
568 //__________________________________________________________________________________________________
569 void AliRsnCutTrackQuality::SetDefaults2011(Bool_t useTPCCrossedRows, Bool_t useDefaultKinematicCuts)
572 // Default std cuts 2011 with crossed rows (=70)
574 fIsUseCrossedRowsCut=useTPCCrossedRows;
575 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,fIsUseCrossedRowsCut);
576 if (useDefaultKinematicCuts) {
577 SetPtRange(0.15, 1E+20);
578 SetEtaRange(-0.8, 0.8);
580 SetAODTestFilterBit(5);
583 //__________________________________________________________________________________________________
584 const char *AliRsnCutTrackQuality::Binary(UInt_t number)
587 // Convert an integer in binary
594 for (z = 512; z > 0; z >>= 1)
595 strncat(b, ((number & z) == z) ? "1" : "0", 1);