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: Massimo Venaruzzo (massimo.venaruzzo@ts.infn.it)
16 // modified: Enrico Fragiacomo (enrico.fragiacomo@ts.infn.it)
19 #include <Riostream.h>
24 #include "AliESDtrackCuts.h"
26 #include "AliRsnEvent.h"
27 #include "AliRsnDaughter.h"
28 #include "AliRsnCutV0.h"
32 //_________________________________________________________________________________________________
33 AliRsnCutV0::AliRsnCutV0(const char *name, Int_t hypothesis, AliPID::EParticleType pid, AliPID::EParticleType pid2) :
34 AliRsnCut(name, AliRsnTarget::kDaughter),
39 fMinCosPointAngle(0.95),
40 fMaxDaughtersDCA(0.5),
48 fCutQuality(Form("%sDaughtersQuality", name)),
52 // Default constructor.
53 // Initializes all cuts in such a way that all of them are disabled.
56 SetHypothesis(hypothesis);
59 //_________________________________________________________________________________________________
60 AliRsnCutV0::AliRsnCutV0(const AliRsnCutV0 ©) :
62 fHypothesis(copy.fHypothesis),
64 fTolerance(copy.fTolerance),
65 fMaxDCAVertex(copy.fMaxDCAVertex),
66 fMinCosPointAngle(copy.fMinCosPointAngle),
67 fMaxDaughtersDCA(copy.fMaxDaughtersDCA),
68 fMinTPCcluster(copy.fMinTPCcluster),
69 fMaxRapidity(copy.fMaxRapidity),
72 fPIDCutProton(copy.fPIDCutProton),
73 fPIDCutPion(copy.fPIDCutPion),
74 fESDtrackCuts(copy.fESDtrackCuts),
75 fCutQuality(copy.fCutQuality),
76 fAODTestFilterBit(copy.fAODTestFilterBit)
80 // Just copy all data member values.:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
83 fCutQuality.SetPtRange(0.15, 1E+20);
84 fCutQuality.SetEtaRange(-0.8, 0.8);
85 fCutQuality.SetSPDminNClusters(1);
86 fCutQuality.SetITSminNClusters(0);
87 fCutQuality.SetITSmaxChi2(1E+20);
88 fCutQuality.SetTPCminNClusters(fMinTPCcluster);
89 fCutQuality.SetTPCmaxChi2(4.0);
90 fCutQuality.SetRejectKinkDaughters();
91 fCutQuality.SetAODTestFilterBit(5);
95 //_________________________________________________________________________________________________
96 AliRsnCutV0 &AliRsnCutV0::operator=(const AliRsnCutV0 ©)
99 // Assignment operator.
100 // Just copy all data member values.
104 fHypothesis = copy.fHypothesis;
106 fTolerance = copy.fTolerance;
107 fMaxDCAVertex = copy.fMaxDCAVertex;
108 fMinCosPointAngle = copy.fMinCosPointAngle;
109 fMaxDaughtersDCA = copy.fMaxDaughtersDCA;
110 fMinTPCcluster = copy.fMinTPCcluster;
111 fMaxRapidity = copy.fMaxRapidity;
112 fCutQuality = copy.fCutQuality;
115 fPIDCutProton = copy.fPIDCutProton;
116 fPIDCutPion = copy.fPIDCutPion;
117 fESDtrackCuts = copy.fESDtrackCuts;
118 fCutQuality = copy.fCutQuality;
119 fAODTestFilterBit = copy.fAODTestFilterBit;
124 //_________________________________________________________________________________________________
125 Bool_t AliRsnCutV0::IsSelected(TObject *object)
127 //:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
130 // Checks the type of object being evaluated
131 // and then calls the appropriate sub-function (for ESD or AOD)
135 if (!TargetOK(object)) return kFALSE;
138 AliESDv0 *v0esd = fDaughter->Ref2ESDv0();
139 AliAODv0 *v0aod = fDaughter->Ref2AODv0();
140 //cout << fDaughter->GetRef()->ClassName() << ' ' << v0esd << ' ' << v0aod << endl;
142 // operate depending on cast:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
145 return CheckESD(v0esd);
147 return CheckAOD(v0aod);
149 AliDebugClass(1, "Object is not a V0");
154 //_________________________________________________________________________________________________
155 Bool_t AliRsnCutV0::CheckESD(AliESDv0 *v0)
159 // This is done using the default track checker for ESD.
160 // It is declared static, not to recreate it every time.
163 AliDebugClass(1, "Check ESD");
164 if (v0->GetOnFlyStatus()) {
165 AliDebugClass(1, "Rejecting V0 in 'on fly' status");
166 return kFALSE; // if kTRUE, then this V0 is recontructed
169 // retrieve pointer to owner event
170 AliESDEvent *lESDEvent = fEvent->GetRefESD();
171 Double_t xPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetX();
172 Double_t yPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetY();
173 Double_t zPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetZ();
174 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
176 // retrieve the V0 daughters
177 UInt_t lIdxPos = (UInt_t) TMath::Abs(v0->GetPindex());
178 UInt_t lIdxNeg = (UInt_t) TMath::Abs(v0->GetNindex());
179 AliESDtrack *pTrack = lESDEvent->GetTrack(lIdxPos);
180 AliESDtrack *nTrack = lESDEvent->GetTrack(lIdxNeg);
182 // check quality cuts
184 AliDebugClass(2, "Checking quality cuts");
185 if (!fESDtrackCuts->IsSelected(pTrack)) {
186 AliDebugClass(2, "Positive daughter failed quality cuts");
189 if (!fESDtrackCuts->IsSelected(nTrack)) {
190 AliDebugClass(2, "Negative daughter failed quality cuts");
195 // filter like-sign V0
196 if ( TMath::Abs( ((pTrack->GetSign()) - (nTrack->GetSign())) ) < 0.1) {
197 AliDebugClass(2, "Failed like-sign V0 check");
202 // check compatibility with expected species hypothesis
203 v0->ChangeMassHypothesis(fHypothesis);
204 if ((TMath::Abs(v0->GetEffMass() - fMass)) > fTolerance) {
205 AliDebugClass(2, "V0 is not in the expected inv mass range");
209 // topological checks
210 if (TMath::Abs(v0->GetD(xPrimaryVertex, yPrimaryVertex, zPrimaryVertex)) > fMaxDCAVertex) {
211 AliDebugClass(2, "Failed check on DCA to primary vertes");
214 if (TMath::Abs(v0->GetV0CosineOfPointingAngle()) < fMinCosPointAngle) {
215 AliDebugClass(2, "Failed check on cosine of pointing angle");
218 if (TMath::Abs(v0->GetDcaV0Daughters()) > fMaxDaughtersDCA) {
219 AliDebugClass(2, "Failed check on DCA between daughters");
222 if (TMath::Abs(v0->Y(fHypothesis)) > fMaxRapidity) {
223 AliDebugClass(2, "Failed check on V0 rapidity");
228 // check PID on proton or antiproton from V0
230 // check initialization of PID object
231 AliPIDResponse *pid = fEvent->GetPIDResponse();
233 AliFatal("NULL PID response");
237 // check if TOF is matched
238 // and computes all values used in the PID cut
239 //Bool_t isTOFpos = MatchTOF(ptrack);
240 //Bool_t isTOFneg = MatchTOF(ntrack);
241 //Double_t pospTPC = pTrack->GetTPCmomentum();
242 //Double_t negpTPC = nTrack->GetTPCmomentum();
243 //Double_t posp = pTrack->P();
244 //Double_t negp = nTrack->P();
245 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
246 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
247 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
248 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
249 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
250 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
251 Double_t maxTPC = 1E20;
252 Double_t maxTPC2 = 1E20;
253 //Double_t maxTOF = 1E20;
255 // applies the cut differently depending on the PID and the momentum
257 if(fHypothesis==kLambda0) {
259 // TPC: 5sigma cut for all
260 //if (posnsTPC > 5.0) return kFALSE;
263 //return (posnsTOF <= maxTOF);
267 maxTPC = fPIDCutProton;
268 maxTPC2 = fPIDCutPion;
270 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
271 AliDebugClass(2, "Failed check on V0 PID");
278 if(fHypothesis==kLambda0Bar) {
280 // TPC: 5sigma cut for all
281 //if (negnsTPC > 5.0) return kFALSE;
284 //return (negnsTOF <= maxTOF);
289 maxTPC = fPIDCutProton;
290 maxTPC2 = fPIDCutPion;
292 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
293 AliDebugClass(2, "Failed check on V0 PID");
300 // if we reach this point, all checks were successful
301 AliDebugClass(2, "Good V0 (hallelujah)");
305 //_________________________________________________________________________________________________
306 Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
310 // This is done doing directly all checks, since there is not
311 // an equivalend checker for AOD tracks
314 AliDebugClass(2, "Check AOD");
315 if (v0->GetOnFlyStatus()) {
316 AliDebugClass(2, "Rejecting V0 in 'on fly' status");
317 return kFALSE; // if kTRUE, then this V0 is recontructed
322 // retrieve pointer to owner event
323 AliAODEvent *lAODEvent = fEvent->GetRefAOD();
324 Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
325 Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
326 Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
327 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
329 // retrieve the V0 daughters
330 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
331 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
334 // check quality cuts
335 UInt_t filtermapP = 9999;
336 UInt_t filtermapN = 9999;
337 filtermapP = pTrack->GetFilterMap();
338 filtermapN = nTrack->GetFilterMap();
341 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
342 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
345 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
346 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
352 /*AliDebugClass(1, Form("fESDtrackCuts=%p",fESDtrackCuts));
353 if (fESDtrackCuts) { // use fESDtrackCuts to retrieve cuts values
356 AliDebugClass(2, "Checking quality cuts");
360 const Bool_t CutAcceptKinkDaughters = fESDtrackCuts->GetAcceptKinkDaughters(); // 0 = kFalse
361 const Float_t CutMaxChi2PerClusterTPC = fESDtrackCuts->GetMaxChi2PerClusterTPC();
362 const Int_t CutMinNClusterTPC = fESDtrackCuts->GetMinNClusterTPC();
363 const Bool_t CutRequireTPCRefit = fESDtrackCuts->GetRequireTPCRefit();
364 //AliDebugClass(2, Form("accept kink=%d maxchi2=%f minnclSTPC=%d requireTPCrefit=%d", CutAcceptKinkDaughters,
365 // CutMaxChi2PerClusterTPC, CutMinNClusterTPC, CutRequireTPCRefit));
366 //AliDebugClass(2, Form("pTrack->TPCNcls=%d", pTrack->GetTPCNcls() ));
367 //AliDebugClass(2, Form("nTrack->TPCNcls=%d", nTrack->GetTPCNcls() ));
370 if(pTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Positive daughter not MinNclsTPC"); return kFALSE;}
371 if(nTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Negative daughter not MinNclsTPC"); return kFALSE;}
375 // filter like-sign V0
376 if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
377 AliDebugClass(2, "Failed like-sign V0 check");
381 // check compatibility with expected species hypothesis
383 if(fHypothesis==kLambda0) {
384 mass = v0->MassLambda();
386 else if (fHypothesis==kLambda0Bar) {
387 mass = v0->MassAntiLambda();
389 if ((TMath::Abs(mass - fMass)) > fTolerance) {
390 AliDebugClass(2, Form("V0 is not in the expected inv mass range Mass: %d %f %f", fHypothesis, fMass, mass));
393 AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
396 // topological checks
397 if (TMath::Abs(v0->DcaV0ToPrimVertex()) > fMaxDCAVertex) {
398 AliDebugClass(2, Form("Failed check on DCA to primary vertes dca=%f maxdca=%f",TMath::Abs(v0->DcaV0ToPrimVertex()),fMaxDCAVertex));
401 if (TMath::Abs( TMath::Cos(v0->OpenAngleV0()) ) < fMinCosPointAngle) {
402 AliDebugClass(2, "Failed check on cosine of pointing angle");
405 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
406 AliDebugClass(2, "Failed check on DCA between daughters");
409 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
410 AliDebugClass(2, "Failed check on V0 rapidity");
418 // check initialization of PID object
419 AliPIDResponse *pid = fEvent->GetPIDResponse();
421 AliFatal("NULL PID response");
425 // check if TOF is matched
426 // and computes all values used in the PID cut
427 //Bool_t isTOFpos = MatchTOF(ptrack);
428 //Bool_t isTOFneg = MatchTOF(ntrack);
429 //Double_t pospTPC = pTrack->GetTPCmomentum();
430 //Double_t negpTPC = nTrack->GetTPCmomentum();
431 //Double_t posp = pTrack->P();
432 //Double_t negp = nTrack->P();
433 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
434 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
435 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
436 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
437 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
438 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
439 Double_t maxTPC = 1E20;
440 Double_t maxTPC2 = 1E20;
441 //Double_t maxTOF = 1E20;
443 // applies the cut differently depending on the PID and the momentum
445 if(fHypothesis==kLambda0) {
449 // TPC: 5sigma cut for all
450 //if (posnsTPC > 5.0) return kFALSE;
453 //return (posnsTOF <= maxTOF);
458 maxTPC = fPIDCutProton;
459 maxTPC2 = fPIDCutPion;
461 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
462 AliDebugClass(2, "Failed check on V0 PID");
467 if(fHypothesis==kLambda0Bar) {
470 // TPC: 5sigma cut for all
471 //if (negnsTPC > 5.0) return kFALSE;
474 //return (negnsTOF <= maxTOF);
479 maxTPC = fPIDCutProton;
480 maxTPC2 = fPIDCutPion;
482 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
483 AliDebugClass(2, "Failed check on V0 PID");
490 // if we reach this point, all checks were successful
491 AliDebugClass(1, "Good AOD V0 (hallelujah)");
492 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
497 //_________________________________________________________________________________________________
498 void AliRsnCutV0::Print(const Option_t *) const
501 // Print information on this cut