1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
19 // ESD track cuts for flow framework
21 // origin: Mikolaj Krzewicki (mikolaj.krzewicki@cern.ch)
23 // This class gurantees consistency of cut methods, trackparameter
24 // selection (global tracks, TPC only, etc..) and parameter mixing
25 // in the flow framework. Transparently handles different input types:
27 // This class works in 2 steps: first the requested track parameters are
28 // constructed (to be set by SetParamType() ), then cuts are applied.
29 // the constructed track can be requested AFTER checking the cuts by
30 // calling GetTrack(), in this case the cut object stays in control,
31 // caller does not have to delete the track.
32 // Additionally caller can request an AliFlowTrack object to be constructed
33 // according the parameter mixing scenario requested by SetParamMix().
34 // AliFlowTrack is made using MakeFlowTrack() method, its an 'object factory'
35 // so caller needs to take care of the freshly created object.
39 #include "TParticle.h"
40 #include "TObjArray.h"
42 #include "AliMCEvent.h"
43 #include "AliESDEvent.h"
44 #include "AliVParticle.h"
45 #include "AliMCParticle.h"
46 #include "AliESDtrack.h"
47 #include "AliMultiplicity.h"
48 #include "AliAODTrack.h"
49 #include "AliFlowTrack.h"
50 #include "AliFlowTrackCuts.h"
53 ClassImp(AliFlowTrackCuts)
55 //-----------------------------------------------------------------------
56 AliFlowTrackCuts::AliFlowTrackCuts():
57 AliFlowTrackSimpleCuts(),
58 fAliESDtrackCuts(new AliESDtrackCuts()),
61 fCutMCprocessType(kFALSE),
62 fMCprocessType(kPNoProcess),
65 fIgnoreSignInPID(kFALSE),
66 fCutMCisPrimary(kFALSE),
68 fRequireCharge(kFALSE),
70 fCutSPDtrackletDeltaPhi(kFALSE),
71 fSPDtrackletDeltaPhiMax(FLT_MAX),
72 fSPDtrackletDeltaPhiMin(-FLT_MAX),
73 fIgnoreTPCzRange(kFALSE),
74 fIgnoreTPCzRangeMax(FLT_MAX),
75 fIgnoreTPCzRangeMin(-FLT_MAX),
76 fCutChi2PerClusterTPC(kFALSE),
77 fMaxChi2PerClusterTPC(FLT_MAX),
78 fMinChi2PerClusterTPC(-FLT_MAX),
94 //-----------------------------------------------------------------------
95 AliFlowTrackCuts::AliFlowTrackCuts(const AliFlowTrackCuts& that):
96 AliFlowTrackSimpleCuts(that),
97 fAliESDtrackCuts(new AliESDtrackCuts(*(that.fAliESDtrackCuts))),
100 fCutMCprocessType(that.fCutMCprocessType),
101 fMCprocessType(that.fMCprocessType),
102 fCutMCPID(that.fCutMCPID),
104 fIgnoreSignInPID(that.fIgnoreSignInPID),
105 fCutMCisPrimary(that.fCutMCisPrimary),
106 fMCisPrimary(that.fMCisPrimary),
107 fRequireCharge(that.fRequireCharge),
108 fFakesAreOK(that.fFakesAreOK),
109 fCutSPDtrackletDeltaPhi(that.fCutSPDtrackletDeltaPhi),
110 fSPDtrackletDeltaPhiMax(that.fSPDtrackletDeltaPhiMax),
111 fSPDtrackletDeltaPhiMin(that.fSPDtrackletDeltaPhiMin),
112 fIgnoreTPCzRange(that.fIgnoreTPCzRange),
113 fIgnoreTPCzRangeMax(that.fIgnoreTPCzRangeMax),
114 fIgnoreTPCzRangeMin(that.fIgnoreTPCzRangeMin),
115 fCutChi2PerClusterTPC(that.fCutChi2PerClusterTPC),
116 fMaxChi2PerClusterTPC(that.fMaxChi2PerClusterTPC),
117 fMinChi2PerClusterTPC(that.fMinChi2PerClusterTPC),
118 fParamType(that.fParamType),
119 fParamMix(that.fParamMix),
124 fTrackLabel(INT_MIN),
133 //-----------------------------------------------------------------------
134 AliFlowTrackCuts& AliFlowTrackCuts::operator=(const AliFlowTrackCuts& that)
137 AliFlowTrackSimpleCuts::operator=(that);
138 *fAliESDtrackCuts=*(that.fAliESDtrackCuts);
141 fCutMCprocessType=that.fCutMCprocessType;
142 fMCprocessType=that.fMCprocessType;
143 fCutMCPID=that.fCutMCPID;
145 fIgnoreSignInPID=that.fIgnoreSignInPID,
146 fCutMCisPrimary=that.fCutMCisPrimary;
147 fMCisPrimary=that.fMCisPrimary;
148 fRequireCharge=that.fRequireCharge;
149 fFakesAreOK=that.fFakesAreOK;
150 fCutSPDtrackletDeltaPhi=that.fCutSPDtrackletDeltaPhi;
151 fSPDtrackletDeltaPhiMax=that.fSPDtrackletDeltaPhiMax;
152 fSPDtrackletDeltaPhiMin=that.fSPDtrackletDeltaPhiMin;
153 fIgnoreTPCzRange=that.fIgnoreTPCzRange;
154 fIgnoreTPCzRangeMax=that.fIgnoreTPCzRangeMax;
155 fIgnoreTPCzRangeMin=that.fIgnoreTPCzRangeMin;
156 fCutChi2PerClusterTPC=that.fCutChi2PerClusterTPC;
157 fMaxChi2PerClusterTPC=that.fMaxChi2PerClusterTPC;
158 fMinChi2PerClusterTPC=that.fMinChi2PerClusterTPC;
159 fParamType=that.fParamType;
160 fParamMix=that.fParamMix;
174 //-----------------------------------------------------------------------
175 AliFlowTrackCuts::~AliFlowTrackCuts()
178 delete fAliESDtrackCuts;
181 //-----------------------------------------------------------------------
182 Bool_t AliFlowTrackCuts::IsSelected(TObject* obj, Int_t id)
185 AliVParticle* vparticle = dynamic_cast<AliVParticle*>(obj);
186 if (vparticle) return PassesCuts(vparticle);
187 AliFlowTrackSimple* flowtrack = dynamic_cast<AliFlowTrackSimple*>(obj);
188 if (flowtrack) return PassesCuts(flowtrack);
189 AliMultiplicity* tracklets = dynamic_cast<AliMultiplicity*>(obj);
190 if (tracklets) return PassesCuts(tracklets,id);
191 return kFALSE; //default when passed wrong type of object
194 //-----------------------------------------------------------------------
195 Bool_t AliFlowTrackCuts::IsSelectedMCtruth(TObject* obj, Int_t id)
198 AliVParticle* vparticle = dynamic_cast<AliVParticle*>(obj);
201 return PassesMCcuts(fMCevent,vparticle->GetLabel());
203 AliMultiplicity* tracklets = dynamic_cast<AliMultiplicity*>(obj);
206 Int_t label0 = tracklets->GetLabel(id,0);
207 Int_t label1 = tracklets->GetLabel(id,1);
208 Int_t label = (label0==label1)?tracklets->GetLabel(id,1):-666;
209 return PassesMCcuts(fMCevent,label);
211 return kFALSE; //default when passed wrong type of object
214 //-----------------------------------------------------------------------
215 Bool_t AliFlowTrackCuts::PassesCuts(AliFlowTrackSimple* track)
217 //check cuts on a flowtracksimple
219 //clean up from last iteration
221 return AliFlowTrackSimpleCuts::PassesCuts(track);
224 //-----------------------------------------------------------------------
225 Bool_t AliFlowTrackCuts::PassesCuts(AliMultiplicity* tracklet, Int_t id)
227 //check cuts on a tracklets
229 //clean up from last iteration, and init label
234 fTrackPhi = tracklet->GetPhi(id);
235 fTrackEta = tracklet->GetEta(id);
237 if (fCutEta) {if ( fTrackEta < fEtaMin || fTrackEta >= fEtaMax ) return kFALSE;}
238 if (fCutPhi) {if ( fTrackPhi < fPhiMin || fTrackPhi >= fPhiMax ) return kFALSE;}
240 //check MC info if available
241 //if the 2 clusters have different label track cannot be good
242 //and should therefore not pass the mc cuts
243 Int_t label0 = tracklet->GetLabel(id,0);
244 Int_t label1 = tracklet->GetLabel(id,1);
245 //if possible get label and mcparticle
246 fTrackLabel = (label0==label1)?tracklet->GetLabel(id,1):-1;
247 if (fTrackLabel>=0 && fMCevent) fMCparticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(fTrackLabel));
249 if (fCutMC && !PassesMCcuts()) return kFALSE;
253 //-----------------------------------------------------------------------
254 Bool_t AliFlowTrackCuts::PassesMCcuts(AliMCEvent* mcEvent, Int_t label)
257 if (!mcEvent) return kFALSE;
258 if (label<0) return kFALSE;//otherwise AliCMevent prints a warning before returning NULL
259 AliMCParticle* mcparticle = static_cast<AliMCParticle*>(mcEvent->GetTrack(label));
260 if (!mcparticle) {AliError("no MC track"); return kFALSE;}
264 if (IsPhysicalPrimary(mcEvent,label) != fMCisPrimary) return kFALSE;
268 Int_t pdgCode = mcparticle->PdgCode();
269 if (fIgnoreSignInPID)
271 if (TMath::Abs(fMCPID) != TMath::Abs(pdgCode)) return kFALSE;
275 if (fMCPID != pdgCode) return kFALSE;
278 if ( fCutMCprocessType )
280 TParticle* particle = mcparticle->Particle();
281 Int_t processID = particle->GetUniqueID();
282 if (processID != fMCprocessType ) return kFALSE;
286 //-----------------------------------------------------------------------
287 Bool_t AliFlowTrackCuts::PassesMCcuts()
289 if (!fMCevent) return kFALSE;
290 if (fTrackLabel<0) return kFALSE;//otherwise AliCMevent prints a warning before returning NULL
291 fMCparticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(fTrackLabel));
292 return PassesMCcuts(fMCevent,fTrackLabel);
295 //-----------------------------------------------------------------------
296 Bool_t AliFlowTrackCuts::PassesCuts(AliVParticle* vparticle)
298 //check cuts for an ESD vparticle
300 ////////////////////////////////////////////////////////////////
301 // start by preparing the track parameters to cut on //////////
302 ////////////////////////////////////////////////////////////////
303 //clean up from last iteration
306 //get the label and the mc particle
307 fTrackLabel = (fFakesAreOK)?TMath::Abs(vparticle->GetLabel()):vparticle->GetLabel();
308 if (fMCevent) fMCparticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(fTrackLabel));
309 else fMCparticle=NULL;
311 Bool_t isMCparticle = kFALSE; //some things are different for MC particles, check!
312 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*>(vparticle);
314 HandleESDtrack(esdTrack);
317 HandleVParticle(vparticle);
318 //now check if produced particle is MC
319 isMCparticle = (dynamic_cast<AliMCParticle*>(fTrack))!=NULL;
321 ////////////////////////////////////////////////////////////////
322 ////////////////////////////////////////////////////////////////
324 if (!fTrack) return kFALSE;
327 //check the common cuts for the current particle fTrack (MC,AOD,ESD)
328 if (fCutPt) {if (fTrack->Pt() < fPtMin || fTrack->Pt() >= fPtMax ) pass=kFALSE;}
329 if (fCutEta) {if (fTrack->Eta() < fEtaMin || fTrack->Eta() >= fEtaMax ) pass=kFALSE;}
330 if (fCutPhi) {if (fTrack->Phi() < fPhiMin || fTrack->Phi() >= fPhiMax ) pass=kFALSE;}
331 if (fRequireCharge) {if (fTrack->Charge() == 0) pass=kFALSE;}
332 if (fCutCharge && !isMCparticle) {if (fTrack->Charge() != fCharge) pass=kFALSE;}
333 if (fCutCharge && isMCparticle)
335 //in case of an MC particle the charge is stored in units of 1/3|e|
336 Int_t charge = TMath::Nint(fTrack->Charge()/3.0); //mc particles have charge in units of 1/3e
337 return (charge==fCharge);
339 //if(fCutPID) {if (fTrack->PID() != fPID) pass=kFALSE;}
341 //when additionally MC info is required
342 if (fCutMC && !PassesMCcuts()) pass=kFALSE;
344 //check all else for ESDs using aliesdtrackcuts
345 if (esdTrack && (fParamType!=kMC) )
347 if (fIgnoreTPCzRange)
349 const AliExternalTrackParam* pin = esdTrack->GetOuterParam();
350 const AliExternalTrackParam* pout = esdTrack->GetInnerParam();
353 Double_t zin = pin->GetZ();
354 Double_t zout = pout->GetZ();
355 if (zin*zout<0) pass=kFALSE; //reject if cross the membrane
356 if (zin < fIgnoreTPCzRangeMin || zin > fIgnoreTPCzRangeMax) pass=kFALSE;
357 if (zout < fIgnoreTPCzRangeMin || zout > fIgnoreTPCzRangeMax) pass=kFALSE;
360 if (!fAliESDtrackCuts->IsSelected(static_cast<AliESDtrack*>(fTrack))) pass=kFALSE;
361 if (fCutChi2PerClusterTPC)
363 Float_t tpcchi2 = (fParamType==kESD_TPConly)?
364 esdTrack->GetTPCchi2Iter1():esdTrack->GetTPCchi2();
365 Int_t ntpccls = esdTrack->GetTPCNcls();
366 tpcchi2 = (ntpccls>0)?tpcchi2/ntpccls:-FLT_MAX;
367 if (tpcchi2<fMinChi2PerClusterTPC || tpcchi2 >=fMaxChi2PerClusterTPC)
372 return pass; //true by default, if we didn't set any cuts
375 //-----------------------------------------------------------------------
376 void AliFlowTrackCuts::HandleVParticle(AliVParticle* track)
378 //handle the general case
386 //-----------------------------------------------------------------------
387 void AliFlowTrackCuts::HandleESDtrack(AliESDtrack* track)
396 if (!track->FillTPCOnlyTrack(fTPCtrack))
404 //recalculate the label and mc particle, they may differ as TPClabel != global label
405 fTrackLabel = (fFakesAreOK)?TMath::Abs(fTrack->GetLabel()):fTrack->GetLabel();
406 if (fMCevent) fMCparticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(fTrackLabel));
407 else fMCparticle=NULL;
414 //-----------------------------------------------------------------------
415 AliFlowTrackCuts* AliFlowTrackCuts::GetStandardTPCOnlyTrackCuts()
418 AliFlowTrackCuts* cuts = new AliFlowTrackCuts();
419 cuts->SetName("standard TPConly cuts");
420 delete cuts->fAliESDtrackCuts;
421 cuts->fAliESDtrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
422 cuts->SetParamType(kESD_TPConly);
426 //-----------------------------------------------------------------------
427 AliFlowTrackCuts* AliFlowTrackCuts::GetStandardITSTPCTrackCuts2009(Bool_t selPrimaries)
430 AliFlowTrackCuts* cuts = new AliFlowTrackCuts();
431 cuts->SetName("standard global track cuts 2009");
432 delete cuts->fAliESDtrackCuts;
433 cuts->fAliESDtrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2009(selPrimaries);
434 cuts->SetParamType(kGlobal);
438 //-----------------------------------------------------------------------
439 AliFlowTrack* AliFlowTrackCuts::MakeFlowTrack() const
441 //get a flow track constructed from whatever we applied cuts on
442 //caller is resposible for deletion
443 //if construction fails return NULL
444 AliFlowTrack* flowtrack=NULL;
445 TParticle *tmpTParticle=NULL;
446 AliMCParticle* tmpAliMCParticle=NULL;
447 if (fParamType==kESD_SPDtracklet)
452 flowtrack = new AliFlowTrack();
453 flowtrack->SetPhi(fTrackPhi);
454 flowtrack->SetEta(fTrackEta);
456 case kTrackWithMCkine:
457 if (!fMCparticle) return NULL;
458 flowtrack = new AliFlowTrack();
459 flowtrack->SetPhi( fMCparticle->Phi() );
460 flowtrack->SetEta( fMCparticle->Eta() );
461 flowtrack->SetPt( fMCparticle->Pt() );
464 if (!fMCparticle) return NULL;
465 flowtrack = new AliFlowTrack();
466 flowtrack->SetPhi(fTrackPhi);
467 flowtrack->SetEta(fTrackEta);
468 flowtrack->SetPt(fMCparticle->Pt());
470 case kTrackWithPtFromFirstMother:
471 if (!fMCparticle) return NULL;
472 flowtrack = new AliFlowTrack();
473 flowtrack->SetPhi(fTrackPhi);
474 flowtrack->SetEta(fTrackEta);
475 tmpTParticle = fMCparticle->Particle();
476 tmpAliMCParticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(tmpTParticle->GetFirstMother()));
477 flowtrack->SetPt(tmpAliMCParticle->Pt());
479 flowtrack = new AliFlowTrack();
480 flowtrack->SetPhi(fTrackPhi);
481 flowtrack->SetEta(fTrackEta);
483 flowtrack->SetSource(AliFlowTrack::kFromTracklet);
487 if (!fTrack) return NULL;
491 flowtrack = new AliFlowTrack(fTrack);
493 case kTrackWithMCkine:
494 flowtrack = new AliFlowTrack(fMCparticle);
496 case kTrackWithMCPID:
497 flowtrack = new AliFlowTrack(fTrack);
498 //flowtrack->setPID(...) from mc, when implemented
501 if (!fMCparticle) return NULL;
502 flowtrack = new AliFlowTrack(fTrack);
503 flowtrack->SetPt(fMCparticle->Pt());
504 case kTrackWithPtFromFirstMother:
505 if (!fMCparticle) return NULL;
506 flowtrack = new AliFlowTrack(fTrack);
507 tmpTParticle = fMCparticle->Particle();
508 tmpAliMCParticle = static_cast<AliMCParticle*>(fMCevent->GetTrack(tmpTParticle->GetFirstMother()));
509 flowtrack->SetPt(tmpAliMCParticle->Pt());
511 flowtrack = new AliFlowTrack(fTrack);
513 if (fParamType==kMC) flowtrack->SetSource(AliFlowTrack::kFromMC);
514 else if (dynamic_cast<AliESDtrack*>(fTrack)) flowtrack->SetSource(AliFlowTrack::kFromESD);
515 else if (dynamic_cast<AliAODTrack*>(fTrack)) flowtrack->SetSource(AliFlowTrack::kFromAOD);
516 else if (dynamic_cast<AliMCParticle*>(fTrack)) flowtrack->SetSource(AliFlowTrack::kFromMC);
521 //-----------------------------------------------------------------------
522 Bool_t AliFlowTrackCuts::IsPhysicalPrimary() const
524 //check if current particle is a physical primary
525 if (!fMCevent) return kFALSE;
526 if (fTrackLabel<0) return kFALSE;
527 return IsPhysicalPrimary(fMCevent, fTrackLabel);
530 //-----------------------------------------------------------------------
531 Bool_t AliFlowTrackCuts::IsPhysicalPrimary(AliMCEvent* mcEvent, Int_t label)
533 //check if current particle is a physical primary
534 Bool_t physprim=mcEvent->IsPhysicalPrimary(label);
535 if (!physprim) return kFALSE;
536 AliMCParticle* track = static_cast<AliMCParticle*>(mcEvent->GetTrack(label));
537 if (!track) return kFALSE;
538 TParticle* particle = track->Particle();
539 Bool_t transported = particle->TestBit(kTransportBit);
540 //printf("prim: %s, transp: %s\n",(physprim)?"YES":"NO ",(transported)?"YES":"NO ");
541 return (physprim && transported);
544 //-----------------------------------------------------------------------
545 const char* AliFlowTrackCuts::GetParamTypeName(trackParameterType type)
547 //return the name of the selected parameter type
556 case kESD_SPDtracklet:
557 return "SPD tracklet";
564 //-----------------------------------------------------------------------
565 void AliFlowTrackCuts::DefineHistograms()
569 //-----------------------------------------------------------------------
570 Int_t AliFlowTrackCuts::GetNumberOfInputObjects() const
572 //get the number of tracks in the input event according source
573 //selection (ESD tracks, tracklets, MC particles etc.)
574 AliESDEvent* esd=NULL;
577 case kESD_SPDtracklet:
578 esd = dynamic_cast<AliESDEvent*>(fEvent);
580 return esd->GetMultiplicity()->GetNumberOfTracklets();
582 if (!fMCevent) return 0;
583 return fMCevent->GetNumberOfTracks();
585 if (!fEvent) return 0;
586 return fEvent->GetNumberOfTracks();
591 //-----------------------------------------------------------------------
592 TObject* AliFlowTrackCuts::GetInputObject(Int_t i)
594 //get the input object according the data source selection:
595 //(esd tracks, traclets, mc particles,etc...)
596 AliESDEvent* esd=NULL;
599 case kESD_SPDtracklet:
600 esd = dynamic_cast<AliESDEvent*>(fEvent);
601 if (!esd) return NULL;
602 return const_cast<AliMultiplicity*>(esd->GetMultiplicity());
604 if (!fMCevent) return NULL;
605 return fMCevent->GetTrack(i);
607 if (!fEvent) return NULL;
608 return fEvent->GetTrack(i);
612 //-----------------------------------------------------------------------
613 void AliFlowTrackCuts::Clear(Option_t*)