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");
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
320 // retrieve pointer to owner event
321 AliAODEvent *lAODEvent = fEvent->GetRefAOD();
322 Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
323 Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
324 Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
325 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
327 // retrieve the V0 daughters
328 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
329 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
331 // check quality cuts
332 UInt_t filtermapP = 9999;
333 UInt_t filtermapN = 9999;
334 filtermapP = pTrack->GetFilterMap();
335 filtermapN = nTrack->GetFilterMap();
338 // next lines commented out by EF - 17/01/2014
339 // NOTE that the filter bit test on V0 daughters removes a huge amount of V0 candidates, including good ones.
340 // Likely wrong -> requires a DCA max!
341 // Removing the test, there's a little gain in efficiency in the
342 // final search for Sigma* candidates
343 // NOTE that further constrains (e.g. DCA of daughters greater than xxx),
344 // necessary to remove background, are already in V0s. (see also below)
346 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
347 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
350 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
351 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
357 // next lines are not necessary. Just left there (commented-out) to remind that the requirement on the DCA of V0 daughters
358 // is already in the V0, so requiring dca>0.050 (with 0.050 cm the default value from the Lambda analysis)
359 // does not remove V0s candidates
361 Double_t dca = v0->DcaPosToPrimVertex() ;
362 AliDebugClass(2, Form("DCA of Lambda positive daughter %f",dca));
364 AliDebugClass(2, Form("DCA of Lambda positive daughter (%f) less than 0.05",dca));
367 dca = v0->DcaNegToPrimVertex();
369 AliDebugClass(2, Form("DCA of Lambda negative daughter (%f) less than 0.05",dca));
374 // EF - 17/01/2014 - next check apparently not effective!? Already in V0s?
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));
402 // next cut is effective (should it be in AODV0?)
403 if (TMath::Abs( TMath::Cos(v0->OpenAngleV0()) ) < fMinCosPointAngle) {
404 AliDebugClass(2, "Failed check on cosine of pointing angle");
407 // next cut is effective (should it be in AODV0?)
408 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
409 AliDebugClass(2, "Failed check on DCA between daughters");
412 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
413 AliDebugClass(2, "Failed check on V0 rapidity");
417 //-----------------------------------------------------------
418 // check initialization of PID object
419 AliPIDResponse *pid = fEvent->GetPIDResponse();
421 AliFatal("NULL PID response");
425 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
426 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
427 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
428 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
429 Double_t maxTPC = 1E20;
430 Double_t maxTPC2 = 1E20;
432 // applies the cut differently depending on the PID and the momentum
433 if(fHypothesis==kLambda0) {
434 maxTPC = fPIDCutProton;
435 maxTPC2 = fPIDCutPion;
436 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
437 AliDebugClass(2, "Failed check on V0 PID");
442 if(fHypothesis==kLambda0Bar) {
443 maxTPC = fPIDCutProton;
444 maxTPC2 = fPIDCutPion;
445 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
446 AliDebugClass(2, "Failed check on V0 PID");
451 //---------------------------------------------------------------
452 // if we reach this point, all checks were successful
453 AliDebugClass(1, "Good AOD V0");
454 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
459 //_________________________________________________________________________________________________
460 void AliRsnCutV0::Print(const Option_t *) const
463 // Print information on this cut