]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/RESONANCES/AliRsnCutV0.cxx
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / AliRsnCutV0.cxx
CommitLineData
8082e538 1//
2// Class AliRsnCutV0
3//
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()]
7//
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.
14//
76d89202 15// authors: Massimo Venaruzzo (massimo.venaruzzo@ts.infn.it)
16// modified: Enrico Fragiacomo (enrico.fragiacomo@ts.infn.it)
8082e538 17//
18
19#include <Riostream.h>
20#include <TFormula.h>
21#include <TBits.h>
22
23#include "AliLog.h"
24#include "AliESDtrackCuts.h"
25
26#include "AliRsnEvent.h"
27#include "AliRsnDaughter.h"
28#include "AliRsnCutV0.h"
29
30ClassImp(AliRsnCutV0)
31
32//_________________________________________________________________________________________________
3da8cef7 33AliRsnCutV0::AliRsnCutV0(const char *name, Int_t hypothesis, AliPID::EParticleType pid, AliPID::EParticleType pid2) :
8082e538 34 AliRsnCut(name, AliRsnTarget::kDaughter),
35 fHypothesis(0),
36 fMass(0.0),
3da8cef7 37 fTolerance(0.01),
8082e538 38 fMaxDCAVertex(0.3),
39 fMinCosPointAngle(0.95),
3da8cef7 40 fMaxDaughtersDCA(0.5),
9d4bb6d8 41 fMinTPCcluster(70),
3da8cef7 42 fMaxRapidity(0.8),
43 fPID(pid),
44 fPID2(pid2),
92932daf 45 fPIDCutProton(0),
46 fPIDCutPion(0),
76d89202 47 fESDtrackCuts(0x0),
48 fCutQuality(Form("%sDaughtersQuality", name)),
49 fAODTestFilterBit(5)
8082e538 50{
51//
52// Default constructor.
53// Initializes all cuts in such a way that all of them are disabled.
54//
55
56 SetHypothesis(hypothesis);
57}
58
59//_________________________________________________________________________________________________
60AliRsnCutV0::AliRsnCutV0(const AliRsnCutV0 &copy) :
61 AliRsnCut(copy),
62 fHypothesis(copy.fHypothesis),
63 fMass(copy.fMass),
64 fTolerance(copy.fTolerance),
65 fMaxDCAVertex(copy.fMaxDCAVertex),
66 fMinCosPointAngle(copy.fMinCosPointAngle),
67 fMaxDaughtersDCA(copy.fMaxDaughtersDCA),
9d4bb6d8 68 fMinTPCcluster(copy.fMinTPCcluster),
e6952ec7 69 fMaxRapidity(copy.fMaxRapidity),
3da8cef7 70 fPID(copy.fPID),
71 fPID2(copy.fPID2),
92932daf 72 fPIDCutProton(copy.fPIDCutProton),
73 fPIDCutPion(copy.fPIDCutPion),
76d89202 74 fESDtrackCuts(copy.fESDtrackCuts),
75 fCutQuality(copy.fCutQuality),
76 fAODTestFilterBit(copy.fAODTestFilterBit)
8082e538 77{
78//
79// Copy constructor.
76d89202 80// Just copy all data member values.:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
81
8082e538 82//
76d89202 83 fCutQuality.SetPtRange(0.15, 1E+20);
84 fCutQuality.SetEtaRange(-0.8, 0.8);
76d89202 85 fCutQuality.SetSPDminNClusters(1);
86 fCutQuality.SetITSminNClusters(0);
87 fCutQuality.SetITSmaxChi2(1E+20);
9d4bb6d8 88 fCutQuality.SetTPCminNClusters(fMinTPCcluster);
76d89202 89 fCutQuality.SetTPCmaxChi2(4.0);
90 fCutQuality.SetRejectKinkDaughters();
91 fCutQuality.SetAODTestFilterBit(5);
92
8082e538 93}
94
95//_________________________________________________________________________________________________
e6952ec7 96AliRsnCutV0 &AliRsnCutV0::operator=(const AliRsnCutV0 &copy)
8082e538 97{
98//
99// Assignment operator.
100// Just copy all data member values.
101//
4cc7af7d 102 if (this == &copy)
103 return *this;
61f275d1 104 fHypothesis = copy.fHypothesis;
105 fMass = copy.fMass;
106 fTolerance = copy.fTolerance;
107 fMaxDCAVertex = copy.fMaxDCAVertex;
108 fMinCosPointAngle = copy.fMinCosPointAngle;
109 fMaxDaughtersDCA = copy.fMaxDaughtersDCA;
9d4bb6d8 110 fMinTPCcluster = copy.fMinTPCcluster;
3da8cef7 111 fMaxRapidity = copy.fMaxRapidity;
92932daf 112 fCutQuality = copy.fCutQuality;
3da8cef7 113 fPID = copy.fPID;
114 fPID2 = copy.fPID2;
92932daf 115 fPIDCutProton = copy.fPIDCutProton;
116 fPIDCutPion = copy.fPIDCutPion;
61f275d1 117 fESDtrackCuts = copy.fESDtrackCuts;
76d89202 118 fCutQuality = copy.fCutQuality;
119 fAODTestFilterBit = copy.fAODTestFilterBit;
61f275d1 120
8082e538 121 return (*this);
e6952ec7 122}
8082e538 123
124//_________________________________________________________________________________________________
125Bool_t AliRsnCutV0::IsSelected(TObject *object)
126{
76d89202 127//:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
128
8082e538 129// Cut checker.
130// Checks the type of object being evaluated
131// and then calls the appropriate sub-function (for ESD or AOD)
132//
133
134 // coherence check
135 if (!TargetOK(object)) return kFALSE;
e6952ec7 136
8082e538 137 // check cast
138 AliESDv0 *v0esd = fDaughter->Ref2ESDv0();
139 AliAODv0 *v0aod = fDaughter->Ref2AODv0();
140 //cout << fDaughter->GetRef()->ClassName() << ' ' << v0esd << ' ' << v0aod << endl;
e6952ec7 141
76d89202 142 // operate depending on cast:IsSelected: Object is not a V0 (RESONANCES/AliRsnCutV0.cxx:149)
61f275d1 143
8082e538 144 if (v0esd) {
145 return CheckESD(v0esd);
146 } else if (v0aod) {
147 return CheckAOD(v0aod);
148 } else {
149 AliDebugClass(1, "Object is not a V0");
150 return kFALSE;
151 }
152}
153
154//_________________________________________________________________________________________________
155Bool_t AliRsnCutV0::CheckESD(AliESDv0 *v0)
156{
157//
158// Check an ESD V0.
159// This is done using the default track checker for ESD.
160// It is declared static, not to recreate it every time.
161//
162
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
167 }
e6952ec7 168
8082e538 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));
e6952ec7 175
8082e538 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);
e6952ec7 181
8082e538 182 // check quality cuts
183 if (fESDtrackCuts) {
184 AliDebugClass(2, "Checking quality cuts");
185 if (!fESDtrackCuts->IsSelected(pTrack)) {
186 AliDebugClass(2, "Positive daughter failed quality cuts");
187 return kFALSE;
188 }
189 if (!fESDtrackCuts->IsSelected(nTrack)) {
190 AliDebugClass(2, "Negative daughter failed quality cuts");
191 return kFALSE;
192 }
193 }
e6952ec7 194
8082e538 195 // filter like-sign V0
e6952ec7 196 if ( TMath::Abs( ((pTrack->GetSign()) - (nTrack->GetSign())) ) < 0.1) {
197 AliDebugClass(2, "Failed like-sign V0 check");
198 return kFALSE;
199 }
200
61f275d1 201
8082e538 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");
206 return kFALSE;
207 }
e6952ec7 208
8082e538 209 // topological checks
210 if (TMath::Abs(v0->GetD(xPrimaryVertex, yPrimaryVertex, zPrimaryVertex)) > fMaxDCAVertex) {
211 AliDebugClass(2, "Failed check on DCA to primary vertes");
212 return kFALSE;
213 }
058e069b 214 if (TMath::Abs(v0->GetV0CosineOfPointingAngle()) < fMinCosPointAngle) {
8082e538 215 AliDebugClass(2, "Failed check on cosine of pointing angle");
216 return kFALSE;
217 }
218 if (TMath::Abs(v0->GetDcaV0Daughters()) > fMaxDaughtersDCA) {
219 AliDebugClass(2, "Failed check on DCA between daughters");
220 return kFALSE;
221 }
3da8cef7 222 if (TMath::Abs(v0->Y(fHypothesis)) > fMaxRapidity) {
e6952ec7 223 AliDebugClass(2, "Failed check on V0 rapidity");
224 return kFALSE;
76d89202 225 }
e6952ec7 226
058e069b 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");
232 return kFALSE;
233 }
234
76d89202 235 // check PID on proton or antiproton from V0
e6952ec7 236
237 // check initialization of PID object
238 AliPIDResponse *pid = fEvent->GetPIDResponse();
239 if (!pid) {
240 AliFatal("NULL PID response");
241 return kFALSE;
242 }
243
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);
92932daf 248 //Double_t pospTPC = pTrack->GetTPCmomentum();
249 //Double_t negpTPC = nTrack->GetTPCmomentum();
e6952ec7 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;
261
262 // applies the cut differently depending on the PID and the momentum
263
264 if(fHypothesis==kLambda0) {
265 //if (isTOFpos) {
266 // TPC: 5sigma cut for all
267 //if (posnsTPC > 5.0) return kFALSE;
268 // TOF: 3sigma
269 // maxTOF = 3.0;
270 //return (posnsTOF <= maxTOF);
271 //} else {
272 // TPC:
e6952ec7 273
92932daf 274 maxTPC = fPIDCutProton;
275 maxTPC2 = fPIDCutPion;
e6952ec7 276
277 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
278 AliDebugClass(2, "Failed check on V0 PID");
279 return kFALSE;
280 }
281 }
282
283 //}
284
285 if(fHypothesis==kLambda0Bar) {
286 //if (isTOFneg) {
287 // TPC: 5sigma cut for all
288 //if (negnsTPC > 5.0) return kFALSE;
289 // TOF: 3sigma
290 // maxTOF = 3.0;
291 //return (negnsTOF <= maxTOF);
292 //} else {
293 // TPC:
e6952ec7 294
92932daf 295
296 maxTPC = fPIDCutProton;
297 maxTPC2 = fPIDCutPion;
e6952ec7 298
299 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
300 AliDebugClass(2, "Failed check on V0 PID");
301 return kFALSE;
302 }
303 }
304 //}
305
306
76d89202 307 // if we reach this point, all checks were successful
e37e90f9 308 AliDebugClass(2, "Good V0");
e6952ec7 309 return kTRUE;
76d89202 310}
311
312//_________________________________________________________________________________________________
313Bool_t AliRsnCutV0::CheckAOD(AliAODv0 *v0)
314{
315//
316// Check an AOD V0.
317// This is done doing directly all checks, since there is not
318// an equivalend checker for AOD tracks
319//
320
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
325 }
326
76d89202 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));
333
334 // retrieve the V0 daughters
335 AliAODTrack *pTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(0));
336 AliAODTrack *nTrack = (AliAODTrack *) (v0->GetSecondaryVtx()->GetDaughter(1));
337
76d89202 338 // check quality cuts
339 UInt_t filtermapP = 9999;
340 UInt_t filtermapN = 9999;
341 filtermapP = pTrack->GetFilterMap();
342 filtermapN = nTrack->GetFilterMap();
e6952ec7 343
e37e90f9 344 //-----
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)
352 /*
76d89202 353 if ( !pTrack->TestFilterBit(fAODTestFilterBit) ) {
e6952ec7 354 AliDebugClass(2, Form("Positive daughter failed quality cuts filtermapP=%d",filtermapP));
355 return kFALSE;
76d89202 356 }
357 if ( !nTrack->TestFilterBit(fAODTestFilterBit) ) {
e6952ec7 358 AliDebugClass(2, Form("Negative daughter failed quality cuts filtermapN=%d",filtermapN));
359 return kFALSE;
76d89202 360 }
e37e90f9 361 */
362
363 //----
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
367 /*
368 Double_t dca = v0->DcaPosToPrimVertex() ;
369 AliDebugClass(2, Form("DCA of Lambda positive daughter %f",dca));
370 if(dca<0.050) {
371 AliDebugClass(2, Form("DCA of Lambda positive daughter (%f) less than 0.05",dca));
372 return kFALSE;
373 }
374 dca = v0->DcaNegToPrimVertex();
375 if(dca<0.050) {
376 AliDebugClass(2, Form("DCA of Lambda negative daughter (%f) less than 0.05",dca));
377 return kFALSE;
378 }
379 */
e6952ec7 380
e37e90f9 381 // EF - 17/01/2014 - next check apparently not effective!? Already in V0s?
76d89202 382 // filter like-sign V0
e6952ec7 383 if ( TMath::Abs( ((pTrack->Charge()) - (nTrack->Charge())) ) < 0.1) {
384 AliDebugClass(2, "Failed like-sign V0 check");
385 return kFALSE;
386 }
76d89202 387
388 // check compatibility with expected species hypothesis
e6952ec7 389 Double_t mass = 0.0;
390 if(fHypothesis==kLambda0) {
391 mass = v0->MassLambda();
392 }
393 else if (fHypothesis==kLambda0Bar) {
394 mass = v0->MassAntiLambda();
395 }
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));
398 return kFALSE;
399 }
76d89202 400 AliDebugClass(2, Form("Mass: %d %f %f", fHypothesis, fMass, mass));
e6952ec7 401
402
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));
406 return kFALSE;
407 }
e37e90f9 408
058e069b 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");
414 return kFALSE;
3da8cef7 415 }
058e069b 416
417 // next cut is effective (should it be in AODV0?)
76d89202 418 if (TMath::Abs(v0->DcaV0Daughters()) > fMaxDaughtersDCA) {
419 AliDebugClass(2, "Failed check on DCA between daughters");
420 return kFALSE;
421 }
058e069b 422
76d89202 423 if (TMath::Abs(v0->RapLambda()) > fMaxRapidity) {
e6952ec7 424 AliDebugClass(2, "Failed check on V0 rapidity");
425 return kFALSE;
76d89202 426 }
3da8cef7 427
058e069b 428 Double_t radius = v0->RadiusV0();
429 if ( ( radius < 0.8 ) || ( radius > 100 ) ) {
430 AliDebugClass(2, "Failed fiducial volume");
431 return kFALSE;
432 }
433
e37e90f9 434 //-----------------------------------------------------------
3da8cef7 435 // check initialization of PID object
436 AliPIDResponse *pid = fEvent->GetPIDResponse();
437 if (!pid) {
e6952ec7 438 AliFatal("NULL PID response");
439 return kFALSE;
3da8cef7 440 }
441
3da8cef7 442 Double_t posnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID));
443 Double_t posnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(pTrack, fPID2));
3da8cef7 444 Double_t negnsTPC = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID));
445 Double_t negnsTPC2 = TMath::Abs(pid->NumberOfSigmasTPC(nTrack, fPID2));
3da8cef7 446 Double_t maxTPC = 1E20;
447 Double_t maxTPC2 = 1E20;
e6952ec7 448
3da8cef7 449 // applies the cut differently depending on the PID and the momentum
e6952ec7 450 if(fHypothesis==kLambda0) {
e37e90f9 451 maxTPC = fPIDCutProton;
452 maxTPC2 = fPIDCutPion;
453 if (! ((posnsTPC <= maxTPC) && (negnsTPC2 <= maxTPC2)) ) {
454 AliDebugClass(2, "Failed check on V0 PID");
455 return kFALSE;
456 }
3da8cef7 457 }
e37e90f9 458
e6952ec7 459 if(fHypothesis==kLambda0Bar) {
e37e90f9 460 maxTPC = fPIDCutProton;
461 maxTPC2 = fPIDCutPion;
462 if(! ((negnsTPC <= maxTPC) && (posnsTPC2 <= maxTPC2)) ) {
463 AliDebugClass(2, "Failed check on V0 PID");
464 return kFALSE;
465 }
3da8cef7 466 }
e37e90f9 467
468 //---------------------------------------------------------------
8082e538 469 // if we reach this point, all checks were successful
e37e90f9 470 AliDebugClass(1, "Good AOD V0");
76d89202 471 AliDebugClass(1, Form("Mass: %d %f %f %d %d", fHypothesis, fMass, mass, filtermapP, filtermapN));
e6952ec7 472 return kTRUE;
61f275d1 473
8082e538 474}
475
476//_________________________________________________________________________________________________
477void AliRsnCutV0::Print(const Option_t *) const
478{
479//
480// Print information on this cut
481//
482}