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),
49 fCutMaxChi2TPCConstrainedVsGlobal(1E20),
50 fTPCminNCrossedRows(0),
51 fTPCminCrossedRowsOverFindableCls(0),
52 fCutMinLengthActiveVolumeTPC(0),
53 fAODTestFilterBit(-1),
54 fCheckOnlyFilterBit(kTRUE),
58 // Default constructor.
59 // Initializes all cuts in such a way that all of them are disabled.
62 SetPtRange(0.0, 1E20);
63 SetEtaRange(-1E20, 1E20);
66 //_________________________________________________________________________________________________
67 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const AliRsnCutTrackQuality ©) :
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)
93 // Just copy all data member values.
96 SetPtRange(copy.fPt[0], copy.fPt[1]);
97 SetEtaRange(copy.fEta[0], copy.fEta[1]);
100 //_________________________________________________________________________________________________
101 AliRsnCutTrackQuality &AliRsnCutTrackQuality::operator=(const AliRsnCutTrackQuality ©)
104 // Assignment operator.
105 // Just copy all data member values.
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;
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]);
139 //_________________________________________________________________________________________________
140 void AliRsnCutTrackQuality::DisableAll()
148 fRejectKinkDaughters = kFALSE;
155 fSPDminNClusters = 0;
156 fITSminNClusters = 0;
158 fTPCminNClusters = 0;
160 fAODTestFilterBit = -1;
161 fCutMaxChi2TPCConstrainedVsGlobal = 1E20;
162 fTPCminNCrossedRows = 0;
163 fTPCminCrossedRowsOverFindableCls = 0;
164 fCutMinLengthActiveVolumeTPC = 0.0;
167 const char *cutsName = fESDtrackCuts->GetName();
168 const char *cutsTitle = fESDtrackCuts->GetTitle();
169 delete fESDtrackCuts;
170 fESDtrackCuts = new AliESDtrackCuts(cutsName,cutsTitle);
172 SetPtRange(0.0, 1E20);
173 SetEtaRange(-1E20, 1E20);
176 //_________________________________________________________________________________________________
177 Bool_t AliRsnCutTrackQuality::IsSelected(TObject *object)
181 // Checks the type of object being evaluated
182 // and then calls the appropriate sub-function (for ESD or AOD)
186 if (!TargetOK(object)) return kFALSE;
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();
194 AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
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 )));
206 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
207 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
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 )));
214 // retrieve real object type
215 AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
216 AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
218 AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
220 return fESDtrackCuts->IsSelected(esdTrack);
222 return CheckESD(esdTrack);
223 } else if (aodTrack) {
224 AliDebug(AliLog::kDebug + 2, "Checking an AOD track");
225 return CheckAOD(aodTrack);
227 AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
232 //_________________________________________________________________________________________________
233 Bool_t AliRsnCutTrackQuality::CheckESD(AliESDtrack *track)
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.
240 //static AliESDtrackCuts cuts;
241 AliESDtrackCuts cuts;
243 // general acceptance/pt cuts
244 cuts.SetPtRange(fPt[0], fPt[1]);
245 cuts.SetEtaRange(fEta[0], fEta[1]);
247 // transverse DCA cuts
249 cuts.SetMaxDCAToVertexXY(fDCARmax);
251 cuts.SetMaxDCAToVertexXYPtDep(fDCARptFormula.Data());
253 // longitudinal DCA cuts
255 cuts.SetMaxDCAToVertexZ(fDCAZmax);
257 cuts.SetMaxDCAToVertexZPtDep(fDCAZptFormula.Data());
259 // these options are always disabled in current version
260 cuts.SetDCAToVertex2D(kFALSE);
261 cuts.SetRequireSigmaToVertex(kFALSE);
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);
272 // ITS related cuts for TPC+ITS tracks
273 if (fSPDminNClusters > 0)
274 cuts.SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
275 cuts.SetMaxChi2PerClusterITS(fITSmaxChi2);
277 // now that all is initialized, do the check
278 return cuts.IsSelected(track);
281 //_________________________________________________________________________________________________
282 Bool_t AliRsnCutTrackQuality::CheckAOD(AliAODTrack *track)
285 // Check an AOD track.
286 // This is done doing directly all checks, since there is not
287 // an equivalend checker for AOD tracks
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))
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;
303 // try to retrieve the reference AOD event
304 AliAODEvent *aodEvent = 0x0;
305 if (fEvent) aodEvent = fEvent->GetRefAOD();
307 AliError("AOD reference event is not initialized!");
311 // step #0: check SPD and ITS clusters
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");
321 //step #1: check number of clusters
322 if (track->GetTPCNcls() < fTPCminNClusters) {
323 AliDebug(AliLog::kDebug + 2, "Too few TPC clusters. Rejected");
326 if (track->GetITSNcls() < fITSminNClusters) {
327 AliDebug(AliLog::kDebug + 2, "Too few ITS clusters. Rejected");
332 if (track->Chi2perNDF() > fTPCmaxChi2) {
333 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
336 if (track->Chi2perNDF() > fITSmaxChi2) {
337 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
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");
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");
354 AliDebug(AliLog::kDebug + 2, "Negative value for TPC crossed rows/findable clusters. Rejected");
357 //step #2b: check on track length in active volume of TPC implemented only for ESD tracks
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");
368 // step #4: DCA cut (transverse)
369 // --> reject all tracks not ITS refitted
370 Double_t b[2], cov[3];
371 vertex = aodEvent->GetPrimaryVertex();
373 AliDebug(AliLog::kDebug + 2, "NULL vertex");
376 if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) {
377 AliDebug(AliLog::kDebug + 2, "Not ITS refitted");
380 if (!track->PropagateToDCA(vertex, aodEvent->GetMagneticField(), kVeryBig, b, cov)) {
381 AliDebug(AliLog::kDebug + 2, "Failed propagation to vertex");
384 // if the DCA cut is not fixed, compute current value
386 TString str(fDCARptFormula);
387 str.ReplaceAll("pt", "x");
388 TFormula dcaXY(Form("%s_dcaXY", GetName()), str.Data());
389 fDCARmax = dcaXY.Eval(track->Pt());
392 if (TMath::Abs(b[0]) > fDCARmax) {
393 AliDebug(AliLog::kDebug + 2, "Too large transverse DCA");
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
401 TString str(fDCAZptFormula);
402 str.ReplaceAll("pt", "x");
403 TFormula dcaZ(Form("%s_dcaXY", GetName()), str.Data());
404 fDCAZmax = dcaZ.Eval(track->Pt());
407 if (TMath::Abs(b[1]) > fDCAZmax) {
408 AliDebug(AliLog::kDebug + 2, "Too large longitudinal DCA");
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");
417 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) {
418 AliDebug(AliLog::kDebug + 2, "Outside PT acceptance");
422 // if we are here, all cuts were passed and no exit point was got
423 AliDebug(AliLog::kDebug + 2, "============================= ACCEPTED TRACK =====================================================");
427 //_________________________________________________________________________________________________
428 void AliRsnCutTrackQuality::Print(const Option_t *) const
431 // Print information on this cut
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));
442 AliInfo(Form("ITS requirements : min. cluster = %d (all), %d (SPD), max chi2 = %f", fITSminNClusters, fSPDminNClusters, fITSmaxChi2));
445 AliInfo(Form("DCA r cut : fixed to %f cm", fDCARmax));
447 AliInfo(Form("DCA r cut formula : %s", fDCARptFormula.Data()));
451 AliInfo(Form("DCA z cut : fixed to %f cm", fDCAZmax));
453 AliInfo(Form("DCA z cut formula : %s", fDCAZptFormula.Data()));
456 AliInfo(Form("fAODTestFilterBit : filter bit %i",fAODTestFilterBit));
457 AliInfo(Form("fCheckOnlyFilterBit : %i",((int) fCheckOnlyFilterBit)));
459 //__________________________________________________________________________________________________
460 void AliRsnCutTrackQuality::SetDefaults2010()
463 // Default settings for cuts used in 2010
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");
472 SetSPDminNClusters(1);
473 SetITSminNClusters(0);
474 // SetITSmaxChi2(36);
475 // SetMaxChi2TPCConstrainedGlobal(36);
476 SetTPCminNClusters(70);
478 SetRejectKinkDaughters();
479 SetAODTestFilterBit(5);
482 //__________________________________________________________________________________________________
483 void AliRsnCutTrackQuality::SetDefaults2011()
486 // Default settings for cuts used in 2011 (for high-pT)
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);
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);
503 //__________________________________________________________________________________________________
504 const char *AliRsnCutTrackQuality::Binary(UInt_t number)
507 // Convert an integer in binary
514 for (z = 512; z > 0; z >>= 1)
515 strncat(b, ((number & z) == z) ? "1" : "0", 1);