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");
227 Double_t v0Position[3]; // from $ALICE_ROOT/ANALYSIS/AliESDV0Cuts.cxx
228 v0->GetXYZ(v0Position[0],v0Position[1],v0Position[2]);
229 Double_t radius = TMath::Sqrt(TMath::Power(v0Position[0],2) + TMath::Power(v0Position[1],2));
230 if ( ( radius < 0.8 ) || ( radius > 100 ) ) {
231 AliDebugClass(2, "Failed fiducial volume");
235 // check PID on proton or antiproton from V0
237 // check initialization of PID object
238 AliPIDResponse *pid = fEvent->GetPIDResponse();
240 AliFatal("NULL PID response");
244 // check if TOF is matched
245 // and computes all values used in the PID cut
246 //Bool_t isTOFpos = MatchTOF(ptrack);
247 //Bool_t isTOFneg = MatchTOF(ntrack);
248 //Double_t pospTPC = pTrack->GetTPCmomentum();
249 //Double_t negpTPC = nTrack->GetTPCmomentum();
250 //Double_t posp = pTrack->P();
251 //Double_t negp = nTrack->P();
252 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
253 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
254 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
255 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
256 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
257 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
258 Double_t maxTPC = 1E20;
259 Double_t maxTPC2 = 1E20;
260 //Double_t maxTOF = 1E20;
262 // applies the cut differently depending on the PID and the momentum
264 if(fHypothesis==kLambda0) {
266 // TPC: 5sigma cut for all
267 //if (posnsTPC > 5.0) return kFALSE;
270 //return (posnsTOF <= maxTOF);
274 maxTPC = fPIDCutProton;
275 maxTPC2 = fPIDCutPion;
277 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
278 AliDebugClass(2, "Failed check on V0 PID");
285 if(fHypothesis==kLambda0Bar) {
287 // TPC: 5sigma cut for all
288 //if (negnsTPC > 5.0) return kFALSE;
291 //return (negnsTOF <= maxTOF);
296 maxTPC = fPIDCutProton;
297 maxTPC2 = fPIDCutPion;
299 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
300 AliDebugClass(2, "Failed check on V0 PID");
307 // if we reach this point, all checks were successful
308 AliDebugClass(2, "Good V0");
312 //_________________________________________________________________________________________________
313 Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
317 // This is done doing directly all checks, since there is not
318 // an equivalend checker for AOD tracks
321 AliDebugClass(2, "Check AOD");
322 if (v0->GetOnFlyStatus()) {
323 AliDebugClass(2, "Rejecting V0 in 'on fly' status");
324 return kFALSE; // if kTRUE, then this V0 is recontructed
327 // retrieve pointer to owner event
328 AliAODEvent *lAODEvent = fEvent->GetRefAOD();
329 Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
330 Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
331 Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
332 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
334 // retrieve the V0 daughters
335 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
336 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
338 // check quality cuts
339 UInt_t filtermapP = 9999;
340 UInt_t filtermapN = 9999;
341 filtermapP = pTrack->GetFilterMap();
342 filtermapN = nTrack->GetFilterMap();
345 // next lines commented out by EF - 17/01/2014
346 // NOTE that the filter bit test on V0 daughters removes a huge amount of V0 candidates, including good ones.
347 // Likely wrong -> requires a DCA max!
348 // Removing the test, there's a little gain in efficiency in the
349 // final search for Sigma* candidates
350 // NOTE that further constrains (e.g. DCA of daughters greater than xxx),
351 // necessary to remove background, are already in V0s. (see also below)
353 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
354 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
357 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
358 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
364 // next lines are not necessary. Just left there (commented-out) to remind that the requirement on the DCA of V0 daughters
365 // is already in the V0, so requiring dca>0.050 (with 0.050 cm the default value from the Lambda analysis)
366 // does not remove V0s candidates
368 Double_t dca = v0->DcaPosToPrimVertex() ;
369 AliDebugClass(2, Form("DCA of Lambda positive daughter %f",dca));
371 AliDebugClass(2, Form("DCA of Lambda positive daughter (%f) less than 0.05",dca));
374 dca = v0->DcaNegToPrimVertex();
376 AliDebugClass(2, Form("DCA of Lambda negative daughter (%f) less than 0.05",dca));
381 // EF - 17/01/2014 - next check apparently not effective!? Already in V0s?
382 // filter like-sign V0
383 if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
384 AliDebugClass(2, "Failed like-sign V0 check");
388 // check compatibility with expected species hypothesis
390 if(fHypothesis==kLambda0) {
391 mass = v0->MassLambda();
393 else if (fHypothesis==kLambda0Bar) {
394 mass = v0->MassAntiLambda();
396 if ((TMath::Abs(mass - fMass)) > fTolerance) {
397 AliDebugClass(2, Form("V0 is not in the expected inv mass range Mass: %d %f %f", fHypothesis, fMass, mass));
400 AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
403 // topological checks
404 if (TMath::Abs(v0->DcaV0ToPrimVertex()) > fMaxDCAVertex) {
405 AliDebugClass(2, Form("Failed check on DCA to primary vertes dca=%f maxdca=%f",TMath::Abs(v0->DcaV0ToPrimVertex()),fMaxDCAVertex));
409 // next cut is effective (should it be in AODV0?)
410 AliAODVertex *vertex = lAODEvent->GetPrimaryVertex();
411 Double_t cospointangle = v0->CosPointingAngle(vertex);
412 if (TMath::Abs( cospointangle ) < fMinCosPointAngle) {
413 AliDebugClass(2, "Failed check on cosine of pointing angle");
417 // next cut is effective (should it be in AODV0?)
418 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
419 AliDebugClass(2, "Failed check on DCA between daughters");
423 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
424 AliDebugClass(2, "Failed check on V0 rapidity");
428 Double_t radius = v0->RadiusV0();
429 if ( ( radius < 0.8 ) || ( radius > 100 ) ) {
430 AliDebugClass(2, "Failed fiducial volume");
434 //-----------------------------------------------------------
435 // check initialization of PID object
436 AliPIDResponse *pid = fEvent->GetPIDResponse();
438 AliFatal("NULL PID response");
442 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
443 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
444 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
445 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
446 Double_t maxTPC = 1E20;
447 Double_t maxTPC2 = 1E20;
449 // applies the cut differently depending on the PID and the momentum
450 if(fHypothesis==kLambda0) {
451 maxTPC = fPIDCutProton;
452 maxTPC2 = fPIDCutPion;
453 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
454 AliDebugClass(2, "Failed check on V0 PID");
459 if(fHypothesis==kLambda0Bar) {
460 maxTPC = fPIDCutProton;
461 maxTPC2 = fPIDCutPion;
462 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
463 AliDebugClass(2, "Failed check on V0 PID");
468 //---------------------------------------------------------------
469 // if we reach this point, all checks were successful
470 AliDebugClass(1, "Good AOD V0");
471 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
476 //_________________________________________________________________________________________________
477 void AliRsnCutV0::Print(const Option_t *) const
480 // Print information on this cut