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 fAODTestFilterBit(-1),
51 fCheckOnlyFilterBit(kTRUE),
55 // Default constructor.
56 // Initializes all cuts in such a way that all of them are disabled.
59 SetPtRange(0.0, 1E20);
60 SetEtaRange(-1E20, 1E20);
63 //_________________________________________________________________________________________________
64 AliRsnCutTrackQuality::AliRsnCutTrackQuality(const AliRsnCutTrackQuality ©) :
66 fFlagsOn(copy.fFlagsOn),
67 fFlagsOff(copy.fFlagsOff),
68 fRejectKinkDaughters(copy.fRejectKinkDaughters),
69 fDCARfixed(copy.fDCARfixed),
70 fDCARptFormula(copy.fDCARptFormula),
71 fDCARmax(copy.fDCARmax),
72 fDCAZfixed(copy.fDCAZfixed),
73 fDCAZptFormula(copy.fDCAZptFormula),
74 fDCAZmax(copy.fDCAZmax),
75 fSPDminNClusters(copy.fSPDminNClusters),
76 fITSminNClusters(copy.fITSminNClusters),
77 fITSmaxChi2(copy.fITSmaxChi2),
78 fTPCminNClusters(copy.fTPCminNClusters),
79 fTPCmaxChi2(copy.fTPCmaxChi2),
80 fCutMaxChi2TPCConstrainedVsGlobal(copy.fCutMaxChi2TPCConstrainedVsGlobal),
81 fAODTestFilterBit(copy.fAODTestFilterBit),
82 fCheckOnlyFilterBit(copy.fCheckOnlyFilterBit),
83 fESDtrackCuts(copy.fESDtrackCuts)
87 // Just copy all data member values.
90 SetPtRange(copy.fPt[0], copy.fPt[1]);
91 SetEtaRange(copy.fEta[0], copy.fEta[1]);
94 //_________________________________________________________________________________________________
95 AliRsnCutTrackQuality &AliRsnCutTrackQuality::operator=(const AliRsnCutTrackQuality ©)
98 // Assignment operator.
99 // Just copy all data member values.
105 fFlagsOn = copy.fFlagsOn;
106 fFlagsOff = copy.fFlagsOff;
107 fRejectKinkDaughters = copy.fRejectKinkDaughters;
108 fDCARfixed = copy.fDCARfixed;
109 fDCARptFormula = copy.fDCARptFormula;
110 fDCARmax = copy.fDCARmax;
111 fDCAZfixed = copy.fDCAZfixed;
112 fDCAZptFormula = copy.fDCAZptFormula;
113 fDCAZmax = copy.fDCAZmax;
114 fSPDminNClusters = copy.fSPDminNClusters;
115 fITSminNClusters = copy.fITSminNClusters;
116 fITSmaxChi2 = copy.fITSmaxChi2;
117 fTPCminNClusters = copy.fTPCminNClusters;
118 fTPCmaxChi2 = copy.fTPCmaxChi2;
119 fAODTestFilterBit = copy.fAODTestFilterBit;
120 fCheckOnlyFilterBit = copy.fCheckOnlyFilterBit;
121 fESDtrackCuts = copy.fESDtrackCuts;
122 SetPtRange(copy.fPt[0], copy.fPt[1]);
123 SetEtaRange(copy.fEta[0], copy.fEta[1]);
128 //_________________________________________________________________________________________________
129 void AliRsnCutTrackQuality::DisableAll()
137 fRejectKinkDaughters = kFALSE;
144 fSPDminNClusters = 0;
145 fITSminNClusters = 0;
147 fTPCminNClusters = 0;
149 fAODTestFilterBit = -1;
151 const char *cutsName = fESDtrackCuts->GetName();
152 const char *cutsTitle = fESDtrackCuts->GetTitle();
153 delete fESDtrackCuts;
154 fESDtrackCuts = new AliESDtrackCuts(cutsName,cutsTitle);
156 SetPtRange(0.0, 1E20);
157 SetEtaRange(-1E20, 1E20);
160 //_________________________________________________________________________________________________
161 Bool_t AliRsnCutTrackQuality::IsSelected(TObject *object)
165 // Checks the type of object being evaluated
166 // and then calls the appropriate sub-function (for ESD or AOD)
170 if (!TargetOK(object)) return kFALSE;
172 // status is checked in the same way for all tracks, using AliVTrack
173 // as a convention, if a the collection of 'on' flags is '0x0', it
174 // is assumed that no flags are required, and this check is skipped;
175 // for the collection of 'off' flags this is not needed
176 AliVTrack *vtrack = fDaughter->Ref2Vtrack();
178 AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
181 ULong_t status = (ULong_t)vtrack->GetStatus();
182 ULong_t checkOn = status & fFlagsOn;
183 ULong_t checkOff = status & fFlagsOff;
184 if (fFlagsOn != 0x0 && checkOn != fFlagsOn) {
185 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: required %s", Binary(fFlagsOn)));
186 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
190 AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
191 AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
194 AliDebug(AliLog::kDebug + 3, Form("Flag check OK: required %s", Binary(fFlagsOn)));
195 AliDebug(AliLog::kDebug + 3, Form(" forbidden %s", Binary(fFlagsOff)));
196 AliDebug(AliLog::kDebug + 3, Form(" track has %s", Binary(status )));
198 // retrieve real object type
199 AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
200 AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
202 AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
204 return fESDtrackCuts->IsSelected(esdTrack);
206 return CheckESD(esdTrack);
207 } else if (aodTrack) {
208 AliDebug(AliLog::kDebug + 2, "Checking an AOD track");
209 return CheckAOD(aodTrack);
211 AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
216 //_________________________________________________________________________________________________
217 Bool_t AliRsnCutTrackQuality::CheckESD(AliESDtrack *track)
220 // Check an ESD track.
221 // This is done using the default track checker for ESD.
222 // It is declared static, not to recreate it every time.
224 //static AliESDtrackCuts cuts;
225 AliESDtrackCuts cuts;
227 // general acceptance/pt cuts
228 cuts.SetPtRange(fPt[0], fPt[1]);
229 cuts.SetEtaRange(fEta[0], fEta[1]);
231 // transverse DCA cuts
233 cuts.SetMaxDCAToVertexXY(fDCARmax);
235 cuts.SetMaxDCAToVertexXYPtDep(fDCARptFormula.Data());
237 // longitudinal DCA cuts
239 cuts.SetMaxDCAToVertexZ(fDCAZmax);
241 cuts.SetMaxDCAToVertexZPtDep(fDCAZptFormula.Data());
243 // these options are always disabled in current version
244 cuts.SetDCAToVertex2D(kFALSE);
245 cuts.SetRequireSigmaToVertex(kFALSE);
247 // TPC related cuts for TPC+ITS tracks
248 cuts.SetMinNClustersTPC(fTPCminNClusters);
249 cuts.SetMaxChi2PerClusterTPC(fTPCmaxChi2);
250 cuts.SetAcceptKinkDaughters(!fRejectKinkDaughters);
251 cuts.SetMaxChi2TPCConstrainedGlobal(fCutMaxChi2TPCConstrainedVsGlobal);
253 // ITS related cuts for TPC+ITS tracks
254 if (fSPDminNClusters > 0)
255 cuts.SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
256 cuts.SetMaxChi2PerClusterITS(fITSmaxChi2);
258 // now that all is initialized, do the check
259 return cuts.IsSelected(track);
262 //_________________________________________________________________________________________________
263 Bool_t AliRsnCutTrackQuality::CheckAOD(AliAODTrack *track)
266 // Check an AOD track.
267 // This is done doing directly all checks, since there is not
268 // an equivalend checker for AOD tracks
271 // if a test bit is used, check it and skip the following
272 if (fAODTestFilterBit >= 0) {
273 UInt_t bit = 1 << fAODTestFilterBit;
274 AliDebugClass(2, Form("Required a test filter bit for AOD check: %u (result: %s)", bit, (track->TestFilterBit(bit) ? "accept" : "reject")));
275 if (!track->TestFilterBit(bit))
278 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) return kFALSE;
279 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) return kFALSE;
280 if (fCheckOnlyFilterBit) return kTRUE;
284 // try to retrieve the reference AOD event
285 AliAODEvent *aodEvent = 0x0;
286 if (fEvent) aodEvent = fEvent->GetRefAOD();
288 AliError("AOD reference event is not initialized!");
292 // step #0: check SPD and ITS clusters
294 nSPD = TESTBIT(track->GetITSClusterMap(), 0);
295 nSPD += TESTBIT(track->GetITSClusterMap(), 1);
296 if (nSPD < fSPDminNClusters) {
297 AliDebug(AliLog::kDebug + 2, "Not enough SPD clusters in this track. Rejected");
302 // step #1: check number of clusters in TPC
303 if (track->GetTPCNcls() < fTPCminNClusters) {
304 AliDebug(AliLog::kDebug + 2, "Too few TPC clusters. Rejected");
307 if (track->GetITSNcls() < fITSminNClusters) {
308 AliDebug(AliLog::kDebug + 2, "Too few ITS clusters. Rejected");
312 // step #2: check chi square
313 if (track->Chi2perNDF() > fTPCmaxChi2) {
314 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
317 if (track->Chi2perNDF() > fITSmaxChi2) {
318 AliDebug(AliLog::kDebug + 2, "Bad chi2. Rejected");
322 // step #3: reject kink daughters
323 AliAODVertex *vertex = track->GetProdVertex();
324 if (vertex && fRejectKinkDaughters) {
325 if (vertex->GetType() == AliAODVertex::kKink) {
326 AliDebug(AliLog::kDebug + 2, "Kink daughter. Rejected");
331 // step #4: DCA cut (transverse)
332 // --> reject all tracks not ITS refitted
333 Double_t b[2], cov[3];
334 vertex = aodEvent->GetPrimaryVertex();
336 AliDebug(AliLog::kDebug + 2, "NULL vertex");
339 if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) {
340 AliDebug(AliLog::kDebug + 2, "Not ITS refitted");
343 if (!track->PropagateToDCA(vertex, aodEvent->GetMagneticField(), kVeryBig, b, cov)) {
344 AliDebug(AliLog::kDebug + 2, "Failed propagation to vertex");
347 // if the DCA cut is not fixed, compute current value
349 TString str(fDCARptFormula);
350 str.ReplaceAll("pt", "x");
351 TFormula dcaXY(Form("%s_dcaXY", GetName()), str.Data());
352 fDCARmax = dcaXY.Eval(track->Pt());
355 if (TMath::Abs(b[0]) > fDCARmax) {
356 AliDebug(AliLog::kDebug + 2, "Too large transverse DCA");
360 // step #5: DCA cut (longitudinal)
361 // the DCA has already been computed above
362 // if the DCA cut is not fixed, compute current value
364 TString str(fDCAZptFormula);
365 str.ReplaceAll("pt", "x");
366 TFormula dcaZ(Form("%s_dcaXY", GetName()), str.Data());
367 fDCAZmax = dcaZ.Eval(track->Pt());
370 if (TMath::Abs(b[1]) > fDCAZmax) {
371 AliDebug(AliLog::kDebug + 2, "Too large longitudinal DCA");
375 // step #6: check eta/pt range
376 if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) {
377 AliDebug(AliLog::kDebug + 2, "Outside ETA acceptance");
380 if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) {
381 AliDebug(AliLog::kDebug + 2, "Outside PT acceptance");
385 // if we are here, all cuts were passed and no exit point was got
386 AliDebug(AliLog::kDebug + 2, "============================= ACCEPTED TRACK =====================================================");
390 //_________________________________________________________________________________________________
391 void AliRsnCutTrackQuality::Print(const Option_t *) const
394 // Print information on this cut
397 AliInfo(Form("Cut name : %s", GetName()));
398 AliInfo(Form("Required flags (off, on): %lx %lx", fFlagsOn, fFlagsOff));
399 AliInfo(Form("Ranges in eta, pt : %.2f - %.2f, %.2f - %.2f", fEta[0], fEta[1], fPt[0], fPt[1]));
400 AliInfo(Form("Kink daughters are : %s", (fRejectKinkDaughters ? "rejected" : "accepted")));
401 AliInfo(Form("TPC requirements : min. cluster = %d, max chi2 = %f", fTPCminNClusters, fTPCmaxChi2));
402 AliInfo(Form("ITS requirements : min. cluster = %d (all), %d (SPD), max chi2 = %f", fITSminNClusters, fSPDminNClusters, fITSmaxChi2));
405 AliInfo(Form("DCA r cut : fixed to %f cm", fDCARmax));
407 AliInfo(Form("DCA r cut formula : %s", fDCARptFormula.Data()));
411 AliInfo(Form("DCA z cut : fixed to %f cm", fDCAZmax));
413 AliInfo(Form("DCA z cut formula : %s", fDCAZptFormula.Data()));
416 AliInfo(Form("fAODTestFilterBit : filter bit %i",fAODTestFilterBit));
417 AliInfo(Form("fCheckOnlyFilterBit : %i",((int) fCheckOnlyFilterBit)));
419 //__________________________________________________________________________________________________
420 void AliRsnCutTrackQuality::SetDefaults2010()
423 // Default settings for cuts used in 2010
425 AddStatusFlag(AliESDtrack::kTPCin , kTRUE);
426 AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);
427 AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);
428 SetPtRange(0.15, 1E+20);
429 SetEtaRange(-0.8, 0.8);
430 SetDCARPtFormula("0.0182+0.0350/pt^1.01");
432 SetSPDminNClusters(1);
433 SetITSminNClusters(0);
434 // SetITSmaxChi2(36);
435 // SetMaxChi2TPCConstrainedGlobal(36);
436 SetTPCminNClusters(70);
438 SetRejectKinkDaughters();
439 SetAODTestFilterBit(5);
442 //__________________________________________________________________________________________________
443 void AliRsnCutTrackQuality::SetDefaults2011()
446 // Default settings for cuts used in 2011
448 fESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
449 fESDtrackCuts->SetMinNCrossedRowsTPC(120);
450 fESDtrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
451 fESDtrackCuts->SetMaxChi2PerClusterITS(36);
452 fESDtrackCuts->SetMaxFractionSharedTPCClusters(0.4);
453 fESDtrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
455 AddStatusFlag(AliESDtrack::kTPCin , kTRUE);
456 AddStatusFlag(AliESDtrack::kTPCrefit, kTRUE);
457 AddStatusFlag(AliESDtrack::kITSrefit, kTRUE);
458 SetPtRange(0.15, 1E+20);
459 SetEtaRange(-0.8, 0.8);
460 SetAODTestFilterBit(10);
463 //__________________________________________________________________________________________________
464 const char *AliRsnCutTrackQuality::Binary(UInt_t number)
467 // Convert an integer in binary
474 for (z = 512; z > 0; z >>= 1)
475 strncat(b, ((number & z) == z) ? "1" : "0", 1);