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 **************************************************************************/
15 //#include <TBranch.h>
16 //#include <TCanvas.h>
23 //#include <TLorentzVector.h>
25 #include <TObjArray.h>
27 //#include <TProfile.h>
28 //#include <TRandom.h>
29 //#include <TSystem.h>
33 #include "AliAnalyseLeadingTrackUE.h"
34 //#include "AliAnalysisTask.h"
36 //#include "AliAnalysisHelperJetTasks.h"
37 //#include "AliAnalysisManager.h"
38 #include "AliAODEvent.h"
39 //#include "AliAODHandler.h"
40 //#include "AliAODJet.h"
41 #include "AliAODMCParticle.h"
42 #include "AliAODTrack.h"
43 #include "AliESDEvent.h"
44 #include "AliESDtrack.h"
45 #include "AliESDtrackCuts.h"
46 //#include "AliGenPythiaEventHeader.h"
47 #include "AliInputEventHandler.h"
48 //#include "AliKFVertex.h"
50 #include "AliMCEvent.h"
51 #include "AliVParticle.h"
52 #include "AliAODMCHeader.h"
54 #include "AliAnalysisManager.h"
55 #include "AliMCEventHandler.h"
57 #include "AliPIDResponse.h"
58 #include "AliHelperPID.h"
61 ////////////////////////////////////////////////
62 //---------------------------------------------
63 // Class for transverse regions analysis
64 //---------------------------------------------
65 ////////////////////////////////////////////////
70 ClassImp(AliAnalyseLeadingTrackUE)
72 //-------------------------------------------------------------------
73 AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
79 fCheckMotherPDG(kTRUE),
82 fEventSelection(AliVEvent::kMB|AliVEvent::kUserDefined),
84 fEsdTrackCutsExtra1(0x0),
85 fEsdTrackCutsExtra2(0x0),
92 //-------------------------------------------------------------------
93 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
95 // assignment operator
100 //-------------------------------------------------------------------
101 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
109 //____________________________________________________________________
110 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
113 // select track according to set of cuts
114 if (!fEsdTrackCuts->IsSelected(track) )return kFALSE;
115 if (fEsdTrackCutsExtra1 && fEsdTrackCutsExtra2 && !fEsdTrackCutsExtra1->IsSelected(track) && !fEsdTrackCutsExtra2->IsSelected(track)) return kFALSE;
121 //____________________________________________________________________
122 void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t filterbit) {
124 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
125 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
128 filterbit = fFilterBit;
130 if (filterbit == 128)
132 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
133 fEsdTrackCuts->SetMinNClustersTPC(70);
135 else if (filterbit == 256)
138 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
139 fEsdTrackCuts->SetMinNClustersTPC(80);
140 fEsdTrackCuts->SetMaxChi2PerClusterTPC(3);
141 fEsdTrackCuts->SetMaxDCAToVertexZ(2.7);
142 fEsdTrackCuts->SetMaxDCAToVertexXY(1.9);
144 else if (filterbit == 512)
147 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
148 fEsdTrackCuts->SetMinNClustersTPC(60);
149 fEsdTrackCuts->SetMaxChi2PerClusterTPC(5);
150 fEsdTrackCuts->SetMaxDCAToVertexZ(3.7);
151 fEsdTrackCuts->SetMaxDCAToVertexXY(2.9);
153 else if (filterbit == 1024)
155 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
156 fEsdTrackCuts->SetMinNClustersTPC(-1);
157 fEsdTrackCuts->SetMinNCrossedRowsTPC(70);
158 fEsdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
160 else if (filterbit == 2048) // mimic hybrid tracks
162 // correspond to esdTrackCutsHTG, but WITHOUT spd constraint. this is checked with the next object
163 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE);
164 fEsdTrackCuts->SetName("Global Hybrid tracks, loose DCA");
165 fEsdTrackCuts->SetMaxDCAToVertexXY(2.4);
166 fEsdTrackCuts->SetMaxDCAToVertexZ(3.2);
167 fEsdTrackCuts->SetDCAToVertex2D(kTRUE);
168 fEsdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
169 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
171 // Add SPD requirement
172 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
173 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
174 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra1 corresponds to esdTrackCutsHTG
176 fEsdTrackCutsExtra2 = new AliESDtrackCuts("No_SPD", "Reject tracks with cluster in SPD");
177 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kNone);
178 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra2 corresponds to esdTrackCutsHTGC and needs to be constrained
180 else if (filterbit == 4096) // require TOF matching
182 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE);
183 // FIXME: TOF REQUIREMENTS ARE IN GetParticleSpecies FOR THE MOMENT
187 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
188 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
190 // Add SPD requirement
191 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
192 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
194 // Add SDD requirement
195 fEsdTrackCutsExtra2 = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
196 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
200 //____________________________________________________________________
201 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
204 // Returns an array of charged particles (or jets) ordered according to their pT.
206 Int_t nTracks = NParticles(obj);
209 if( !nTracks ) return 0;
211 // Define array of AliVParticle objects
212 TObjArray* tracks = new TObjArray(nTracks);
214 // Loop over tracks or jets
215 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
216 AliVParticle* part = ParticleWithCuts( obj, ipart );
218 // Accept leading-tracks in a limited pseudo-rapidity range
219 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
220 tracks->AddLast( part );
222 // Order tracks by pT
223 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
225 nTracks = tracks->GetEntriesFast();
226 if( !nTracks ) return 0;
232 void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject* mcObj, Int_t maxLabel)
234 // remove injected signals (primaries above <maxLabel>)
235 // <tracks> can be the following cases:
236 // a. tracks: in this case the label is taken and then case b.
237 // b. particles: the first stable mother is searched and checked if it is <= <maxLabel>
238 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
240 TClonesArray* arrayMC = 0;
241 AliMCEvent* mcEvent = 0;
242 if (mcObj->InheritsFrom("AliMCEvent"))
243 mcEvent = static_cast<AliMCEvent*>(mcObj);
244 else if (mcObj->InheritsFrom("TClonesArray"))
245 arrayMC = static_cast<TClonesArray*>(mcObj);
249 AliFatal("Invalid object passed");
252 Int_t before = tracks->GetEntriesFast();
254 for (Int_t i=0; i<before; ++i)
256 AliVParticle* part = (AliVParticle*) tracks->At(i);
258 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
259 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
261 AliVParticle* mother = part;
264 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
266 if (((AliMCParticle*)mother)->GetMother() < 0)
272 mother = (AliMCParticle*) mcEvent->GetTrack(((AliMCParticle*)mother)->GetMother());
279 // find the primary mother
280 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
282 if (((AliAODMCParticle*)mother)->GetMother() < 0)
288 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
296 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
300 if (mother->GetLabel() >= maxLabel)
302 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
303 TObject* object = tracks->RemoveAt(i);
304 if (tracks->IsOwner())
311 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
314 //-------------------------------------------------------------------
315 void AliAnalyseLeadingTrackUE::RemoveWeakDecays(TObjArray* tracks, TObject* mcObj)
317 // remove particles from weak decays
318 // <tracks> can be the following cases:
319 // a. tracks: in this case the label is taken and then case b.
320 // b. particles: it is checked if IsSecondaryFromWeakDecay is true
321 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
323 TClonesArray* arrayMC = 0;
324 AliMCEvent* mcEvent = 0;
325 if (mcObj->InheritsFrom("AliMCEvent"))
326 mcEvent = static_cast<AliMCEvent*>(mcObj);
327 else if (mcObj->InheritsFrom("TClonesArray"))
328 arrayMC = static_cast<TClonesArray*>(mcObj);
332 AliFatal("Invalid object passed");
335 Int_t before = tracks->GetEntriesFast();
337 for (Int_t i=0; i<before; ++i)
339 AliVParticle* part = (AliVParticle*) tracks->At(i);
341 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
342 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
344 if (part->InheritsFrom("AliAODMCParticle"))
346 if (!((AliAODMCParticle*) part)->IsSecondaryFromWeakDecay())
349 else if (part->InheritsFrom("AliMCParticle") && mcEvent)
351 if (!(mcEvent->Stack()->IsSecondaryFromWeakDecay(part->GetLabel())))
357 AliFatal("Unknown particle");
360 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
361 TObject* object = tracks->RemoveAt(i);
362 if (tracks->IsOwner())
368 if (before > tracks->GetEntriesFast())
369 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
372 //-------------------------------------------------------------------
373 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts, Bool_t speciesOnTracks)
375 // 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
376 // particleSpecies: -1 all particles are returned
377 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
378 // speciesOnTracks if kFALSE, particleSpecies is only applied on the matched MC particle (not on the track itself)
380 Int_t nTracks = NParticles(obj);
381 TObjArray* tracks = new TObjArray;
383 // for TPC only tracks
384 Bool_t hasOwnership = kFALSE;
385 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
386 hasOwnership = kTRUE;
389 tracks->SetOwner(hasOwnership);
391 // Loop over tracks or jets
392 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
393 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, (speciesOnTracks) ? particleSpecies : -1);
397 if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
405 Int_t label = part->GetLabel();
408 // re-define part as the matched MC particle
409 part = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
419 //-------------------------------------------------------------------
420 TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
422 // particleSpecies: -1 all particles are returned
423 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
425 Int_t nTracks = NParticles(obj);
426 TObjArray* tracksReconstructed = new TObjArray;
427 TObjArray* tracksOriginal = new TObjArray;
428 TObjArray* tracksFake = new TObjArray;
430 // for TPC only tracks
431 Bool_t hasOwnership = kFALSE;
432 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
433 hasOwnership = kTRUE;
435 tracksReconstructed->SetOwner(hasOwnership);
436 tracksFake->SetOwner(hasOwnership);
438 // Loop over tracks or jets
439 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
440 AliVParticle* partReconstructed = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
441 if (!partReconstructed) continue;
444 if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || partReconstructed->Pt() < fTrackPtMin)
447 delete partReconstructed;
451 Int_t label = partReconstructed->GetLabel();
455 Printf(">>> TPC only track:");
456 partReconstructed->Print();
457 partReconstructed->Dump();
458 Printf(">>> Global track:");
459 ((AliESDEvent*) obj)->GetTrack(ipart)->Dump();
460 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());
461 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());
463 tracksFake->AddLast(partReconstructed);
467 AliVParticle* partOriginal = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
471 delete partReconstructed;
475 tracksReconstructed->AddLast(partReconstructed);
476 tracksOriginal->AddLast(partOriginal);
478 TObjArray* pairs = new TObjArray;
479 pairs->SetOwner(kTRUE);
480 pairs->Add(tracksReconstructed);
481 pairs->Add(tracksOriginal);
482 pairs->Add(tracksFake);
486 //-------------------------------------------------------------------
487 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
490 // Returns two lists of particles, one for MIN and one for MAX region
491 Double_t sumpT1 = 0.;
492 Double_t sumpT2 = 0.;
494 Int_t particles1 = transv1->GetEntries();
495 Int_t particles2 = transv2->GetEntries();
497 // Loop on transverse region 1
498 for (Int_t i=0; i<particles1; i++){
499 AliVParticle *part = (AliVParticle*)transv1->At(i);
500 sumpT1 += part->Pt();
503 // Loop on transverse region 2
504 for (Int_t i=0; i<particles2; i++){
505 AliVParticle *part = (AliVParticle*)transv2->At(i);
506 sumpT2 += part->Pt();
509 TObjArray *regionParticles = new TObjArray;
510 if ( sumpT2 >= sumpT1 ){
511 regionParticles->AddLast(transv1); // MIN
512 regionParticles->AddLast(transv2); // MAX
514 regionParticles->AddLast(transv2); // MIN
515 regionParticles->AddLast(transv1); // MAX
518 return regionParticles;
521 //-------------------------------------------------------------------
522 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
525 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
529 if (obj->InheritsFrom("TClonesArray")){ // MC particles
530 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
531 nTracks = arrayMC->GetEntriesFast();
532 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
533 TObjArray *array = static_cast<TObjArray*>(obj);
534 nTracks = array->GetEntriesFast();
535 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
536 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
537 nTracks = aodEvent->GetNTracks();
538 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
539 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
540 nTracks = esdEvent->GetNumberOfTracks();
541 }else if (obj->InheritsFrom("AliMCEvent")){ // RECO ESD tracks
542 AliMCEvent *mcEvent = static_cast<AliMCEvent*>(obj);
543 nTracks = mcEvent->GetNumberOfTracks();
545 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
552 //-------------------------------------------------------------------
553 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
555 // Returns track or MC particle at position "ipart" if passes selection criteria
556 // particleSpecies: -1 all particles are returned
557 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
558 AliVParticle *part=0;
560 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
561 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
562 part = (AliVParticle*)arrayMC->At( ipart );
564 // eventually only primaries
565 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
566 // eventually only hadrons
568 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
569 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
570 TMath::Abs(pdgCode)==2212 || // Proton
571 TMath::Abs(pdgCode)==321; // Kaon
572 if (!isHadron) return 0;
574 if (particleSpecies != -1) {
575 // find the primary mother
576 AliVParticle* mother = part;
577 if(fCheckMotherPDG) {
578 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
580 if (((AliAODMCParticle*)mother)->GetMother() < 0)
586 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
593 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
594 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
596 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
598 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
600 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
605 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
606 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
610 // this code prints the details of the mother that is missing in the AOD
611 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
613 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
615 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
616 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
617 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
620 if (particleSpecies != 3)
625 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
626 TObjArray *array = static_cast<TObjArray*>(obj);
627 part = (AliVParticle*)array->At( ipart );
629 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
630 AliMCEvent* mcEvent = static_cast<AliMCEvent*>(obj);
631 part = mcEvent->GetTrack( ipart );
633 // eventually only primaries
634 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
635 // eventually only hadrons
638 Int_t pdgCode = part->GetPdgCode();
639 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
640 TMath::Abs(pdgCode)==2212 || // Proton
641 TMath::Abs(pdgCode)==321; // Kaon
642 if (!isHadron) return 0;
645 if (particleSpecies != -1) {
646 // find the primary mother
647 AliMCParticle* mother = (AliMCParticle*) part;
649 if(fCheckMotherPDG) {
650 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
652 // Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
653 if (mother->GetMother() < 0)
659 mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
666 Int_t pdgCode = mother->PdgCode();
667 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
669 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
671 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
673 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
678 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
679 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
684 // this code prints the details of the mother that is missing in the AOD
685 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
687 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
689 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
690 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
691 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
694 if (particleSpecies != 3)
698 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
699 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
700 part = aodEvent->GetTrack(ipart);
702 // track selection cuts
703 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
704 if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
706 // eventually only hadrons
708 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
709 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
710 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
711 if (!isHadron) return 0;
714 if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0;
716 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
717 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
718 part = esdEvent->GetTrack(ipart);
721 // track selection cuts
722 if (!( ApplyCuts(part)) )
725 if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
727 if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
729 // create TPC only tracks constrained to the SPD vertex
731 const AliESDVertex *vtxSPD = esdEvent->GetPrimaryVertexSPD();
733 AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
736 // Printf(">%f %f %f", track->Eta(), track->Phi(), track->Pt());
739 // only constrain tracks above threshold
740 AliExternalTrackParam exParam;
741 // take the B-feild from the ESD, no 3D fieldMap available at this point
742 Bool_t relate = kFALSE;
743 relate = track->RelateToVertexTPC(vtxSPD,esdEvent->GetMagneticField(),kVeryBig,&exParam);
746 // Printf("relating failed");
750 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
753 // Printf(">%f %f %f\n", track->Eta(), track->Phi(), track->Pt());
757 else if (fFilterBit == 2048)
762 AliESDtrack* esdTrack = new AliESDtrack(*((AliESDtrack*) part));
763 // Printf("%d %d %d %d %d", fEsdTrackCuts->IsSelected(esdTrack), fEsdTrackCutsExtra1->IsSelected(esdTrack), fEsdTrackCutsExtra2->IsSelected(esdTrack), esdTrack->HasPointOnITSLayer(0), esdTrack->HasPointOnITSLayer(1));
765 if (fEsdTrackCutsExtra2->IsSelected(esdTrack))
767 // Float_t ptBefore = esdTrack->Pt();
768 // set constrained pT as default pT
769 if (!esdTrack->GetConstrainedParam())
771 esdTrack->CopyFromVTrack(esdTrack->GetConstrainedParam());
772 // Printf("%f %f", ptBefore, esdTrack->Pt());
777 // eventually only hadrons
780 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
781 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
782 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
783 if (!isHadron) return 0;
786 if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0; // If it is -1 you take all the particles
789 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
794 if (!part->Charge())return 0;
800 //-------------------------------------------------------------------
801 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
803 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
806 static int i; // "static" to save stack space
809 while (last - first > 1) {
813 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
815 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
831 if (j - first < last - (j + 1)) {
832 QSortTracks(a, first, j);
833 first = j + 1; // QSortTracks(j + 1, last);
835 QSortTracks(a, j + 1, last);
836 last = j; // QSortTracks(first, j);
841 //____________________________________________________________________
842 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
845 // Assign particles to towards, away or transverse regions.
846 // Returns a lists of particles for each region.
848 static const Double_t k60rad = 60.*TMath::Pi()/180.;
849 static const Double_t k120rad = 120.*TMath::Pi()/180.;
851 // Define output lists of particles
852 TList *toward = new TList();
853 TList *away = new TList();
854 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
855 // MIN and MAX can be sorted in GetMinMaxRegion function
856 TList *transverse1 = new TList();
857 TList *transverse2 = new TList();
859 TObjArray *regionParticles = new TObjArray;
860 regionParticles->SetOwner(kTRUE);
862 regionParticles->AddLast(toward);
863 regionParticles->AddLast(away);
864 regionParticles->AddLast(transverse1);
865 regionParticles->AddLast(transverse2);
868 return regionParticles;
870 // Switch to vector for leading particle
871 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
873 Int_t nTracks = NParticles(obj);
874 if( !nTracks ) return 0;
876 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
877 AliVParticle* part = ParticleWithCuts(obj, ipart);
879 //Switch to vectors for particles
880 TVector3 partVect(part->Px(), part->Py(), part->Pz());
883 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
884 // transverse regions
885 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
886 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
888 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
889 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
891 // skip leading particle
895 if (!region)continue;
896 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
897 Int_t label = ((AliAODTrack*)part)->GetLabel();
898 // re-define part as the matched MC particle
899 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
901 // skip leading particle
905 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
906 Int_t label = ((AliESDtrack*)part)->GetLabel();
907 // look for the matched MC particle (but do not re-define part)
908 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
911 if ( region == 1 ) transverse1->Add(part);
912 if ( region == -1 ) transverse2->Add(part);
913 if ( region == 2 ) toward->Add(part);
914 if ( region == -2 ) away->Add(part);
916 }//end loop on tracks
918 return regionParticles;
923 //____________________________________________________________________
924 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
929 // Use AliPhysicsSelection to select good events, works for ESD and AOD
930 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&(fEventSelection)))
936 //____________________________________________________________________
937 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
940 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
942 if (obj->InheritsFrom("AliAODEvent")){
943 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
945 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
946 Int_t nTracksPrim = vertex->GetNContributors();
947 Double_t zVertex = vertex->GetZ();
948 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
949 // Reject TPC only vertex
950 TString name(vertex->GetName());
951 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
953 // Select a quality vertex by number of tracks?
954 if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
955 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
958 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
959 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
961 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
963 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
968 if (obj->InheritsFrom("AliMCEvent"))
970 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) >= zed)
972 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
977 if (obj->InheritsFrom("AliAODMCHeader"))
979 if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) >= zed)
981 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
986 // ESD case for DCA studies
987 if (obj->InheritsFrom("AliESDEvent")){
988 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
990 Int_t nTracksPrim = vertex->GetNContributors();
991 Double_t zVertex = vertex->GetZ();
992 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
993 // Reject SPD or TPC only vertex
994 TString name(vertex->GetName());
995 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
997 // Select a quality vertex by number of tracks?
998 if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
999 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1002 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
1003 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
1005 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
1007 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1015 //____________________________________________________________________
1017 Bool_t AliAnalyseLeadingTrackUE::CheckTrack(AliVParticle * part)
1019 // check if the track status flags are set
1021 UInt_t status=((AliVTrack*)part)->GetStatus();
1022 if ((status & fTrackStatus) == fTrackStatus)