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) :
34 AliRsnCutV0::AliRsnCutV0(const char *name, Int_t hypothesis, AliPID::EParticleType pid, AliPID::EParticleType pid2) :
35 AliRsnCut(name, AliRsnTarget::kDaughter),
40 fMinCosPointAngle(0.95),
41 fMaxDaughtersDCA(0.5),
49 fCutQuality(Form("%sDaughtersQuality", name)),
53 // Default constructor.
54 // Initializes all cuts in such a way that all of them are disabled.
57 SetHypothesis(hypothesis);
60 //_________________________________________________________________________________________________
61 AliRsnCutV0::AliRsnCutV0(const AliRsnCutV0 ©) :
63 fHypothesis(copy.fHypothesis),
65 fTolerance(copy.fTolerance),
66 fMaxDCAVertex(copy.fMaxDCAVertex),
67 fMinCosPointAngle(copy.fMinCosPointAngle),
68 fMaxDaughtersDCA(copy.fMaxDaughtersDCA),
69 fMaxRapidity(copy.fMaxRapidity),
72 fPIDCut1(copy.fPIDCut1),
73 fPIDCut2(copy.fPIDCut2),
74 fPIDCut3(copy.fPIDCut3),
75 fESDtrackCuts(copy.fESDtrackCuts),
76 fCutQuality(copy.fCutQuality),
77 fAODTestFilterBit(copy.fAODTestFilterBit)
81 // Just copy all data member values.:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
84 fCutQuality.SetPtRange(0.15, 1E+20);
85 fCutQuality.SetEtaRange(-0.8, 0.8);
86 fCutQuality.SetDCARmax(0.05);
87 //fCutQuality.SetDCARPtFormula("0.0182+0.0350/pt^1.01");
88 fCutQuality.SetDCAZmax(2.0);
89 fCutQuality.SetSPDminNClusters(1);
90 fCutQuality.SetITSminNClusters(0);
91 fCutQuality.SetITSmaxChi2(1E+20);
92 fCutQuality.SetTPCminNClusters(70);
93 fCutQuality.SetTPCmaxChi2(4.0);
94 fCutQuality.SetRejectKinkDaughters();
95 fCutQuality.SetAODTestFilterBit(5);
99 //_________________________________________________________________________________________________
100 AliRsnCutV0& AliRsnCutV0::operator=(const AliRsnCutV0 ©)
103 // Assignment operator.
104 // Just copy all data member values.
106 fHypothesis = copy.fHypothesis;
108 fTolerance = copy.fTolerance;
109 fMaxDCAVertex = copy.fMaxDCAVertex;
110 fMinCosPointAngle = copy.fMinCosPointAngle;
111 fMaxDaughtersDCA = copy.fMaxDaughtersDCA;
112 fMaxRapidity = copy.fMaxRapidity;
115 fPIDCut1 = copy.fPIDCut1;
116 fPIDCut2 = copy.fPIDCut2;
117 fPIDCut3 = copy.fPIDCut3;
118 fESDtrackCuts = copy.fESDtrackCuts;
119 fCutQuality = copy.fCutQuality;
120 fAODTestFilterBit = copy.fAODTestFilterBit;
125 //_________________________________________________________________________________________________
126 Bool_t AliRsnCutV0::IsSelected(TObject *object)
128 //:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
131 // Checks the type of object being evaluated
132 // and then calls the appropriate sub-function (for ESD or AOD)
136 if (!TargetOK(object)) return kFALSE;
139 AliESDv0 *v0esd = fDaughter->Ref2ESDv0();
140 AliAODv0 *v0aod = fDaughter->Ref2AODv0();
141 //cout << fDaughter->GetRef()->ClassName() << ' ' << v0esd << ' ' << v0aod << endl;
143 // operate depending on cast:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
146 return CheckESD(v0esd);
148 return CheckAOD(v0aod);
150 AliDebugClass(1, "Object is not a V0");
155 //_________________________________________________________________________________________________
156 Bool_t AliRsnCutV0::CheckESD(AliESDv0 *v0)
160 // This is done using the default track checker for ESD.
161 // It is declared static, not to recreate it every time.
164 AliDebugClass(1, "Check ESD");
165 if (v0->GetOnFlyStatus()) {
166 AliDebugClass(1, "Rejecting V0 in 'on fly' status");
167 return kFALSE; // if kTRUE, then this V0 is recontructed
170 // retrieve pointer to owner event
171 AliESDEvent *lESDEvent = fEvent->GetRefESD();
172 Double_t xPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetX();
173 Double_t yPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetY();
174 Double_t zPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetZ();
175 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
177 // retrieve the V0 daughters
178 UInt_t lIdxPos = (UInt_t) TMath::Abs(v0->GetPindex());
179 UInt_t lIdxNeg = (UInt_t) TMath::Abs(v0->GetNindex());
180 AliESDtrack *pTrack = lESDEvent->GetTrack(lIdxPos);
181 AliESDtrack *nTrack = lESDEvent->GetTrack(lIdxNeg);
183 // check quality cuts
185 AliDebugClass(2, "Checking quality cuts");
186 if (!fESDtrackCuts->IsSelected(pTrack)) {
187 AliDebugClass(2, "Positive daughter failed quality cuts");
190 if (!fESDtrackCuts->IsSelected(nTrack)) {
191 AliDebugClass(2, "Negative daughter failed quality cuts");
196 // filter like-sign V0
197 if ( TMath::Abs( ((pTrack->GetSign()) - (nTrack->GetSign())) ) < 0.1) {
198 AliDebugClass(2, "Failed like-sign V0 check");
203 // check compatibility with expected species hypothesis
204 v0->ChangeMassHypothesis(fHypothesis);
205 if ((TMath::Abs(v0->GetEffMass() - fMass)) > fTolerance) {
206 AliDebugClass(2, "V0 is not in the expected inv mass range");
210 // topological checks
211 if (TMath::Abs(v0->GetD(xPrimaryVertex, yPrimaryVertex, zPrimaryVertex)) > fMaxDCAVertex) {
212 AliDebugClass(2, "Failed check on DCA to primary vertes");
215 if (TMath::Abs(v0->GetV0CosineOfPointingAngle()) < fMinCosPointAngle) {
216 AliDebugClass(2, "Failed check on cosine of pointing angle");
219 if (TMath::Abs(v0->GetDcaV0Daughters()) > fMaxDaughtersDCA) {
220 AliDebugClass(2, "Failed check on DCA between daughters");
223 if (TMath::Abs(v0->Y(fHypothesis)) > fMaxRapidity) {
224 AliDebugClass(2, "Failed check on V0 rapidity");
229 // check PID on proton or antiproton from V0
231 // check initialization of PID object
232 AliPIDResponse *pid = fEvent->GetPIDResponse();
234 AliFatal("NULL PID response");
238 // check if TOF is matched
239 // and computes all values used in the PID cut
240 //Bool_t isTOFpos = MatchTOF(ptrack);
241 //Bool_t isTOFneg = MatchTOF(ntrack);
242 Double_t pospTPC = pTrack->GetTPCmomentum();
243 Double_t negpTPC = nTrack->GetTPCmomentum();
244 //Double_t posp = pTrack->P();
245 //Double_t negp = nTrack->P();
246 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
247 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
248 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
249 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
250 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
251 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
252 Double_t maxTPC = 1E20;
253 Double_t maxTPC2 = 1E20;
254 //Double_t maxTOF = 1E20;
256 // applies the cut differently depending on the PID and the momentum
258 if(fHypothesis==kLambda0){
260 // TPC: 5sigma cut for all
261 //if (posnsTPC > 5.0) return kFALSE;
264 //return (posnsTOF <= maxTOF);
267 // below 600 MeV: 4sigma
268 // above 600 MeV: 3sigma
270 if (pospTPC <= 0.6 && fPID==AliPID::kProton)
272 else if (pospTPC > 0.6 && fPID==AliPID::kProton)
279 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
280 AliDebugClass(2, "Failed check on V0 PID");
287 if(fHypothesis==kLambda0Bar){
289 // TPC: 5sigma cut for all
290 //if (negnsTPC > 5.0) return kFALSE;
293 //return (negnsTOF <= maxTOF);
296 // below 600 MeV: 4sigma
297 // above 600 MeV: 3sigma
299 if (negpTPC <= 0.6 && fPID==AliPID::kProton)
301 else if (negpTPC > 0.6 && fPID==AliPID::kProton)
308 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ){
309 AliDebugClass(2, "Failed check on V0 PID");
316 // if we reach this point, all checks were successful
317 AliDebugClass(2, "Good V0 (hallelujah)");
321 //_________________________________________________________________________________________________
322 Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
326 // This is done doing directly all checks, since there is not
327 // an equivalend checker for AOD tracks
330 AliDebugClass(2, "Check AOD");
331 if (v0->GetOnFlyStatus()) {
332 AliDebugClass(2, "Rejecting V0 in 'on fly' status");
333 return kFALSE; // if kTRUE, then this V0 is recontructed
338 // retrieve pointer to owner event
339 AliAODEvent *lAODEvent = fEvent->GetRefAOD();
340 Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
341 Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
342 Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
343 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
345 // retrieve the V0 daughters
346 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
347 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
350 // check quality cuts
351 UInt_t filtermapP = 9999;
352 UInt_t filtermapN = 9999;
353 filtermapP = pTrack->GetFilterMap();
354 filtermapN = nTrack->GetFilterMap();
357 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
358 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
361 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
362 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
368 AliDebugClass(1, Form("fESDtrackCuts=%p",fESDtrackCuts));
369 if (fESDtrackCuts) { // use fESDtrackCuts to retrieve cuts values
372 AliDebugClass(2, "Checking quality cuts");
376 const Bool_t CutAcceptKinkDaughters = fESDtrackCuts->GetAcceptKinkDaughters(); // 0 = kFalse
377 const Float_t CutMaxChi2PerClusterTPC = fESDtrackCuts->GetMaxChi2PerClusterTPC();
378 const Int_t CutMinNClusterTPC = fESDtrackCuts->GetMinNClusterTPC();
379 const Bool_t CutRequireTPCRefit = fESDtrackCuts->GetRequireTPCRefit();
380 //AliDebugClass(2, Form("accept kink=%d maxchi2=%f minnclSTPC=%d requireTPCrefit=%d", CutAcceptKinkDaughters,
381 // CutMaxChi2PerClusterTPC, CutMinNClusterTPC, CutRequireTPCRefit));
382 //AliDebugClass(2, Form("pTrack->TPCNcls=%d", pTrack->GetTPCNcls() ));
383 //AliDebugClass(2, Form("nTrack->TPCNcls=%d", nTrack->GetTPCNcls() ));
386 if(pTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Positive daughter not MinNclsTPC"); return kFALSE;}
387 if(nTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Negative daughter not MinNclsTPC"); return kFALSE;}
391 // filter like-sign V0
392 if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
393 AliDebugClass(2, "Failed like-sign V0 check");
397 // check compatibility with expected species hypothesis
399 if(fHypothesis==kLambda0) {
400 mass = v0->MassLambda();
402 else if (fHypothesis==kLambda0Bar) {
403 mass = v0->MassAntiLambda();
405 if ((TMath::Abs(mass - fMass)) > fTolerance) {
406 AliDebugClass(2, Form("V0 is not in the expected inv mass range Mass: %d %f %f", fHypothesis, fMass, mass));
409 AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
412 // topological checks
413 if (TMath::Abs(v0->DcaV0ToPrimVertex()) > fMaxDCAVertex) {
414 AliDebugClass(2, Form("Failed check on DCA to primary vertes dca=%f maxdca=%f",TMath::Abs(v0->DcaV0ToPrimVertex()),fMaxDCAVertex));
417 if (TMath::Abs( TMath::Cos(v0->OpenAngleV0()) ) < fMinCosPointAngle) {
418 AliDebugClass(2, "Failed check on cosine of pointing angle");
421 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
422 AliDebugClass(2, "Failed check on DCA between daughters");
425 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
426 AliDebugClass(2, "Failed check on V0 rapidity");
434 // check initialization of PID object
435 AliPIDResponse *pid = fEvent->GetPIDResponse();
437 AliFatal("NULL PID response");
441 // check if TOF is matched
442 // and computes all values used in the PID cut
443 //Bool_t isTOFpos = MatchTOF(ptrack);
444 //Bool_t isTOFneg = MatchTOF(ntrack);
445 Double_t pospTPC = pTrack->GetTPCmomentum();
446 Double_t negpTPC = nTrack->GetTPCmomentum();
447 //Double_t posp = pTrack->P();
448 //Double_t negp = nTrack->P();
449 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
450 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
451 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
452 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
453 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
454 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
455 Double_t maxTPC = 1E20;
456 Double_t maxTPC2 = 1E20;
457 //Double_t maxTOF = 1E20;
459 // applies the cut differently depending on the PID and the momentum
461 if(fHypothesis==kLambda0){
465 // TPC: 5sigma cut for all
466 //if (posnsTPC > 5.0) return kFALSE;
469 //return (posnsTOF <= maxTOF);
472 // below 600 MeV: 4sigma
473 // above 600 MeV: 3sigma
475 if (pospTPC <= 0.6 && fPID==AliPID::kProton)
476 maxTPC = fPIDCut1; // EF safer value to run on MC
477 else if (pospTPC > 0.6 && fPID==AliPID::kProton)
478 maxTPC = fPIDCut2; // EF safer value to run on MC
482 maxTPC2 = fPIDCut3; // EF safer value to run on MC
484 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
485 AliDebugClass(2, "Failed check on V0 PID");
490 if(fHypothesis==kLambda0Bar){
493 // TPC: 5sigma cut for all
494 //if (negnsTPC > 5.0) return kFALSE;
497 //return (negnsTOF <= maxTOF);
500 // below 600 MeV: 4sigma
501 // above 600 MeV: 3sigma
503 if (negpTPC <= 0.6 && fPID==AliPID::kProton)
504 maxTPC = fPIDCut1; // EF safer value to run on MC
505 else if (negpTPC > 0.6 && fPID==AliPID::kProton)
506 maxTPC = fPIDCut2; // EF safer value to run on MC
510 maxTPC2 = fPIDCut3; // EF safer value to run on MC
512 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ){
513 AliDebugClass(2, "Failed check on V0 PID");
520 // if we reach this point, all checks were successful
521 AliDebugClass(1, "Good AOD V0 (hallelujah)");
522 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
527 //_________________________________________________________________________________________________
528 void AliRsnCutV0::Print(const Option_t *) const
531 // Print information on this cut