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 "AliMCEventHandler.h"
52 //#include "AliStack.h"
53 #include "AliVParticle.h"
55 ////////////////////////////////////////////////
56 //---------------------------------------------
57 // Class for transverse regions analysis
58 //---------------------------------------------
59 ////////////////////////////////////////////////
64 ClassImp(AliAnalyseLeadingTrackUE)
66 //-------------------------------------------------------------------
67 AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
75 fEsdTrackCutsSPD(0x0),
82 //-------------------------------------------------------------------
83 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
85 // assignment operator
90 //-------------------------------------------------------------------
91 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
99 //____________________________________________________________________
100 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
103 // select track according to set of cuts
104 if (! fEsdTrackCuts->IsSelected(track) )return kFALSE;
105 if (!fEsdTrackCutsSPD->IsSelected(track) && fEsdTrackCutsSDD->IsSelected(track)) return kFALSE;
111 //____________________________________________________________________
112 void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t /*filterbit*/){
114 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
115 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
117 fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
118 fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kNone);
120 // Add SPD requirement
121 fEsdTrackCutsSPD = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
122 fEsdTrackCutsSPD->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
124 // Add SDD requirement
125 fEsdTrackCutsSDD = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
126 fEsdTrackCutsSDD->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
130 //____________________________________________________________________
131 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
134 // Returns an array of charged particles (or jets) ordered according to their pT.
136 Int_t nTracks = NParticles(obj);
139 if( !nTracks ) return 0;
141 // Define array of AliVParticle objects
142 TObjArray* tracks = new TObjArray(nTracks);
144 // Loop over tracks or jets
145 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
146 AliVParticle* part = ParticleWithCuts( obj, ipart );
148 // Accept leading-tracks in a limited pseudo-rapidity range
149 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
150 tracks->AddLast( part );
152 // Order tracks by pT
153 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
155 nTracks = tracks->GetEntriesFast();
156 if( !nTracks ) return 0;
162 //-------------------------------------------------------------------
163 TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
165 // 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
166 // particleSpecies: -1 all particles are returned
167 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
169 Int_t nTracks = NParticles(obj);
170 TObjArray* tracks = new TObjArray;
172 // Loop over tracks or jets
173 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
174 AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
178 if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
181 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")) {
182 Int_t label = ((AliAODTrack*)part)->GetLabel();
183 // re-define part as the matched MC particle
184 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
194 //-------------------------------------------------------------------
195 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
198 // Returns two lists of particles, one for MIN and one for MAX region
199 Double_t sumpT1 = 0.;
200 Double_t sumpT2 = 0.;
202 Int_t particles1 = transv1->GetEntries();
203 Int_t particles2 = transv2->GetEntries();
205 // Loop on transverse region 1
206 for (Int_t i=0; i<particles1; i++){
207 AliVParticle *part = (AliVParticle*)transv1->At(i);
208 sumpT1 += part->Pt();
211 // Loop on transverse region 2
212 for (Int_t i=0; i<particles2; i++){
213 AliVParticle *part = (AliVParticle*)transv2->At(i);
214 sumpT2 += part->Pt();
217 TObjArray *regionParticles = new TObjArray;
218 if ( sumpT2 >= sumpT1 ){
219 regionParticles->AddLast(transv1); // MIN
220 regionParticles->AddLast(transv2); // MAX
222 regionParticles->AddLast(transv2); // MIN
223 regionParticles->AddLast(transv1); // MAX
226 return regionParticles;
229 //-------------------------------------------------------------------
230 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
233 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
237 if (obj->InheritsFrom("TClonesArray")){ // MC particles
238 TClonesArray *arrayMC = dynamic_cast<TClonesArray*>(obj);
239 nTracks = arrayMC->GetEntriesFast();
240 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
241 TObjArray *array = dynamic_cast<TObjArray*>(obj);
242 nTracks = array->GetEntriesFast();
243 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
244 AliAODEvent *aodEvent = dynamic_cast<AliAODEvent*>(obj);
245 nTracks = aodEvent->GetNTracks();
246 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
247 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*>(obj);
248 nTracks = esdEvent->GetNumberOfTracks();
249 }else if (obj->InheritsFrom("AliMCEvent")){ // RECO ESD tracks
250 AliMCEvent *mcEvent = dynamic_cast<AliMCEvent*>(obj);
251 nTracks = mcEvent->GetNumberOfTracks();
253 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
261 //-------------------------------------------------------------------
262 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
264 // Returns track or MC particle at position "ipart" if passes selection criteria
265 // particleSpecies: -1 all particles are returned
266 // 0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
267 AliVParticle *part=0;
269 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
270 TClonesArray *arrayMC = dynamic_cast<TClonesArray*>(obj);
271 part = (AliVParticle*)arrayMC->At( ipart );
273 // eventually only primaries
274 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
275 // eventually only hadrons
277 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
278 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
279 TMath::Abs(pdgCode)==2212 || // Proton
280 TMath::Abs(pdgCode)==321; // Kaon
281 if (!isHadron) return 0;
283 if (particleSpecies != -1) {
284 // find the primary mother
285 AliVParticle* mother = part;
286 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
288 if (((AliAODMCParticle*)mother)->GetMother() < 0)
294 mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
301 Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
302 if (particleSpecies == 0 && TMath::Abs(pdgCode)!=211)
304 if (particleSpecies == 1 && TMath::Abs(pdgCode)!=321)
306 if (particleSpecies == 2 && TMath::Abs(pdgCode)!=2212)
308 if (particleSpecies == 3 && (TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212))
313 // if mother not found, accept particle only in case of particleSpecies == 3. To include it in all or no sample is no solution
314 Printf("WARNING: No mother found for particle %d", part->GetLabel());
315 if (particleSpecies != 3)
320 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
321 TObjArray *array = dynamic_cast<TObjArray*>(obj);
322 part = (AliVParticle*)array->At( ipart );
324 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
325 AliMCEvent* mcEvent = dynamic_cast<AliMCEvent*>(obj);
326 part = mcEvent->GetTrack( ipart );
328 // eventually only primaries
329 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
330 // eventually only hadrons
333 Int_t pdgCode = part->GetPdgCode();
334 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
335 TMath::Abs(pdgCode)==2212 || // Proton
336 TMath::Abs(pdgCode)==321; // Kaon
337 if (!isHadron) return 0;
341 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
342 AliAODEvent *aodEvent = dynamic_cast<AliAODEvent*>(obj);
343 part = aodEvent->GetTrack(ipart);
344 // track selection cuts
345 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
346 //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0;
347 // only primary candidates
348 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
349 // eventually only hadrons
351 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
352 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
353 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
354 if (!isHadron) return 0;
357 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
358 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*>(obj);
359 part = esdEvent->GetTrack(ipart);
361 // track selection cuts
363 if (!( ApplyCuts(part)) )
366 // only primary candidates (does not exist for ESD tracks??????)
367 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
369 // eventually only hadrons
372 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
373 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
374 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
375 if (!isHadron) return 0;
379 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
384 if (!part->Charge())return 0;
390 //-------------------------------------------------------------------
391 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
393 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
396 static int i; // "static" to save stack space
399 while (last - first > 1) {
403 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
405 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
421 if (j - first < last - (j + 1)) {
422 QSortTracks(a, first, j);
423 first = j + 1; // QSortTracks(j + 1, last);
425 QSortTracks(a, j + 1, last);
426 last = j; // QSortTracks(first, j);
431 //____________________________________________________________________
432 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
435 // Assign particles to towards, away or transverse regions.
436 // Returns a lists of particles for each region.
438 static const Double_t k60rad = 60.*TMath::Pi()/180.;
439 static const Double_t k120rad = 120.*TMath::Pi()/180.;
441 // Define output lists of particles
442 TList *toward = new TList();
443 TList *away = new TList();
444 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
445 // MIN and MAX can be sorted in GetMinMaxRegion function
446 TList *transverse1 = new TList();
447 TList *transverse2 = new TList();
449 TObjArray *regionParticles = new TObjArray;
450 regionParticles->SetOwner(kTRUE);
452 regionParticles->AddLast(toward);
453 regionParticles->AddLast(away);
454 regionParticles->AddLast(transverse1);
455 regionParticles->AddLast(transverse2);
458 return regionParticles;
460 // Switch to vector for leading particle
461 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
463 Int_t nTracks = NParticles(obj);
464 if( !nTracks ) return 0;
466 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
467 AliVParticle* part = ParticleWithCuts(obj, ipart);
469 //Switch to vectors for particles
470 TVector3 partVect(part->Px(), part->Py(), part->Pz());
473 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
474 // transverse regions
475 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
476 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
478 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
479 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
481 // skip leading particle
485 if (!region)continue;
486 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
487 Int_t label = ((AliAODTrack*)part)->GetLabel();
488 // re-define part as the matched MC particle
489 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
491 // skip leading particle
495 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
496 Int_t label = ((AliESDtrack*)part)->GetLabel();
497 // look for the matched MC particle (but do not re-define part)
498 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
501 if ( region == 1 ) transverse1->Add(part);
502 if ( region == -1 ) transverse2->Add(part);
503 if ( region == 2 ) toward->Add(part);
504 if ( region == -2 ) away->Add(part);
506 }//end loop on tracks
508 return regionParticles;
513 //____________________________________________________________________
514 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
519 //Use AliPhysicsSelection to select good events
520 if( !obj->InheritsFrom("AliAODInputHandler") ) { // not needed for AOD input
521 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&AliVEvent::kMB))return kFALSE;
524 // TODO for AOD input trigger bit needs to be checked too (is stored in the AOD)
529 //____________________________________________________________________
530 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
533 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
535 if (obj->InheritsFrom("AliAODEvent")){
536 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
538 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
539 Int_t nTracksPrim = vertex->GetNContributors();
540 Double_t zVertex = vertex->GetZ();
541 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
542 // Reject TPC only vertex
543 TString name(vertex->GetName());
544 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
546 // Select a quality vertex by number of tracks?
547 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
548 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
551 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
552 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
554 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
556 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
561 if (obj->InheritsFrom("AliMCEvent"))
563 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
565 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
570 // ESD case for DCA studies
571 if (obj->InheritsFrom("AliESDEvent")){
572 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
574 Int_t nTracksPrim = vertex->GetNContributors();
575 Double_t zVertex = vertex->GetZ();
576 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
577 // Reject SPD or TPC only vertex
578 TString name(vertex->GetName());
579 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
581 // Select a quality vertex by number of tracks?
582 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
583 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
586 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
587 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
589 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
591 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");