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"
60 ////////////////////////////////////////////////
61 //---------------------------------------------
62 // Class for transverse regions analysis
63 //---------------------------------------------
64 ////////////////////////////////////////////////
69 ClassImp(AliAnalyseLeadingTrackUE)
71 //-------------------------------------------------------------------
72 AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
79 fEventSelection(AliVEvent::kMB|AliVEvent::kUserDefined),
81 fEsdTrackCutsExtra1(0x0),
82 fEsdTrackCutsExtra2(0x0)
88 //-------------------------------------------------------------------
89 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
91 // assignment operator
96 //-------------------------------------------------------------------
97 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
105 //____________________________________________________________________
106 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
109 // select track according to set of cuts
110 if (!fEsdTrackCuts->IsSelected(track) )return kFALSE;
111 if (fEsdTrackCutsExtra1 && fEsdTrackCutsExtra2 && !fEsdTrackCutsExtra1->IsSelected(track) && !fEsdTrackCutsExtra2->IsSelected(track)) return kFALSE;
117 //____________________________________________________________________
118 void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t filterbit) {
120 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
121 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
124 filterbit = fFilterBit;
126 if (filterbit == 128)
128 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
129 fEsdTrackCuts->SetMinNClustersTPC(70);
131 else if (filterbit == 256)
134 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
135 fEsdTrackCuts->SetMinNClustersTPC(80);
136 fEsdTrackCuts->SetMaxChi2PerClusterTPC(3);
137 fEsdTrackCuts->SetMaxDCAToVertexZ(2.7);
138 fEsdTrackCuts->SetMaxDCAToVertexXY(1.9);
140 else if (filterbit == 512)
143 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
144 fEsdTrackCuts->SetMinNClustersTPC(60);
145 fEsdTrackCuts->SetMaxChi2PerClusterTPC(5);
146 fEsdTrackCuts->SetMaxDCAToVertexZ(3.7);
147 fEsdTrackCuts->SetMaxDCAToVertexXY(2.9);
149 else if (filterbit == 1024)
151 fEsdTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
152 fEsdTrackCuts->SetMinNClustersTPC(-1);
153 fEsdTrackCuts->SetMinNCrossedRowsTPC(70);
154 fEsdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
156 else if (filterbit == 2048) // mimic hybrid tracks
158 // correspond to esdTrackCutsHTG, but WITHOUT spd constraint. this is checked with the next object
159 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE);
160 fEsdTrackCuts->SetName("Global Hybrid tracks, loose DCA");
161 fEsdTrackCuts->SetMaxDCAToVertexXY(2.4);
162 fEsdTrackCuts->SetMaxDCAToVertexZ(3.2);
163 fEsdTrackCuts->SetDCAToVertex2D(kTRUE);
164 fEsdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
165 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
167 // Add SPD requirement
168 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
169 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
170 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra1 corresponds to esdTrackCutsHTG
172 fEsdTrackCutsExtra2 = new AliESDtrackCuts("No_SPD", "Reject tracks with cluster in SPD");
173 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kNone);
174 // A track passing fEsdTrackCuts and fEsdTrackCutsExtra2 corresponds to esdTrackCutsHTGC and needs to be constrained
176 else if (filterbit == 4096) // require TOF matching
178 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE);
179 // FIXME: TOF REQUIREMENTS ARE IN GetParticleSpecies FOR THE MOMENT
183 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
184 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
186 // Add SPD requirement
187 fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
188 fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
190 // Add SDD requirement
191 fEsdTrackCutsExtra2 = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
192 fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
196 //____________________________________________________________________
197 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
200 // Returns an array of charged particles (or jets) ordered according to their pT.
202 Int_t nTracks = NParticles(obj);
205 if( !nTracks ) return 0;
207 // Define array of AliVParticle objects
208 TObjArray* tracks = new TObjArray(nTracks);
210 // Loop over tracks or jets
211 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
212 AliVParticle* part = ParticleWithCuts( obj, ipart );
214 // Accept leading-tracks in a limited pseudo-rapidity range
215 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
216 tracks->AddLast( part );
218 // Order tracks by pT
219 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
221 nTracks = tracks->GetEntriesFast();
222 if( !nTracks ) return 0;
228 void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject* mcObj, Int_t maxLabel)
230 // remove injected signals (primaries above <maxLabel>)
231 // <tracks> can be the following cases:
232 // a. tracks: in this case the label is taken and then case b.
233 // b. particles: the first stable mother is searched and checked if it is <= <maxLabel>
234 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
236 TClonesArray* arrayMC = 0;
237 AliMCEvent* mcEvent = 0;
238 if (mcObj->InheritsFrom("AliMCEvent"))
239 mcEvent = static_cast<AliMCEvent*>(mcObj);
240 else if (mcObj->InheritsFrom("TClonesArray"))
241 arrayMC = static_cast<TClonesArray*>(mcObj);
245 AliFatal("Invalid object passed");
248 Int_t before = tracks->GetEntriesFast();
250 for (Int_t i=0; i<before; ++i)
252 AliVParticle* part = (AliVParticle*) tracks->At(i);
254 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
255 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
257 AliVParticle* mother = part;
260 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
262 if (((AliMCParticle*)mother)->GetMother() < 0)
268 mother = (AliMCParticle*) mcEvent->GetTrack(((AliMCParticle*)mother)->GetMother());
275 // find the primary mother
276 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
278 if (((AliAODMCParticle*)mother)->GetMother() < 0)
284 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
292 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
296 if (mother->GetLabel() > maxLabel)
298 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
299 TObject* object = tracks->RemoveAt(i);
300 if (tracks->IsOwner())
307 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
310 //-------------------------------------------------------------------
311 void AliAnalyseLeadingTrackUE::RemoveWeakDecays(TObjArray* tracks, TObject* mcObj)
313 // remove particles from weak decays
314 // <tracks> can be the following cases:
315 // a. tracks: in this case the label is taken and then case b.
316 // b. particles: it is checked if IsSecondaryFromWeakDecay is true
317 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
319 TClonesArray* arrayMC = 0;
320 AliMCEvent* mcEvent = 0;
321 if (mcObj->InheritsFrom("AliMCEvent"))
322 mcEvent = static_cast<AliMCEvent*>(mcObj);
323 else if (mcObj->InheritsFrom("TClonesArray"))
324 arrayMC = static_cast<TClonesArray*>(mcObj);
328 AliFatal("Invalid object passed");
331 Int_t before = tracks->GetEntriesFast();
333 for (Int_t i=0; i<before; ++i)
335 AliVParticle* part = (AliVParticle*) tracks->At(i);
337 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
338 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
340 if (part->InheritsFrom("AliAODMCParticle"))
342 if (!((AliAODMCParticle*) part)->IsSecondaryFromWeakDecay())
345 else if (part->InheritsFrom("AliMCParticle") && mcEvent)
347 if (!(mcEvent->Stack()->IsSecondaryFromWeakDecay(part->GetLabel())))
353 AliFatal("Unknown particle");
356 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
357 TObject* object = tracks->RemoveAt(i);
358 if (tracks->IsOwner())
364 if (before > tracks->GetEntriesFast())
365 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
368 //-------------------------------------------------------------------
369 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
371 // 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
372 // particleSpecies: -1 all particles are returned
373 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
375 Int_t nTracks = NParticles(obj);
376 TObjArray* tracks = new TObjArray;
378 // for TPC only tracks
379 Bool_t hasOwnership = kFALSE;
380 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
381 hasOwnership = kTRUE;
384 tracks->SetOwner(hasOwnership);
386 // Loop over tracks or jets
387 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
388 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
392 if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
400 Int_t label = part->GetLabel();
403 // re-define part as the matched MC particle
404 part = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
414 //-------------------------------------------------------------------
415 TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
417 // particleSpecies: -1 all particles are returned
418 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
420 Int_t nTracks = NParticles(obj);
421 TObjArray* tracksReconstructed = new TObjArray;
422 TObjArray* tracksOriginal = new TObjArray;
423 TObjArray* tracksFake = new TObjArray;
425 // for TPC only tracks
426 Bool_t hasOwnership = kFALSE;
427 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
428 hasOwnership = kTRUE;
430 tracksReconstructed->SetOwner(hasOwnership);
431 tracksFake->SetOwner(hasOwnership);
433 // Loop over tracks or jets
434 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
435 AliVParticle* partReconstructed = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
436 if (!partReconstructed) continue;
439 if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || partReconstructed->Pt() < fTrackPtMin)
442 delete partReconstructed;
446 Int_t label = partReconstructed->GetLabel();
450 Printf(">>> TPC only track:");
451 partReconstructed->Print();
452 partReconstructed->Dump();
453 Printf(">>> Global track:");
454 ((AliESDEvent*) obj)->GetTrack(ipart)->Dump();
455 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());
456 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());
458 tracksFake->AddLast(partReconstructed);
462 AliVParticle* partOriginal = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
466 delete partReconstructed;
470 tracksReconstructed->AddLast(partReconstructed);
471 tracksOriginal->AddLast(partOriginal);
473 TObjArray* pairs = new TObjArray;
474 pairs->SetOwner(kTRUE);
475 pairs->Add(tracksReconstructed);
476 pairs->Add(tracksOriginal);
477 pairs->Add(tracksFake);
481 //-------------------------------------------------------------------
482 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
485 // Returns two lists of particles, one for MIN and one for MAX region
486 Double_t sumpT1 = 0.;
487 Double_t sumpT2 = 0.;
489 Int_t particles1 = transv1->GetEntries();
490 Int_t particles2 = transv2->GetEntries();
492 // Loop on transverse region 1
493 for (Int_t i=0; i<particles1; i++){
494 AliVParticle *part = (AliVParticle*)transv1->At(i);
495 sumpT1 += part->Pt();
498 // Loop on transverse region 2
499 for (Int_t i=0; i<particles2; i++){
500 AliVParticle *part = (AliVParticle*)transv2->At(i);
501 sumpT2 += part->Pt();
504 TObjArray *regionParticles = new TObjArray;
505 if ( sumpT2 >= sumpT1 ){
506 regionParticles->AddLast(transv1); // MIN
507 regionParticles->AddLast(transv2); // MAX
509 regionParticles->AddLast(transv2); // MIN
510 regionParticles->AddLast(transv1); // MAX
513 return regionParticles;
516 //-------------------------------------------------------------------
517 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
520 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
524 if (obj->InheritsFrom("TClonesArray")){ // MC particles
525 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
526 nTracks = arrayMC->GetEntriesFast();
527 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
528 TObjArray *array = static_cast<TObjArray*>(obj);
529 nTracks = array->GetEntriesFast();
530 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
531 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
532 nTracks = aodEvent->GetNTracks();
533 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
534 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
535 nTracks = esdEvent->GetNumberOfTracks();
536 }else if (obj->InheritsFrom("AliMCEvent")){ // RECO ESD tracks
537 AliMCEvent *mcEvent = static_cast<AliMCEvent*>(obj);
538 nTracks = mcEvent->GetNumberOfTracks();
540 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
547 //-------------------------------------------------------------------
548 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
550 // Returns track or MC particle at position "ipart" if passes selection criteria
551 // particleSpecies: -1 all particles are returned
552 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
553 AliVParticle *part=0;
555 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
556 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
557 part = (AliVParticle*)arrayMC->At( ipart );
559 // eventually only primaries
560 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
561 // eventually only hadrons
563 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
564 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
565 TMath::Abs(pdgCode)==2212 || // Proton
566 TMath::Abs(pdgCode)==321; // Kaon
567 if (!isHadron) return 0;
569 if (particleSpecies != -1) {
570 // find the primary mother
571 AliVParticle* mother = part;
572 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
574 if (((AliAODMCParticle*)mother)->GetMother() < 0)
580 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
587 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
588 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
590 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
592 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
594 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
599 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
600 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
604 // this code prints the details of the mother that is missing in the AOD
605 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
607 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
609 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
610 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
611 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
614 if (particleSpecies != 3)
619 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
620 TObjArray *array = static_cast<TObjArray*>(obj);
621 part = (AliVParticle*)array->At( ipart );
623 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
624 AliMCEvent* mcEvent = static_cast<AliMCEvent*>(obj);
625 part = mcEvent->GetTrack( ipart );
627 // eventually only primaries
628 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
629 // eventually only hadrons
632 Int_t pdgCode = part->GetPdgCode();
633 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
634 TMath::Abs(pdgCode)==2212 || // Proton
635 TMath::Abs(pdgCode)==321; // Kaon
636 if (!isHadron) return 0;
639 if (particleSpecies != -1) {
640 // find the primary mother
641 AliMCParticle* mother = (AliMCParticle*) part;
643 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
645 // Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
646 if (mother->GetMother() < 0)
652 mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
659 Int_t pdgCode = mother->PdgCode();
660 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
662 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
664 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
666 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
671 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
672 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
677 // this code prints the details of the mother that is missing in the AOD
678 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
680 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
682 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
683 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
684 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
687 if (particleSpecies != 3)
691 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
692 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
693 part = aodEvent->GetTrack(ipart);
694 // track selection cuts
695 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
696 //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0;
697 // only primary candidates
698 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
699 // eventually only hadrons
701 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
702 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
703 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
704 if (!isHadron) return 0;
707 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
708 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
709 part = esdEvent->GetTrack(ipart);
711 // track selection cuts
713 if (!( ApplyCuts(part)) )
716 if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
718 // create TPC only tracks constrained to the SPD vertex
720 const AliESDVertex *vtxSPD = esdEvent->GetPrimaryVertexSPD();
722 AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
725 // Printf(">%f %f %f", track->Eta(), track->Phi(), track->Pt());
728 // only constrain tracks above threshold
729 AliExternalTrackParam exParam;
730 // take the B-feild from the ESD, no 3D fieldMap available at this point
731 Bool_t relate = kFALSE;
732 relate = track->RelateToVertexTPC(vtxSPD,esdEvent->GetMagneticField(),kVeryBig,&exParam);
735 // Printf("relating failed");
739 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
742 // Printf(">%f %f %f\n", track->Eta(), track->Phi(), track->Pt());
746 else if (fFilterBit == 2048)
751 AliESDtrack* esdTrack = new AliESDtrack(*((AliESDtrack*) part));
752 // Printf("%d %d %d %d %d", fEsdTrackCuts->IsSelected(esdTrack), fEsdTrackCutsExtra1->IsSelected(esdTrack), fEsdTrackCutsExtra2->IsSelected(esdTrack), esdTrack->HasPointOnITSLayer(0), esdTrack->HasPointOnITSLayer(1));
754 if (fEsdTrackCutsExtra2->IsSelected(esdTrack))
756 // Float_t ptBefore = esdTrack->Pt();
757 // set constrained pT as default pT
758 if (!esdTrack->GetConstrainedParam())
760 esdTrack->CopyFromVTrack(esdTrack->GetConstrainedParam());
761 // Printf("%f %f", ptBefore, esdTrack->Pt());
766 // eventually only hadrons
769 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
770 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
771 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
772 if (!isHadron) return 0;
775 if (particleSpecies != -1 && GetParticleSpecies((AliVTrack*) part) != particleSpecies) return 0; // If it is -1 you take all the particles
778 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
783 if (!part->Charge())return 0;
789 //-------------------------------------------------------------------
790 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
792 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
795 static int i; // "static" to save stack space
798 while (last - first > 1) {
802 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
804 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
820 if (j - first < last - (j + 1)) {
821 QSortTracks(a, first, j);
822 first = j + 1; // QSortTracks(j + 1, last);
824 QSortTracks(a, j + 1, last);
825 last = j; // QSortTracks(first, j);
830 //____________________________________________________________________
831 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
834 // Assign particles to towards, away or transverse regions.
835 // Returns a lists of particles for each region.
837 static const Double_t k60rad = 60.*TMath::Pi()/180.;
838 static const Double_t k120rad = 120.*TMath::Pi()/180.;
840 // Define output lists of particles
841 TList *toward = new TList();
842 TList *away = new TList();
843 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
844 // MIN and MAX can be sorted in GetMinMaxRegion function
845 TList *transverse1 = new TList();
846 TList *transverse2 = new TList();
848 TObjArray *regionParticles = new TObjArray;
849 regionParticles->SetOwner(kTRUE);
851 regionParticles->AddLast(toward);
852 regionParticles->AddLast(away);
853 regionParticles->AddLast(transverse1);
854 regionParticles->AddLast(transverse2);
857 return regionParticles;
859 // Switch to vector for leading particle
860 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
862 Int_t nTracks = NParticles(obj);
863 if( !nTracks ) return 0;
865 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
866 AliVParticle* part = ParticleWithCuts(obj, ipart);
868 //Switch to vectors for particles
869 TVector3 partVect(part->Px(), part->Py(), part->Pz());
872 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
873 // transverse regions
874 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
875 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
877 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
878 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
880 // skip leading particle
884 if (!region)continue;
885 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
886 Int_t label = ((AliAODTrack*)part)->GetLabel();
887 // re-define part as the matched MC particle
888 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
890 // skip leading particle
894 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
895 Int_t label = ((AliESDtrack*)part)->GetLabel();
896 // look for the matched MC particle (but do not re-define part)
897 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
900 if ( region == 1 ) transverse1->Add(part);
901 if ( region == -1 ) transverse2->Add(part);
902 if ( region == 2 ) toward->Add(part);
903 if ( region == -2 ) away->Add(part);
905 }//end loop on tracks
907 return regionParticles;
912 //____________________________________________________________________
913 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
918 // Use AliPhysicsSelection to select good events, works for ESD and AOD
919 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&(fEventSelection)))
925 //____________________________________________________________________
926 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
929 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
931 if (obj->InheritsFrom("AliAODEvent")){
932 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
934 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
935 Int_t nTracksPrim = vertex->GetNContributors();
936 Double_t zVertex = vertex->GetZ();
937 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
938 // Reject TPC only vertex
939 TString name(vertex->GetName());
940 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
942 // Select a quality vertex by number of tracks?
943 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
944 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
947 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
948 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
950 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
952 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
957 if (obj->InheritsFrom("AliMCEvent"))
959 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
961 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
966 if (obj->InheritsFrom("AliAODMCHeader"))
968 if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) > zed)
970 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
975 // ESD case for DCA studies
976 if (obj->InheritsFrom("AliESDEvent")){
977 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
979 Int_t nTracksPrim = vertex->GetNContributors();
980 Double_t zVertex = vertex->GetZ();
981 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
982 // Reject SPD or TPC only vertex
983 TString name(vertex->GetName());
984 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
986 // Select a quality vertex by number of tracks?
987 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
988 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
991 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
992 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
994 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
996 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1005 Int_t AliAnalyseLeadingTrackUE::GetParticleSpecies(AliVTrack * trk)
1007 // return PID according to detectors
1008 // Get PID response object, if needed
1009 // FIXME: THIS IS UGLY!! THE CODE IS COPIED AND ADAPTED FROM PWGLF/SPECTRA/PiKaPr/TestAOD/AliSpectraBothPID.cxx
1010 // TO BE REPLACED BY THE PROPER CLASS ASAP
1014 enum BothPIDType_t {kNSigmaTPC,kNSigmaTOF,kNSigmaTPCTOF};
1016 enum BothParticleSpecies_t
1018 kSpPion = 0, kSpKaon, kSpProton,
1021 }; // Particle species used in plotting
1023 UInt_t fPIDType = kNSigmaTPCTOF;
1025 // Check TOF matching & PID
1026 // FIXME: this should go in the track selection!!
1028 status=trk->GetStatus();
1029 if((status&AliAODTrack::kTOFout)==0 || (status&AliAODTrack::kTIME)==0){//kTOFout and kTIME
1030 return kSpUndefined;
1035 // guess the particle based on the smaller nsigma
1037 // rec[kSpPion]=false;
1038 // rec[kSpKaon]=false;
1039 // rec[kSpProton]=false;
1041 static AliPIDResponse * fPIDResponse = 0;
1045 AliAnalysisManager *man = AliAnalysisManager::GetAnalysisManager();
1046 AliInputEventHandler* inputHandler = (AliInputEventHandler*)(man->GetInputEventHandler());
1047 fPIDResponse = inputHandler->GetPIDResponse();
1052 AliFatal("Cannot get pid response");
1057 // Compute nsigma for each hypthesis
1058 AliVParticle *inEvHMain = dynamic_cast<AliVParticle *>(trk);
1060 const Double_t fshiftTPC = 0, fshiftTOF=0;
1061 const Double_t fNSigmaPID = 3; // FIXME
1063 Double_t nsigmaTPCkProton = TMath::Abs(fPIDResponse->NumberOfSigmasTPC(inEvHMain, AliPID::kProton)+fshiftTPC);
1064 Double_t nsigmaTPCkKaon = TMath::Abs(fPIDResponse->NumberOfSigmasTPC(inEvHMain, AliPID::kKaon)+fshiftTPC);
1065 Double_t nsigmaTPCkPion = TMath::Abs(fPIDResponse->NumberOfSigmasTPC(inEvHMain, AliPID::kPion)+fshiftTPC);
1068 Double_t nsigmaTOFkProton=100.0,nsigmaTOFkKaon=100.0,nsigmaTOFkPion=100.0;
1070 Double_t nsigmaTPCTOFkProton = TMath::Abs(nsigmaTPCkProton);
1071 Double_t nsigmaTPCTOFkKaon = TMath::Abs(nsigmaTPCkKaon);
1072 Double_t nsigmaTPCTOFkPion = TMath::Abs(nsigmaTPCkPion);
1073 if(fPIDType==kNSigmaTOF)
1075 nsigmaTPCTOFkProton = 100.0;
1076 nsigmaTPCTOFkKaon = 100.0;
1077 nsigmaTPCTOFkPion = 100.0;
1082 nsigmaTOFkProton = TMath::Abs(fPIDResponse->NumberOfSigmasTOF(inEvHMain, AliPID::kProton)+fshiftTOF);
1083 nsigmaTOFkKaon = TMath::Abs(fPIDResponse->NumberOfSigmasTOF(inEvHMain, AliPID::kKaon)+fshiftTOF);
1084 nsigmaTOFkPion = TMath::Abs(fPIDResponse->NumberOfSigmasTOF(inEvHMain, AliPID::kPion)+fshiftTOF);
1085 // the TOF info is used in combined
1086 nsigmaTPCTOFkProton = TMath::Sqrt((nsigmaTPCkProton*nsigmaTPCkProton+nsigmaTOFkProton*nsigmaTOFkProton)/2.);
1087 nsigmaTPCTOFkKaon = TMath::Sqrt((nsigmaTPCkKaon*nsigmaTPCkKaon+nsigmaTOFkKaon*nsigmaTOFkKaon)/2.);
1088 nsigmaTPCTOFkPion = TMath::Sqrt((nsigmaTPCkPion*nsigmaTPCkPion+nsigmaTOFkPion*nsigmaTOFkPion)/2.);
1090 // select the nsigma to be used for the actual PID
1091 Double_t nsigmaPion=100;
1092 Double_t nsigmaKaon=100;
1093 Double_t nsigmaProton=100;
1098 nsigmaProton = nsigmaTPCkProton;
1099 nsigmaKaon = nsigmaTPCkKaon ;
1100 nsigmaPion = nsigmaTPCkPion ;
1103 nsigmaProton = nsigmaTOFkProton;
1104 nsigmaKaon = nsigmaTOFkKaon ;
1105 nsigmaPion = nsigmaTOFkPion ;
1108 nsigmaProton = nsigmaTPCTOFkProton;
1109 nsigmaKaon = nsigmaTPCTOFkKaon ;
1110 nsigmaPion = nsigmaTPCTOFkPion ;
1114 // if(nsigmaPion < fNSigmaPID)
1115 // rec[kSpPion]=true;
1116 // if(nsigmaKaon < fNSigmaPID)
1117 // rec[kSpKaon]=true;
1118 // if(nsigmaProton < fNSigmaPID)
1119 // rec[kSpProton]=true;
1121 if( ( nsigmaKaon==nsigmaPion ) && ( nsigmaKaon==nsigmaProton ))
1122 return kSpUndefined;//if is the default value for the three
1123 if( ( nsigmaKaon < nsigmaPion ) && ( nsigmaKaon < nsigmaProton ) && (nsigmaKaon < fNSigmaPID))
1127 if( ( nsigmaPion < nsigmaKaon ) && ( nsigmaPion < nsigmaProton ) && (nsigmaPion < fNSigmaPID))
1131 if( ( nsigmaProton < nsigmaKaon ) && ( nsigmaProton < nsigmaPion ) && (nsigmaProton < fNSigmaPID))
1135 // else, return undefined
1136 return kSpUndefined;