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.
108 fHypothesis = copy.fHypothesis;
110 fTolerance = copy.fTolerance;
111 fMaxDCAVertex = copy.fMaxDCAVertex;
112 fMinCosPointAngle = copy.fMinCosPointAngle;
113 fMaxDaughtersDCA = copy.fMaxDaughtersDCA;
114 fMaxRapidity = copy.fMaxRapidity;
117 fPIDCut1 = copy.fPIDCut1;
118 fPIDCut2 = copy.fPIDCut2;
119 fPIDCut3 = copy.fPIDCut3;
120 fESDtrackCuts = copy.fESDtrackCuts;
121 fCutQuality = copy.fCutQuality;
122 fAODTestFilterBit = copy.fAODTestFilterBit;
127 //_________________________________________________________________________________________________
128 Bool_t AliRsnCutV0::IsSelected(TObject *object)
130 //:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
133 // Checks the type of object being evaluated
134 // and then calls the appropriate sub-function (for ESD or AOD)
138 if (!TargetOK(object)) return kFALSE;
141 AliESDv0 *v0esd = fDaughter->Ref2ESDv0();
142 AliAODv0 *v0aod = fDaughter->Ref2AODv0();
143 //cout << fDaughter->GetRef()->ClassName() << ' ' << v0esd << ' ' << v0aod << endl;
145 // operate depending on cast:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
148 return CheckESD(v0esd);
150 return CheckAOD(v0aod);
152 AliDebugClass(1, "Object is not a V0");
157 //_________________________________________________________________________________________________
158 Bool_t AliRsnCutV0::CheckESD(AliESDv0 *v0)
162 // This is done using the default track checker for ESD.
163 // It is declared static, not to recreate it every time.
166 AliDebugClass(1, "Check ESD");
167 if (v0->GetOnFlyStatus()) {
168 AliDebugClass(1, "Rejecting V0 in 'on fly' status");
169 return kFALSE; // if kTRUE, then this V0 is recontructed
172 // retrieve pointer to owner event
173 AliESDEvent *lESDEvent = fEvent->GetRefESD();
174 Double_t xPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetX();
175 Double_t yPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetY();
176 Double_t zPrimaryVertex = lESDEvent->GetPrimaryVertex()->GetZ();
177 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
179 // retrieve the V0 daughters
180 UInt_t lIdxPos = (UInt_t) TMath::Abs(v0->GetPindex());
181 UInt_t lIdxNeg = (UInt_t) TMath::Abs(v0->GetNindex());
182 AliESDtrack *pTrack = lESDEvent->GetTrack(lIdxPos);
183 AliESDtrack *nTrack = lESDEvent->GetTrack(lIdxNeg);
185 // check quality cuts
187 AliDebugClass(2, "Checking quality cuts");
188 if (!fESDtrackCuts->IsSelected(pTrack)) {
189 AliDebugClass(2, "Positive daughter failed quality cuts");
192 if (!fESDtrackCuts->IsSelected(nTrack)) {
193 AliDebugClass(2, "Negative daughter failed quality cuts");
198 // filter like-sign V0
199 if ( TMath::Abs( ((pTrack->GetSign()) - (nTrack->GetSign())) ) < 0.1) {
200 AliDebugClass(2, "Failed like-sign V0 check");
205 // check compatibility with expected species hypothesis
206 v0->ChangeMassHypothesis(fHypothesis);
207 if ((TMath::Abs(v0->GetEffMass() - fMass)) > fTolerance) {
208 AliDebugClass(2, "V0 is not in the expected inv mass range");
212 // topological checks
213 if (TMath::Abs(v0->GetD(xPrimaryVertex, yPrimaryVertex, zPrimaryVertex)) > fMaxDCAVertex) {
214 AliDebugClass(2, "Failed check on DCA to primary vertes");
217 if (TMath::Abs(v0->GetV0CosineOfPointingAngle()) < fMinCosPointAngle) {
218 AliDebugClass(2, "Failed check on cosine of pointing angle");
221 if (TMath::Abs(v0->GetDcaV0Daughters()) > fMaxDaughtersDCA) {
222 AliDebugClass(2, "Failed check on DCA between daughters");
225 if (TMath::Abs(v0->Y(fHypothesis)) > fMaxRapidity) {
226 AliDebugClass(2, "Failed check on V0 rapidity");
231 // check PID on proton or antiproton from V0
233 // check initialization of PID object
234 AliPIDResponse *pid = fEvent->GetPIDResponse();
236 AliFatal("NULL PID response");
240 // check if TOF is matched
241 // and computes all values used in the PID cut
242 //Bool_t isTOFpos = MatchTOF(ptrack);
243 //Bool_t isTOFneg = MatchTOF(ntrack);
244 Double_t pospTPC = pTrack->GetTPCmomentum();
245 Double_t negpTPC = nTrack->GetTPCmomentum();
246 //Double_t posp = pTrack->P();
247 //Double_t negp = nTrack->P();
248 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
249 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
250 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
251 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
252 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
253 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
254 Double_t maxTPC = 1E20;
255 Double_t maxTPC2 = 1E20;
256 //Double_t maxTOF = 1E20;
258 // applies the cut differently depending on the PID and the momentum
260 if(fHypothesis==kLambda0) {
262 // TPC: 5sigma cut for all
263 //if (posnsTPC > 5.0) return kFALSE;
266 //return (posnsTOF <= maxTOF);
269 // below 600 MeV: 4sigma
270 // above 600 MeV: 3sigma
272 if (pospTPC <= 0.6 && fPID==AliPID::kProton)
274 else if (pospTPC > 0.6 && fPID==AliPID::kProton)
281 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
282 AliDebugClass(2, "Failed check on V0 PID");
289 if(fHypothesis==kLambda0Bar) {
291 // TPC: 5sigma cut for all
292 //if (negnsTPC > 5.0) return kFALSE;
295 //return (negnsTOF <= maxTOF);
298 // below 600 MeV: 4sigma
299 // above 600 MeV: 3sigma
301 if (negpTPC <= 0.6 && fPID==AliPID::kProton)
303 else if (negpTPC > 0.6 && fPID==AliPID::kProton)
310 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
311 AliDebugClass(2, "Failed check on V0 PID");
318 // if we reach this point, all checks were successful
319 AliDebugClass(2, "Good V0 (hallelujah)");
323 //_________________________________________________________________________________________________
324 Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
328 // This is done doing directly all checks, since there is not
329 // an equivalend checker for AOD tracks
332 AliDebugClass(2, "Check AOD");
333 if (v0->GetOnFlyStatus()) {
334 AliDebugClass(2, "Rejecting V0 in 'on fly' status");
335 return kFALSE; // if kTRUE, then this V0 is recontructed
340 // retrieve pointer to owner event
341 AliAODEvent *lAODEvent = fEvent->GetRefAOD();
342 Double_t xPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetX();
343 Double_t yPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetY();
344 Double_t zPrimaryVertex = lAODEvent->GetPrimaryVertex()->GetZ();
345 AliDebugClass(2, Form("Primary vertex: %f %f %f", xPrimaryVertex, yPrimaryVertex, zPrimaryVertex));
347 // retrieve the V0 daughters
348 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
349 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
352 // check quality cuts
353 UInt_t filtermapP = 9999;
354 UInt_t filtermapN = 9999;
355 filtermapP = pTrack->GetFilterMap();
356 filtermapN = nTrack->GetFilterMap();
359 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
360 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
363 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
364 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
370 /*AliDebugClass(1, Form("fESDtrackCuts=%p",fESDtrackCuts));
371 if (fESDtrackCuts) { // use fESDtrackCuts to retrieve cuts values
374 AliDebugClass(2, "Checking quality cuts");
378 const Bool_t CutAcceptKinkDaughters = fESDtrackCuts->GetAcceptKinkDaughters(); // 0 = kFalse
379 const Float_t CutMaxChi2PerClusterTPC = fESDtrackCuts->GetMaxChi2PerClusterTPC();
380 const Int_t CutMinNClusterTPC = fESDtrackCuts->GetMinNClusterTPC();
381 const Bool_t CutRequireTPCRefit = fESDtrackCuts->GetRequireTPCRefit();
382 //AliDebugClass(2, Form("accept kink=%d maxchi2=%f minnclSTPC=%d requireTPCrefit=%d", CutAcceptKinkDaughters,
383 // CutMaxChi2PerClusterTPC, CutMinNClusterTPC, CutRequireTPCRefit));
384 //AliDebugClass(2, Form("pTrack->TPCNcls=%d", pTrack->GetTPCNcls() ));
385 //AliDebugClass(2, Form("nTrack->TPCNcls=%d", nTrack->GetTPCNcls() ));
388 if(pTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Positive daughter not MinNclsTPC"); return kFALSE;}
389 if(nTrack->GetTPCNcls() < CutMinNClusterTPC) {AliDebugClass(2, "Negative daughter not MinNclsTPC"); return kFALSE;}
393 // filter like-sign V0
394 if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
395 AliDebugClass(2, "Failed like-sign V0 check");
399 // check compatibility with expected species hypothesis
401 if(fHypothesis==kLambda0) {
402 mass = v0->MassLambda();
404 else if (fHypothesis==kLambda0Bar) {
405 mass = v0->MassAntiLambda();
407 if ((TMath::Abs(mass - fMass)) > fTolerance) {
408 AliDebugClass(2, Form("V0 is not in the expected inv mass range Mass: %d %f %f", fHypothesis, fMass, mass));
411 AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
414 // topological checks
415 if (TMath::Abs(v0->DcaV0ToPrimVertex()) > fMaxDCAVertex) {
416 AliDebugClass(2, Form("Failed check on DCA to primary vertes dca=%f maxdca=%f",TMath::Abs(v0->DcaV0ToPrimVertex()),fMaxDCAVertex));
419 if (TMath::Abs( TMath::Cos(v0->OpenAngleV0()) ) < fMinCosPointAngle) {
420 AliDebugClass(2, "Failed check on cosine of pointing angle");
423 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
424 AliDebugClass(2, "Failed check on DCA between daughters");
427 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
428 AliDebugClass(2, "Failed check on V0 rapidity");
436 // check initialization of PID object
437 AliPIDResponse *pid = fEvent->GetPIDResponse();
439 AliFatal("NULL PID response");
443 // check if TOF is matched
444 // and computes all values used in the PID cut
445 //Bool_t isTOFpos = MatchTOF(ptrack);
446 //Bool_t isTOFneg = MatchTOF(ntrack);
447 Double_t pospTPC = pTrack->GetTPCmomentum();
448 Double_t negpTPC = nTrack->GetTPCmomentum();
449 //Double_t posp = pTrack->P();
450 //Double_t negp = nTrack->P();
451 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
452 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
453 //Double_t posnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ptrack, fPID));
454 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
455 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
456 //Double_t negnsTOF = TMath::Abs(pid->NumberOfSigmasTOF(ntrack, fPID));
457 Double_t maxTPC = 1E20;
458 Double_t maxTPC2 = 1E20;
459 //Double_t maxTOF = 1E20;
461 // applies the cut differently depending on the PID and the momentum
463 if(fHypothesis==kLambda0) {
467 // TPC: 5sigma cut for all
468 //if (posnsTPC > 5.0) return kFALSE;
471 //return (posnsTOF <= maxTOF);
474 // below 600 MeV: 4sigma
475 // above 600 MeV: 3sigma
477 if (pospTPC <= 0.6 && fPID==AliPID::kProton)
478 maxTPC = fPIDCut1; // EF safer value to run on MC
479 else if (pospTPC > 0.6 && fPID==AliPID::kProton)
480 maxTPC = fPIDCut2; // EF safer value to run on MC
484 maxTPC2 = fPIDCut3; // EF safer value to run on MC
486 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
487 AliDebugClass(2, "Failed check on V0 PID");
492 if(fHypothesis==kLambda0Bar) {
495 // TPC: 5sigma cut for all
496 //if (negnsTPC > 5.0) return kFALSE;
499 //return (negnsTOF <= maxTOF);
502 // below 600 MeV: 4sigma
503 // above 600 MeV: 3sigma
505 if (negpTPC <= 0.6 && fPID==AliPID::kProton)
506 maxTPC = fPIDCut1; // EF safer value to run on MC
507 else if (negpTPC > 0.6 && fPID==AliPID::kProton)
508 maxTPC = fPIDCut2; // EF safer value to run on MC
512 maxTPC2 = fPIDCut3; // EF safer value to run on MC
514 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
515 AliDebugClass(2, "Failed check on V0 PID");
522 // if we reach this point, all checks were successful
523 AliDebugClass(1, "Good AOD V0 (hallelujah)");
524 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
529 //_________________________________________________________________________________________________
530 void AliRsnCutV0::Print(const Option_t *) const
533 // Print information on this cut