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"
59 ////////////////////////////////////////////////
60 //---------------------------------------------
61 // Class for transverse regions analysis
62 //---------------------------------------------
63 ////////////////////////////////////////////////
68 ClassImp(AliAnalyseLeadingTrackUE)
70 //-------------------------------------------------------------------
71 AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
78 fEventSelection(AliVEvent::kMB|AliVEvent::kUserDefined),
80 fEsdTrackCutsExtra1(0x0),
81 fEsdTrackCutsExtra2(0x0)
87 //-------------------------------------------------------------------
88 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
90 // assignment operator
95 //-------------------------------------------------------------------
96 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
104 //____________________________________________________________________
105 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
108 // select track according to set of cuts
109 if (!fEsdTrackCuts->IsSelected(track) )return kFALSE;
110 if (fEsdTrackCutsExtra1 && fEsdTrackCutsExtra2 && !fEsdTrackCutsExtra1->IsSelected(track) && !fEsdTrackCutsExtra2->IsSelected(track)) return kFALSE;
116 //____________________________________________________________________
117 void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t filterbit) {
119 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
120 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
123 filterbit = fFilterBit;
125 if (filterbit == 128)
127 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
128 fEsdTrackCuts->SetMinNClustersTPC(70);
130 else if (filterbit == 256)
133 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
134 fEsdTrackCuts->SetMinNClustersTPC(80);
135 fEsdTrackCuts->SetMaxChi2PerClusterTPC(3);
136 fEsdTrackCuts->SetMaxDCAToVertexZ(2.7);
137 fEsdTrackCuts->SetMaxDCAToVertexXY(1.9);
139 else if (filterbit == 512)
142 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
143 fEsdTrackCuts->SetMinNClustersTPC(60);
144 fEsdTrackCuts->SetMaxChi2PerClusterTPC(5);
145 fEsdTrackCuts->SetMaxDCAToVertexZ(3.7);
146 fEsdTrackCuts->SetMaxDCAToVertexXY(2.9);
148 else if (filterbit == 1024)
150 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
151 fEsdTrackCuts->SetMinNClustersTPC(-1);
152 fEsdTrackCuts->SetMinNCrossedRowsTPC(70);
153 fEsdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
155 else if (filterbit == 2048) // mimic hybrid tracks
157 // correspond to esdTrackCutsHTG, but WITHOUT spd constraint. this is checked with the next object
158 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE);
159 fEsdTrackCuts->SetName("Global Hybrid tracks, loose DCA");
160 fEsdTrackCuts->SetMaxDCAToVertexXY(2.4);
161 fEsdTrackCuts->SetMaxDCAToVertexZ(3.2);
162 fEsdTrackCuts->SetDCAToVertex2D(kTRUE);
163 fEsdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
164 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
166 // Add SPD requirement
167 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
168 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
169 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra1 corresponds to esdTrackCutsHTG
171 fEsdTrackCutsExtra2 = new AliESDtrackCuts("No_SPD", "Reject tracks with cluster in SPD");
172 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kNone);
173 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra2 corresponds to esdTrackCutsHTGC and needs to be constrained
177 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
178 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
180 // Add SPD requirement
181 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
182 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
184 // Add SDD requirement
185 fEsdTrackCutsExtra2 = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
186 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
190 //____________________________________________________________________
191 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
194 // Returns an array of charged particles (or jets) ordered according to their pT.
196 Int_t nTracks = NParticles(obj);
199 if( !nTracks ) return 0;
201 // Define array of AliVParticle objects
202 TObjArray* tracks = new TObjArray(nTracks);
204 // Loop over tracks or jets
205 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
206 AliVParticle* part = ParticleWithCuts( obj, ipart );
208 // Accept leading-tracks in a limited pseudo-rapidity range
209 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
210 tracks->AddLast( part );
212 // Order tracks by pT
213 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
215 nTracks = tracks->GetEntriesFast();
216 if( !nTracks ) return 0;
222 void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject* mcObj, Int_t maxLabel)
224 // remove injected signals (primaries above <maxLabel>)
225 // <tracks> can be the following cases:
226 // a. tracks: in this case the label is taken and then case b.
227 // b. particles: the first stable mother is searched and checked if it is <= <maxLabel>
228 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
230 TClonesArray* arrayMC = 0;
231 AliMCEvent* mcEvent = 0;
232 if (mcObj->InheritsFrom("AliMCEvent"))
233 mcEvent = static_cast<AliMCEvent*>(mcObj);
234 else if (mcObj->InheritsFrom("TClonesArray"))
235 arrayMC = static_cast<TClonesArray*>(mcObj);
239 AliFatal("Invalid object passed");
242 Int_t before = tracks->GetEntriesFast();
244 for (Int_t i=0; i<before; ++i)
246 AliVParticle* part = (AliVParticle*) tracks->At(i);
248 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
249 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
251 AliVParticle* mother = part;
254 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
256 if (((AliMCParticle*)mother)->GetMother() < 0)
262 mother = (AliMCParticle*) mcEvent->GetTrack(((AliMCParticle*)mother)->GetMother());
269 // find the primary mother
270 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
272 if (((AliAODMCParticle*)mother)->GetMother() < 0)
278 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
286 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
290 if (mother->GetLabel() > maxLabel)
292 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
293 TObject* object = tracks->RemoveAt(i);
294 if (tracks->IsOwner())
301 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
304 //-------------------------------------------------------------------
305 void AliAnalyseLeadingTrackUE::RemoveWeakDecays(TObjArray* tracks, TObject* mcObj)
307 // remove particles from weak decays
308 // <tracks> can be the following cases:
309 // a. tracks: in this case the label is taken and then case b.
310 // b. particles: it is checked if IsSecondaryFromWeakDecay is true
311 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
313 TClonesArray* arrayMC = 0;
314 AliMCEvent* mcEvent = 0;
315 if (mcObj->InheritsFrom("AliMCEvent"))
316 mcEvent = static_cast<AliMCEvent*>(mcObj);
317 else if (mcObj->InheritsFrom("TClonesArray"))
318 arrayMC = static_cast<TClonesArray*>(mcObj);
322 AliFatal("Invalid object passed");
325 Int_t before = tracks->GetEntriesFast();
327 for (Int_t i=0; i<before; ++i)
329 AliVParticle* part = (AliVParticle*) tracks->At(i);
331 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
332 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
334 if (part->InheritsFrom("AliAODMCParticle"))
336 if (!((AliAODMCParticle*) part)->IsSecondaryFromWeakDecay())
339 else if (part->InheritsFrom("AliMCParticle") && mcEvent)
341 if (!(mcEvent->Stack()->IsSecondaryFromWeakDecay(((AliMCParticle*) part)->Label())))
347 AliFatal("Unknown particle");
350 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
351 TObject* object = tracks->RemoveAt(i);
352 if (tracks->IsOwner())
358 if (before > tracks->GetEntriesFast())
359 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
362 //-------------------------------------------------------------------
363 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
365 // 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
366 // particleSpecies: -1 all particles are returned
367 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
369 Int_t nTracks = NParticles(obj);
370 TObjArray* tracks = new TObjArray;
372 // for TPC only tracks
373 Bool_t hasOwnership = kFALSE;
374 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
375 hasOwnership = kTRUE;
378 tracks->SetOwner(hasOwnership);
380 // Loop over tracks or jets
381 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
382 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
386 if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
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 || 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 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
568 if (((AliAODMCParticle*)mother)->GetMother() < 0)
574 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
581 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
582 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
584 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
586 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
588 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
593 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
594 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
598 // this code prints the details of the mother that is missing in the AOD
599 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
601 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
603 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
604 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
605 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
608 if (particleSpecies != 3)
613 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
614 TObjArray *array = static_cast<TObjArray*>(obj);
615 part = (AliVParticle*)array->At( ipart );
617 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
618 AliMCEvent* mcEvent = static_cast<AliMCEvent*>(obj);
619 part = mcEvent->GetTrack( ipart );
621 // eventually only primaries
622 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
623 // eventually only hadrons
626 Int_t pdgCode = part->GetPdgCode();
627 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
628 TMath::Abs(pdgCode)==2212 || // Proton
629 TMath::Abs(pdgCode)==321; // Kaon
630 if (!isHadron) return 0;
633 if (particleSpecies != -1) {
634 // find the primary mother
635 AliMCParticle* mother = (AliMCParticle*) part;
637 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
639 // Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
640 if (mother->GetMother() < 0)
646 mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
653 Int_t pdgCode = mother->PdgCode();
654 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
656 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
658 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
660 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
665 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
666 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
671 // this code prints the details of the mother that is missing in the AOD
672 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
674 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
676 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
677 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
678 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
681 if (particleSpecies != 3)
685 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
686 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
687 part = aodEvent->GetTrack(ipart);
688 // track selection cuts
689 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
690 //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0;
691 // only primary candidates
692 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
693 // eventually only hadrons
695 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
696 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
697 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
698 if (!isHadron) return 0;
701 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
702 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
703 part = esdEvent->GetTrack(ipart);
705 // track selection cuts
707 if (!( ApplyCuts(part)) )
710 if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
712 // create TPC only tracks constrained to the SPD vertex
714 const AliESDVertex *vtxSPD = esdEvent->GetPrimaryVertexSPD();
716 AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
719 // Printf(">%f %f %f", track->Eta(), track->Phi(), track->Pt());
722 // only constrain tracks above threshold
723 AliExternalTrackParam exParam;
724 // take the B-feild from the ESD, no 3D fieldMap available at this point
725 Bool_t relate = kFALSE;
726 relate = track->RelateToVertexTPC(vtxSPD,esdEvent->GetMagneticField(),kVeryBig,&exParam);
729 // Printf("relating failed");
733 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
736 // Printf(">%f %f %f\n", track->Eta(), track->Phi(), track->Pt());
740 else if (fFilterBit == 2048)
745 AliESDtrack* esdTrack = new AliESDtrack(*((AliESDtrack*) part));
746 // Printf("%d %d %d %d %d", fEsdTrackCuts->IsSelected(esdTrack), fEsdTrackCutsExtra1->IsSelected(esdTrack), fEsdTrackCutsExtra2->IsSelected(esdTrack), esdTrack->HasPointOnITSLayer(0), esdTrack->HasPointOnITSLayer(1));
748 if (fEsdTrackCutsExtra2->IsSelected(esdTrack))
750 // Float_t ptBefore = esdTrack->Pt();
751 // set constrained pT as default pT
752 if (!esdTrack->GetConstrainedParam())
754 esdTrack->CopyFromVTrack(esdTrack->GetConstrainedParam());
755 // Printf("%f %f", ptBefore, esdTrack->Pt());
760 // eventually only hadrons
763 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
764 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
765 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
766 if (!isHadron) return 0;
770 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
775 if (!part->Charge())return 0;
781 //-------------------------------------------------------------------
782 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
784 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
787 static int i; // "static" to save stack space
790 while (last - first > 1) {
794 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
796 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
812 if (j - first < last - (j + 1)) {
813 QSortTracks(a, first, j);
814 first = j + 1; // QSortTracks(j + 1, last);
816 QSortTracks(a, j + 1, last);
817 last = j; // QSortTracks(first, j);
822 //____________________________________________________________________
823 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
826 // Assign particles to towards, away or transverse regions.
827 // Returns a lists of particles for each region.
829 static const Double_t k60rad = 60.*TMath::Pi()/180.;
830 static const Double_t k120rad = 120.*TMath::Pi()/180.;
832 // Define output lists of particles
833 TList *toward = new TList();
834 TList *away = new TList();
835 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
836 // MIN and MAX can be sorted in GetMinMaxRegion function
837 TList *transverse1 = new TList();
838 TList *transverse2 = new TList();
840 TObjArray *regionParticles = new TObjArray;
841 regionParticles->SetOwner(kTRUE);
843 regionParticles->AddLast(toward);
844 regionParticles->AddLast(away);
845 regionParticles->AddLast(transverse1);
846 regionParticles->AddLast(transverse2);
849 return regionParticles;
851 // Switch to vector for leading particle
852 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
854 Int_t nTracks = NParticles(obj);
855 if( !nTracks ) return 0;
857 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
858 AliVParticle* part = ParticleWithCuts(obj, ipart);
860 //Switch to vectors for particles
861 TVector3 partVect(part->Px(), part->Py(), part->Pz());
864 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
865 // transverse regions
866 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
867 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
869 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
870 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
872 // skip leading particle
876 if (!region)continue;
877 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
878 Int_t label = ((AliAODTrack*)part)->GetLabel();
879 // re-define part as the matched MC particle
880 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
882 // skip leading particle
886 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
887 Int_t label = ((AliESDtrack*)part)->GetLabel();
888 // look for the matched MC particle (but do not re-define part)
889 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
892 if ( region == 1 ) transverse1->Add(part);
893 if ( region == -1 ) transverse2->Add(part);
894 if ( region == 2 ) toward->Add(part);
895 if ( region == -2 ) away->Add(part);
897 }//end loop on tracks
899 return regionParticles;
904 //____________________________________________________________________
905 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
910 // Use AliPhysicsSelection to select good events, works for ESD and AOD
911 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&(fEventSelection)))
917 //____________________________________________________________________
918 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
921 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
923 if (obj->InheritsFrom("AliAODEvent")){
924 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
926 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
927 Int_t nTracksPrim = vertex->GetNContributors();
928 Double_t zVertex = vertex->GetZ();
929 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
930 // Reject TPC only vertex
931 TString name(vertex->GetName());
932 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
934 // Select a quality vertex by number of tracks?
935 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
936 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
939 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
940 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
942 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
944 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
949 if (obj->InheritsFrom("AliMCEvent"))
951 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
953 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
958 if (obj->InheritsFrom("AliAODMCHeader"))
960 if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) > zed)
962 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
967 // ESD case for DCA studies
968 if (obj->InheritsFrom("AliESDEvent")){
969 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
971 Int_t nTracksPrim = vertex->GetNContributors();
972 Double_t zVertex = vertex->GetZ();
973 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
974 // Reject SPD or TPC only vertex
975 TString name(vertex->GetName());
976 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
978 // Select a quality vertex by number of tracks?
979 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
980 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
983 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
984 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
986 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
988 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");