1 /*************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: A.Abrahantes, E.Lopez, S.Vallero *
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 **************************************************************************/
18 #include <TObjArray.h>
22 #include "AliAnalyseLeadingTrackUE.h"
24 #include "AliAODEvent.h"
25 #include "AliAODMCParticle.h"
26 #include "AliAODTrack.h"
27 #include "AliESDEvent.h"
28 #include "AliESDtrack.h"
29 #include "AliESDtrackCuts.h"
30 #include "AliInputEventHandler.h"
31 #include "AliMCEvent.h"
32 #include "AliVParticle.h"
33 #include "AliAODMCHeader.h"
36 #include "AliAnalysisManager.h"
37 #include "AliMCEventHandler.h"
39 #include "AliPIDResponse.h"
40 #include "AliHelperPID.h"
43 ////////////////////////////////////////////////
44 //---------------------------------------------
45 // Class for transverse regions analysis
46 //---------------------------------------------
47 ////////////////////////////////////////////////
52 ClassImp(AliAnalyseLeadingTrackUE)
54 //-------------------------------------------------------------------
55 AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
61 fCheckMotherPDG(kTRUE),
65 fEventSelection(AliVEvent::kMB|AliVEvent::kUserDefined),
67 fSharedClusterCut(-1),
69 fEsdTrackCutsExtra1(0x0),
70 fEsdTrackCutsExtra2(0x0),
78 //-------------------------------------------------------------------
79 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
81 // assignment operator
86 //-------------------------------------------------------------------
87 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
95 //____________________________________________________________________
96 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
99 // select track according to set of cuts
100 if (!fEsdTrackCuts->IsSelected(track) )return kFALSE;
101 if (fEsdTrackCutsExtra1 && fEsdTrackCutsExtra2 && !fEsdTrackCutsExtra1->IsSelected(track) && !fEsdTrackCutsExtra2->IsSelected(track)) return kFALSE;
107 //____________________________________________________________________
108 void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t filterbit) {
110 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
111 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
114 filterbit = fFilterBit;
116 if (filterbit == 128)
118 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
119 fEsdTrackCuts->SetMinNClustersTPC(70);
121 else if (filterbit == 256)
124 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
125 fEsdTrackCuts->SetMinNClustersTPC(80);
126 fEsdTrackCuts->SetMaxChi2PerClusterTPC(3);
127 fEsdTrackCuts->SetMaxDCAToVertexZ(2.7);
128 fEsdTrackCuts->SetMaxDCAToVertexXY(1.9);
130 else if (filterbit == 512)
133 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
134 fEsdTrackCuts->SetMinNClustersTPC(60);
135 fEsdTrackCuts->SetMaxChi2PerClusterTPC(5);
136 fEsdTrackCuts->SetMaxDCAToVertexZ(3.7);
137 fEsdTrackCuts->SetMaxDCAToVertexXY(2.9);
139 else if (filterbit == 1024)
141 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
142 fEsdTrackCuts->SetMinNClustersTPC(-1);
143 fEsdTrackCuts->SetMinNCrossedRowsTPC(70);
144 fEsdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
146 else if (filterbit == 2048) // mimic hybrid tracks
148 // correspond to esdTrackCutsHTG, but WITHOUT spd constraint. this is checked with the next object
149 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE);
150 fEsdTrackCuts->SetName("Global Hybrid tracks, loose DCA");
151 fEsdTrackCuts->SetMaxDCAToVertexXY(2.4);
152 fEsdTrackCuts->SetMaxDCAToVertexZ(3.2);
153 fEsdTrackCuts->SetDCAToVertex2D(kTRUE);
154 fEsdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
155 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
157 // Add SPD requirement
158 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
159 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
160 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra1 corresponds to esdTrackCutsHTG
162 fEsdTrackCutsExtra2 = new AliESDtrackCuts("No_SPD", "Reject tracks with cluster in SPD");
163 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kNone);
164 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra2 corresponds to esdTrackCutsHTGC and needs to be constrained
166 else if (filterbit == 4096) // require TOF matching
168 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE);
169 // FIXME: TOF REQUIREMENTS ARE IN GetParticleSpecies FOR THE MOMENT
173 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
174 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
176 // Add SPD requirement
177 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
178 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
180 // Add SDD requirement
181 fEsdTrackCutsExtra2 = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
182 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
186 //____________________________________________________________________
187 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
190 // Returns an array of charged particles (or jets) ordered according to their pT.
192 Int_t nTracks = NParticles(obj);
195 if( !nTracks ) return 0;
197 // Define array of AliVParticle objects
198 TObjArray* tracks = new TObjArray(nTracks);
200 // Loop over tracks or jets
201 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
202 AliVParticle* part = ParticleWithCuts( obj, ipart );
204 // Accept leading-tracks in a limited pseudo-rapidity range
205 if( TMath::Abs(part->Eta()) > fTrackEtaCut || TMath::Abs(part->Eta()) < fTrackEtaCutMin ) continue;
206 tracks->AddLast( part );
208 // Order tracks by pT
209 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
211 nTracks = tracks->GetEntriesFast();
212 if( !nTracks ) return 0;
218 void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject* mcObj, Int_t maxLabel)
220 // remove injected signals (primaries above <maxLabel>)
221 // <tracks> can be the following cases:
222 // a. tracks: in this case the label is taken and then case b.
223 // b. particles: the first stable mother is searched and checked if it is <= <maxLabel>
224 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
226 TClonesArray* arrayMC = 0;
227 AliMCEvent* mcEvent = 0;
228 if (mcObj->InheritsFrom("AliMCEvent"))
229 mcEvent = static_cast<AliMCEvent*>(mcObj);
230 else if (mcObj->InheritsFrom("TClonesArray"))
231 arrayMC = static_cast<TClonesArray*>(mcObj);
235 AliFatal("Invalid object passed");
238 Int_t before = tracks->GetEntriesFast();
240 for (Int_t i=0; i<before; ++i)
242 AliVParticle* part = (AliVParticle*) tracks->At(i);
244 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
245 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
247 AliVParticle* mother = part;
250 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
252 if (((AliMCParticle*)mother)->GetMother() < 0)
258 mother = (AliMCParticle*) mcEvent->GetTrack(((AliMCParticle*)mother)->GetMother());
265 // find the primary mother
266 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
268 if (((AliAODMCParticle*)mother)->GetMother() < 0)
274 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
282 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
286 // Printf("%d %d %d", i, part->GetLabel(), mother->GetLabel());
287 if (mother->GetLabel() >= maxLabel)
289 // Printf("Removing %d with label %d", i, part->GetLabel()); ((AliMCParticle*)part)->Particle()->Print(); ((AliMCParticle*)mother)->Particle()->Print();
290 TObject* object = tracks->RemoveAt(i);
291 if (tracks->IsOwner())
298 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
301 //-------------------------------------------------------------------
302 void AliAnalyseLeadingTrackUE::RemoveWeakDecays(TObjArray* tracks, TObject* mcObj)
304 // remove particles from weak decays
305 // <tracks> can be the following cases:
306 // a. tracks: in this case the label is taken and then case b.
307 // b. particles: it is checked if IsSecondaryFromWeakDecay is true
308 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
310 TClonesArray* arrayMC = 0;
311 AliMCEvent* mcEvent = 0;
312 if (mcObj->InheritsFrom("AliMCEvent"))
313 mcEvent = static_cast<AliMCEvent*>(mcObj);
314 else if (mcObj->InheritsFrom("TClonesArray"))
315 arrayMC = static_cast<TClonesArray*>(mcObj);
319 AliFatal("Invalid object passed");
322 Int_t before = tracks->GetEntriesFast();
324 for (Int_t i=0; i<before; ++i)
326 AliVParticle* part = (AliVParticle*) tracks->At(i);
328 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
329 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
331 if (part->InheritsFrom("AliAODMCParticle"))
333 if (!((AliAODMCParticle*) part)->IsSecondaryFromWeakDecay())
336 else if (part->InheritsFrom("AliMCParticle") && mcEvent)
338 if (!(mcEvent->Stack()->IsSecondaryFromWeakDecay(part->GetLabel())))
344 AliFatal("Unknown particle");
347 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
348 TObject* object = tracks->RemoveAt(i);
349 if (tracks->IsOwner())
355 if (before > tracks->GetEntriesFast())
356 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
359 //-------------------------------------------------------------------
360 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts, Bool_t speciesOnTracks)
362 // Returns an array of particles that pass the cuts, if arrayMC is given each reconstructed particle is replaced by its corresponding MC particles, depending on the parameter onlyprimaries only for primaries
363 // particleSpecies: -1 all particles are returned
364 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
365 // speciesOnTracks if kFALSE, particleSpecies is only applied on the matched MC particle (not on the track itself)
367 Int_t nTracks = NParticles(obj);
368 TObjArray* tracks = new TObjArray;
370 // for TPC only tracks
371 Bool_t hasOwnership = kFALSE;
372 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
373 hasOwnership = kTRUE;
376 tracks->SetOwner(hasOwnership);
378 // Loop over tracks or jets
379 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
380 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, (speciesOnTracks) ? particleSpecies : -1);
384 if (TMath::Abs(part->Eta()) > fTrackEtaCut || TMath::Abs(part->Eta()) < fTrackEtaCutMin || part->Pt() < fTrackPtMin)
391 // Printf("%p %p %d Accepted %d %f %f %f", obj, arrayMC, particleSpecies, ipart, part->Eta(), part->Phi(), part->Pt());
394 Int_t label = part->GetLabel();
397 // re-define part as the matched MC particle
398 part = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
408 //-------------------------------------------------------------------
409 TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
411 // particleSpecies: -1 all particles are returned
412 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
414 Int_t nTracks = NParticles(obj);
415 TObjArray* tracksReconstructed = new TObjArray;
416 TObjArray* tracksOriginal = new TObjArray;
417 TObjArray* tracksFake = new TObjArray;
419 // for TPC only tracks
420 Bool_t hasOwnership = kFALSE;
421 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
422 hasOwnership = kTRUE;
424 tracksReconstructed->SetOwner(hasOwnership);
425 tracksFake->SetOwner(hasOwnership);
427 // Loop over tracks or jets
428 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
429 AliVParticle* partReconstructed = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
430 if (!partReconstructed) continue;
433 if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || TMath::Abs(partReconstructed->Eta()) < fTrackEtaCutMin || partReconstructed->Pt() < fTrackPtMin)
436 delete partReconstructed;
440 Int_t label = partReconstructed->GetLabel();
444 Printf(">>> TPC only track:");
445 partReconstructed->Print();
446 partReconstructed->Dump();
447 Printf(">>> Global track:");
448 ((AliESDEvent*) obj)->GetTrack(ipart)->Dump();
449 Printf("Fake (TPC only): eta = %f, phi = %f, pT = %f, ncl = %d, dedx = %f", partReconstructed->Eta(), partReconstructed->Phi(), partReconstructed->Pt(), ((AliESDtrack*) partReconstructed)->GetTPCclusters(0), ((AliESDtrack*) partReconstructed)->GetTPCsignal());
450 Printf("Fake (global ): eta = %f, phi = %f, pT = %f, ncl = %d, dedx = %f", ((AliESDEvent*) obj)->GetTrack(ipart)->Eta(), ((AliESDEvent*) obj)->GetTrack(ipart)->Phi(), ((AliESDEvent*) obj)->GetTrack(ipart)->Pt(), ((AliESDEvent*) obj)->GetTrack(ipart)->GetTPCclusters(0), ((AliESDEvent*) obj)->GetTrack(ipart)->GetTPCsignal());
452 tracksFake->AddLast(partReconstructed);
456 AliVParticle* partOriginal = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
460 delete partReconstructed;
464 tracksReconstructed->AddLast(partReconstructed);
465 tracksOriginal->AddLast(partOriginal);
467 TObjArray* pairs = new TObjArray;
468 pairs->SetOwner(kTRUE);
469 pairs->Add(tracksReconstructed);
470 pairs->Add(tracksOriginal);
471 pairs->Add(tracksFake);
475 //-------------------------------------------------------------------
476 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
479 // Returns two lists of particles, one for MIN and one for MAX region
480 Double_t sumpT1 = 0.;
481 Double_t sumpT2 = 0.;
483 Int_t particles1 = transv1->GetEntries();
484 Int_t particles2 = transv2->GetEntries();
486 // Loop on transverse region 1
487 for (Int_t i=0; i<particles1; i++){
488 AliVParticle *part = (AliVParticle*)transv1->At(i);
489 sumpT1 += part->Pt();
492 // Loop on transverse region 2
493 for (Int_t i=0; i<particles2; i++){
494 AliVParticle *part = (AliVParticle*)transv2->At(i);
495 sumpT2 += part->Pt();
498 TObjArray *regionParticles = new TObjArray;
499 if ( sumpT2 >= sumpT1 ){
500 regionParticles->AddLast(transv1); // MIN
501 regionParticles->AddLast(transv2); // MAX
503 regionParticles->AddLast(transv2); // MIN
504 regionParticles->AddLast(transv1); // MAX
507 return regionParticles;
510 //-------------------------------------------------------------------
511 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
514 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
518 if (obj->InheritsFrom("TClonesArray")){ // MC particles
519 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
520 nTracks = arrayMC->GetEntriesFast();
521 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
522 TObjArray *array = static_cast<TObjArray*>(obj);
523 nTracks = array->GetEntriesFast();
524 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
525 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
526 nTracks = aodEvent->GetNTracks();
527 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
528 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
529 nTracks = esdEvent->GetNumberOfTracks();
530 }else if (obj->InheritsFrom("AliMCEvent")){ // RECO ESD tracks
531 AliMCEvent *mcEvent = static_cast<AliMCEvent*>(obj);
532 nTracks = mcEvent->GetNumberOfTracks();
534 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
541 //-------------------------------------------------------------------
542 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
544 // Returns track or MC particle at position "ipart" if passes selection criteria
545 // particleSpecies: -1 all particles are returned
546 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
547 AliVParticle *part=0;
549 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
550 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
551 part = (AliVParticle*)arrayMC->At( ipart );
553 // eventually only primaries
554 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
555 // eventually only hadrons
557 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
558 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
559 TMath::Abs(pdgCode)==2212 || // Proton
560 TMath::Abs(pdgCode)==321; // Kaon
561 if (!isHadron) return 0;
563 if (particleSpecies != -1) {
564 // find the primary mother
565 AliVParticle* mother = part;
566 if(fCheckMotherPDG) {
567 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
569 if (((AliAODMCParticle*)mother)->GetMother() < 0)
575 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
582 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
583 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
585 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
587 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
589 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
594 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
595 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
599 // this code prints the details of the mother that is missing in the AOD
600 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
602 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
604 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
605 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
606 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
609 if (particleSpecies != 3)
614 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
615 TObjArray *array = static_cast<TObjArray*>(obj);
616 part = (AliVParticle*)array->At( ipart );
618 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
619 AliMCEvent* mcEvent = static_cast<AliMCEvent*>(obj);
620 part = mcEvent->GetTrack( ipart );
622 // eventually only primaries
623 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
624 // eventually only hadrons
627 Int_t pdgCode = part->GetPdgCode();
628 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
629 TMath::Abs(pdgCode)==2212 || // Proton
630 TMath::Abs(pdgCode)==321; // Kaon
631 if (!isHadron) return 0;
634 if (particleSpecies != -1) {
635 // find the primary mother
636 AliMCParticle* mother = (AliMCParticle*) part;
638 if(fCheckMotherPDG) {
639 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
641 // Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
642 if (mother->GetMother() < 0)
648 mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
655 Int_t pdgCode = mother->PdgCode();
656 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
658 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
660 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
662 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
667 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
668 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
673 // this code prints the details of the mother that is missing in the AOD
674 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
676 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
678 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
679 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
680 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
683 if (particleSpecies != 3)
687 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
688 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
689 part = aodEvent->GetTrack(ipart);
691 // track selection cuts
692 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
693 if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
698 const AliVVertex* vertex = aodEvent->GetPrimaryVertex();
704 AliAODTrack* clone = (AliAODTrack*) part->Clone();
705 Bool_t success = clone->PropagateToDCA(vertex, aodEvent->GetHeader()->GetMagneticField(), 3, pos, covar);
710 // Printf("%f", ((AliAODTrack*)part)->DCA());
711 // Printf("%f", pos[0]);
712 if (TMath::Abs(pos[0]) > fDCAXYCut->Eval(part->Pt()))
716 if (fSharedClusterCut >= 0)
718 Double_t frac = Double_t(((AliAODTrack*)part)->GetTPCnclsS()) / Double_t(((AliAODTrack*)part)->GetTPCncls());
719 if (frac > fSharedClusterCut)
723 // eventually only hadrons
725 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
726 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
727 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
728 if (!isHadron) return 0;
731 if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0;
733 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
734 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
735 part = esdEvent->GetTrack(ipart);
738 // track selection cuts
739 if (!( ApplyCuts(part)) )
742 if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
744 if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
746 // create TPC only tracks constrained to the SPD vertex
748 const AliESDVertex *vtxSPD = esdEvent->GetPrimaryVertexSPD();
750 AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
753 // Printf(">%f %f %f", track->Eta(), track->Phi(), track->Pt());
756 // only constrain tracks above threshold
757 AliExternalTrackParam exParam;
758 // take the B-feild from the ESD, no 3D fieldMap available at this point
759 Bool_t relate = kFALSE;
760 relate = track->RelateToVertexTPC(vtxSPD,esdEvent->GetMagneticField(),kVeryBig,&exParam);
763 // Printf("relating failed");
767 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
770 // Printf(">%f %f %f\n", track->Eta(), track->Phi(), track->Pt());
774 else if (fFilterBit == 2048)
779 AliESDtrack* esdTrack = new AliESDtrack(*((AliESDtrack*) part));
780 // Printf("%d %d %d %d %d", fEsdTrackCuts->IsSelected(esdTrack), fEsdTrackCutsExtra1->IsSelected(esdTrack), fEsdTrackCutsExtra2->IsSelected(esdTrack), esdTrack->HasPointOnITSLayer(0), esdTrack->HasPointOnITSLayer(1));
782 if (fEsdTrackCutsExtra2->IsSelected(esdTrack))
784 // Float_t ptBefore = esdTrack->Pt();
785 // set constrained pT as default pT
786 if (!esdTrack->GetConstrainedParam())
788 esdTrack->CopyFromVTrack(esdTrack->GetConstrainedParam());
789 // Printf("%f %f", ptBefore, esdTrack->Pt());
794 // eventually only hadrons
797 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
798 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
799 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
800 if (!isHadron) return 0;
803 if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0; // If it is -1 you take all the particles
806 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
811 if (!part->Charge())return 0;
813 part->SetUniqueID(fEventCounter * 100000 + ipart);
818 //-------------------------------------------------------------------
819 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
821 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
824 static int i; // "static" to save stack space
827 while (last - first > 1) {
831 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
833 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
849 if (j - first < last - (j + 1)) {
850 QSortTracks(a, first, j);
851 first = j + 1; // QSortTracks(j + 1, last);
853 QSortTracks(a, j + 1, last);
854 last = j; // QSortTracks(first, j);
859 //____________________________________________________________________
860 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
863 // Assign particles to towards, away or transverse regions.
864 // Returns a lists of particles for each region.
866 static const Double_t k60rad = 60.*TMath::Pi()/180.;
867 static const Double_t k120rad = 120.*TMath::Pi()/180.;
869 // Define output lists of particles
870 TList *toward = new TList();
871 TList *away = new TList();
872 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
873 // MIN and MAX can be sorted in GetMinMaxRegion function
874 TList *transverse1 = new TList();
875 TList *transverse2 = new TList();
877 TObjArray *regionParticles = new TObjArray;
878 regionParticles->SetOwner(kTRUE);
880 regionParticles->AddLast(toward);
881 regionParticles->AddLast(away);
882 regionParticles->AddLast(transverse1);
883 regionParticles->AddLast(transverse2);
886 return regionParticles;
888 // Switch to vector for leading particle
889 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
891 Int_t nTracks = NParticles(obj);
892 if( !nTracks ) return 0;
894 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
895 AliVParticle* part = ParticleWithCuts(obj, ipart);
897 //Switch to vectors for particles
898 TVector3 partVect(part->Px(), part->Py(), part->Pz());
901 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut || TMath::Abs(partVect.Eta()) < fTrackEtaCutMin) continue;
902 // transverse regions
903 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
904 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
906 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
907 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
909 // skip leading particle
913 if (!region)continue;
914 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
915 Int_t label = ((AliAODTrack*)part)->GetLabel();
916 // re-define part as the matched MC particle
917 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
919 // skip leading particle
923 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
924 Int_t label = ((AliESDtrack*)part)->GetLabel();
925 // look for the matched MC particle (but do not re-define part)
926 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
929 if ( region == 1 ) transverse1->Add(part);
930 if ( region == -1 ) transverse2->Add(part);
931 if ( region == 2 ) toward->Add(part);
932 if ( region == -2 ) away->Add(part);
934 }//end loop on tracks
936 return regionParticles;
941 //____________________________________________________________________
942 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
947 // Use AliPhysicsSelection to select good events, works for ESD and AOD
948 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&(fEventSelection)))
954 //____________________________________________________________________
955 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
958 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
960 if (obj->InheritsFrom("AliAODEvent")){
961 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
963 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
964 Int_t nTracksPrim = vertex->GetNContributors();
965 Double_t zVertex = vertex->GetZ();
966 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
967 // Reject TPC only vertex
968 TString name(vertex->GetName());
969 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
971 // Select a quality vertex by number of tracks?
972 if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
973 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
976 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
977 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
979 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
981 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
986 if (obj->InheritsFrom("AliMCEvent"))
988 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) >= zed)
990 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
995 if (obj->InheritsFrom("AliAODMCHeader"))
997 if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) >= zed)
999 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
1004 // ESD case for DCA studies
1005 if (obj->InheritsFrom("AliESDEvent")){
1006 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
1008 Int_t nTracksPrim = vertex->GetNContributors();
1009 Double_t zVertex = vertex->GetZ();
1010 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
1011 // Reject SPD or TPC only vertex
1012 TString name(vertex->GetName());
1013 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
1015 // Select a quality vertex by number of tracks?
1016 if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
1017 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1020 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
1021 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
1023 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
1025 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1033 //____________________________________________________________________
1035 Bool_t AliAnalyseLeadingTrackUE::CheckTrack(AliVParticle * part)
1037 // check if the track status flags are set
1039 UInt_t status=((AliVTrack*)part)->GetStatus();
1040 if ((status & fTrackStatus) == fTrackStatus)