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 fEsdTrackCutsSPD(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 (fEsdTrackCutsSPD && fEsdTrackCutsSDD && !fEsdTrackCutsSPD->IsSelected(track) && fEsdTrackCutsSDD->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);
157 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
158 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kNone);
160 // Add SPD requirement
161 fEsdTrackCutsSPD = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
162 fEsdTrackCutsSPD->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
164 // Add SDD requirement
165 fEsdTrackCutsSDD = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
166 fEsdTrackCutsSDD->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
170 //____________________________________________________________________
171 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
174 // Returns an array of charged particles (or jets) ordered according to their pT.
176 Int_t nTracks = NParticles(obj);
179 if( !nTracks ) return 0;
181 // Define array of AliVParticle objects
182 TObjArray* tracks = new TObjArray(nTracks);
184 // Loop over tracks or jets
185 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
186 AliVParticle* part = ParticleWithCuts( obj, ipart );
188 // Accept leading-tracks in a limited pseudo-rapidity range
189 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
190 tracks->AddLast( part );
192 // Order tracks by pT
193 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
195 nTracks = tracks->GetEntriesFast();
196 if( !nTracks ) return 0;
202 void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject* mcObj, Int_t maxLabel)
204 // remove injected signals (primaries above <maxLabel>)
205 // <tracks> can be the following cases:
206 // a. tracks: in this case the label is taken and then case b.
207 // b. particles: the first stable mother is searched and checked if it is <= <maxLabel>
208 // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
210 TClonesArray* arrayMC = 0;
211 AliMCEvent* mcEvent = 0;
212 if (mcObj->InheritsFrom("AliMCEvent"))
213 mcEvent = static_cast<AliMCEvent*>(mcObj);
214 else if (mcObj->InheritsFrom("TClonesArray"))
215 arrayMC = static_cast<TClonesArray*>(mcObj);
219 AliFatal("Invalid object passed");
222 Int_t before = tracks->GetEntriesFast();
224 for (Int_t i=0; i<before; ++i)
226 AliVParticle* part = (AliVParticle*) tracks->At(i);
228 if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
229 part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
231 AliVParticle* mother = part;
234 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
236 if (((AliMCParticle*)mother)->GetMother() < 0)
242 mother = (AliMCParticle*) mcEvent->GetTrack(((AliMCParticle*)mother)->GetMother());
249 // find the primary mother
250 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
252 if (((AliAODMCParticle*)mother)->GetMother() < 0)
258 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
266 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
270 if (mother->GetLabel() > maxLabel)
272 // Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
273 TObject* object = tracks->RemoveAt(i);
274 if (tracks->IsOwner())
281 AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast()));
284 //-------------------------------------------------------------------
285 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
287 // 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
288 // particleSpecies: -1 all particles are returned
289 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
291 Int_t nTracks = NParticles(obj);
292 TObjArray* tracks = new TObjArray;
294 // for TPC only tracks
295 Bool_t hasOwnership = kFALSE;
296 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024) && obj->InheritsFrom("AliESDEvent"))
297 hasOwnership = kTRUE;
300 tracks->SetOwner(hasOwnership);
302 // Loop over tracks or jets
303 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
304 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
308 if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
316 Int_t label = part->GetLabel();
319 // re-define part as the matched MC particle
320 part = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
330 //-------------------------------------------------------------------
331 TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
333 // particleSpecies: -1 all particles are returned
334 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
336 Int_t nTracks = NParticles(obj);
337 TObjArray* tracksReconstructed = new TObjArray;
338 TObjArray* tracksOriginal = new TObjArray;
339 TObjArray* tracksFake = new TObjArray;
341 // for TPC only tracks
342 Bool_t hasOwnership = kFALSE;
343 if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024) && obj->InheritsFrom("AliESDEvent"))
344 hasOwnership = kTRUE;
346 tracksReconstructed->SetOwner(hasOwnership);
347 tracksFake->SetOwner(hasOwnership);
349 // Loop over tracks or jets
350 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
351 AliVParticle* partReconstructed = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
352 if (!partReconstructed) continue;
355 if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || partReconstructed->Pt() < fTrackPtMin)
358 delete partReconstructed;
362 Int_t label = partReconstructed->GetLabel();
366 Printf(">>> TPC only track:");
367 partReconstructed->Print();
368 partReconstructed->Dump();
369 Printf(">>> Global track:");
370 ((AliESDEvent*) obj)->GetTrack(ipart)->Dump();
371 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());
372 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());
374 tracksFake->AddLast(partReconstructed);
378 AliVParticle* partOriginal = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
382 delete partReconstructed;
386 tracksReconstructed->AddLast(partReconstructed);
387 tracksOriginal->AddLast(partOriginal);
389 TObjArray* pairs = new TObjArray;
390 pairs->SetOwner(kTRUE);
391 pairs->Add(tracksReconstructed);
392 pairs->Add(tracksOriginal);
393 pairs->Add(tracksFake);
397 //-------------------------------------------------------------------
398 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
401 // Returns two lists of particles, one for MIN and one for MAX region
402 Double_t sumpT1 = 0.;
403 Double_t sumpT2 = 0.;
405 Int_t particles1 = transv1->GetEntries();
406 Int_t particles2 = transv2->GetEntries();
408 // Loop on transverse region 1
409 for (Int_t i=0; i<particles1; i++){
410 AliVParticle *part = (AliVParticle*)transv1->At(i);
411 sumpT1 += part->Pt();
414 // Loop on transverse region 2
415 for (Int_t i=0; i<particles2; i++){
416 AliVParticle *part = (AliVParticle*)transv2->At(i);
417 sumpT2 += part->Pt();
420 TObjArray *regionParticles = new TObjArray;
421 if ( sumpT2 >= sumpT1 ){
422 regionParticles->AddLast(transv1); // MIN
423 regionParticles->AddLast(transv2); // MAX
425 regionParticles->AddLast(transv2); // MIN
426 regionParticles->AddLast(transv1); // MAX
429 return regionParticles;
432 //-------------------------------------------------------------------
433 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
436 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
440 if (obj->InheritsFrom("TClonesArray")){ // MC particles
441 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
442 nTracks = arrayMC->GetEntriesFast();
443 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
444 TObjArray *array = static_cast<TObjArray*>(obj);
445 nTracks = array->GetEntriesFast();
446 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
447 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
448 nTracks = aodEvent->GetNTracks();
449 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
450 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
451 nTracks = esdEvent->GetNumberOfTracks();
452 }else if (obj->InheritsFrom("AliMCEvent")){ // RECO ESD tracks
453 AliMCEvent *mcEvent = static_cast<AliMCEvent*>(obj);
454 nTracks = mcEvent->GetNumberOfTracks();
456 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
464 //-------------------------------------------------------------------
465 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
467 // Returns track or MC particle at position "ipart" if passes selection criteria
468 // particleSpecies: -1 all particles are returned
469 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
470 AliVParticle *part=0;
472 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
473 TClonesArray *arrayMC = static_cast<TClonesArray*>(obj);
474 part = (AliVParticle*)arrayMC->At( ipart );
476 // eventually only primaries
477 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
478 // eventually only hadrons
480 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
481 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
482 TMath::Abs(pdgCode)==2212 || // Proton
483 TMath::Abs(pdgCode)==321; // Kaon
484 if (!isHadron) return 0;
486 if (particleSpecies != -1) {
487 // find the primary mother
488 AliVParticle* mother = part;
489 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
491 if (((AliAODMCParticle*)mother)->GetMother() < 0)
497 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
504 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
505 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
507 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
509 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
511 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
516 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
517 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
521 // this code prints the details of the mother that is missing in the AOD
522 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
524 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
526 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
527 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
528 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
531 if (particleSpecies != 3)
536 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
537 TObjArray *array = static_cast<TObjArray*>(obj);
538 part = (AliVParticle*)array->At( ipart );
540 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
541 AliMCEvent* mcEvent = static_cast<AliMCEvent*>(obj);
542 part = mcEvent->GetTrack( ipart );
544 // eventually only primaries
545 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
546 // eventually only hadrons
549 Int_t pdgCode = part->GetPdgCode();
550 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
551 TMath::Abs(pdgCode)==2212 || // Proton
552 TMath::Abs(pdgCode)==321; // Kaon
553 if (!isHadron) return 0;
556 if (particleSpecies != -1) {
557 // find the primary mother
558 AliMCParticle* mother = (AliMCParticle*) part;
560 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
562 // Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
563 if (mother->GetMother() < 0)
569 mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
576 Int_t pdgCode = mother->PdgCode();
577 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
579 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
581 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
583 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
588 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
589 Printf("WARNING: No mother found for particle %d:", part->GetLabel());
594 // this code prints the details of the mother that is missing in the AOD
595 AliMCEventHandler* fMcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
597 AliMCEvent* fMcEvent = fMcHandler->MCEvent();
599 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->Print();
600 fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Print();
601 Printf("eta = %f", fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(fMcEvent->Stack()->Particle(part->GetLabel())->GetMother(0))->GetMother(0))->Eta());
604 if (particleSpecies != 3)
608 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
609 AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
610 part = aodEvent->GetTrack(ipart);
611 // track selection cuts
612 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
613 //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0;
614 // only primary candidates
615 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
616 // eventually only hadrons
618 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
619 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
620 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
621 if (!isHadron) return 0;
624 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
625 AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
626 part = esdEvent->GetTrack(ipart);
628 // track selection cuts
630 if (!( ApplyCuts(part)) )
633 if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
635 // create TPC only tracks constrained to the SPD vertex
637 const AliESDVertex *vtxSPD = esdEvent->GetPrimaryVertexSPD();
639 AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
643 // only constrain tracks above threshold
644 AliExternalTrackParam exParam;
645 // take the B-feild from the ESD, no 3D fieldMap available at this point
646 Bool_t relate = kFALSE;
647 relate = track->RelateToVertexTPC(vtxSPD,esdEvent->GetMagneticField(),kVeryBig,&exParam);
650 // Printf("relating failed");
654 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
660 // eventually only hadrons
663 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
664 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
665 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
666 if (!isHadron) return 0;
670 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
675 if (!part->Charge())return 0;
681 //-------------------------------------------------------------------
682 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
684 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
687 static int i; // "static" to save stack space
690 while (last - first > 1) {
694 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
696 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
712 if (j - first < last - (j + 1)) {
713 QSortTracks(a, first, j);
714 first = j + 1; // QSortTracks(j + 1, last);
716 QSortTracks(a, j + 1, last);
717 last = j; // QSortTracks(first, j);
722 //____________________________________________________________________
723 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
726 // Assign particles to towards, away or transverse regions.
727 // Returns a lists of particles for each region.
729 static const Double_t k60rad = 60.*TMath::Pi()/180.;
730 static const Double_t k120rad = 120.*TMath::Pi()/180.;
732 // Define output lists of particles
733 TList *toward = new TList();
734 TList *away = new TList();
735 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
736 // MIN and MAX can be sorted in GetMinMaxRegion function
737 TList *transverse1 = new TList();
738 TList *transverse2 = new TList();
740 TObjArray *regionParticles = new TObjArray;
741 regionParticles->SetOwner(kTRUE);
743 regionParticles->AddLast(toward);
744 regionParticles->AddLast(away);
745 regionParticles->AddLast(transverse1);
746 regionParticles->AddLast(transverse2);
749 return regionParticles;
751 // Switch to vector for leading particle
752 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
754 Int_t nTracks = NParticles(obj);
755 if( !nTracks ) return 0;
757 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
758 AliVParticle* part = ParticleWithCuts(obj, ipart);
760 //Switch to vectors for particles
761 TVector3 partVect(part->Px(), part->Py(), part->Pz());
764 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
765 // transverse regions
766 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
767 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
769 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
770 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
772 // skip leading particle
776 if (!region)continue;
777 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
778 Int_t label = ((AliAODTrack*)part)->GetLabel();
779 // re-define part as the matched MC particle
780 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
782 // skip leading particle
786 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
787 Int_t label = ((AliESDtrack*)part)->GetLabel();
788 // look for the matched MC particle (but do not re-define part)
789 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
792 if ( region == 1 ) transverse1->Add(part);
793 if ( region == -1 ) transverse2->Add(part);
794 if ( region == 2 ) toward->Add(part);
795 if ( region == -2 ) away->Add(part);
797 }//end loop on tracks
799 return regionParticles;
804 //____________________________________________________________________
805 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
810 // Use AliPhysicsSelection to select good events, works for ESD and AOD
811 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&(fEventSelection)))
817 //____________________________________________________________________
818 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
821 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
823 if (obj->InheritsFrom("AliAODEvent")){
824 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
826 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
827 Int_t nTracksPrim = vertex->GetNContributors();
828 Double_t zVertex = vertex->GetZ();
829 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
830 // Reject TPC only vertex
831 TString name(vertex->GetName());
832 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
834 // Select a quality vertex by number of tracks?
835 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
836 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
839 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
840 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
842 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
844 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
849 if (obj->InheritsFrom("AliMCEvent"))
851 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
853 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
858 if (obj->InheritsFrom("AliAODMCHeader"))
860 if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) > zed)
862 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
867 // ESD case for DCA studies
868 if (obj->InheritsFrom("AliESDEvent")){
869 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
871 Int_t nTracksPrim = vertex->GetNContributors();
872 Double_t zVertex = vertex->GetZ();
873 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
874 // Reject SPD or TPC only vertex
875 TString name(vertex->GetName());
876 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
878 // Select a quality vertex by number of tracks?
879 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
880 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
883 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
884 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
886 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
888 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");