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() :
78 //-------------------------------------------------------------------
79 AliAnalyseLeadingTrackUE & AliAnalyseLeadingTrackUE::operator = (const AliAnalyseLeadingTrackUE & /*source*/)
81 // assignment operator
86 //-------------------------------------------------------------------
87 AliAnalyseLeadingTrackUE::~AliAnalyseLeadingTrackUE()
95 //____________________________________________________________________
96 Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track, Int_t filterbit)
98 // Reproduces the cuts of the corresponding bit in the ESD->AOD filtering
99 // (see $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C)
101 AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts();
104 // tighter cuts on primary particles for high pT tracks
105 // needed as input for jetfinder
106 esdTrackCuts->SetMinNClustersTPC(50);
107 esdTrackCuts->SetMaxChi2PerClusterTPC(3.5);
108 esdTrackCuts->SetRequireTPCRefit(kTRUE);
109 esdTrackCuts->SetMaxDCAToVertexXY(2.4);
110 esdTrackCuts->SetMaxDCAToVertexZ(3.2);
111 esdTrackCuts->SetDCAToVertex2D(kTRUE);
112 esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
113 esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
114 esdTrackCuts->SetRequireITSRefit(kTRUE); // additional cut
119 esdTrackCuts->GetStandardITSTPCTrackCuts2009(kTRUE);
123 if (fDebug > 1) AliFatal("Set of cuts not defined");
127 // select track according to set of cuts
128 if (! esdTrackCuts->IsSelected(track) )return kFALSE;
137 //____________________________________________________________________
138 TObjArray* AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
141 // Returns an array of charged particles (or jets) ordered according to their pT.
143 Int_t nTracks = NParticles(obj);
146 if( !nTracks ) return 0;
148 // Define array of AliVParticle objects
149 TObjArray* tracks = new TObjArray(nTracks);
151 // Loop over tracks or jets
152 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
153 AliVParticle* part = ParticleWithCuts( obj, ipart );
155 // Accept leading-tracks in a limited pseudo-rapidity range
156 if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
157 tracks->AddLast( part );
159 // Order tracks by pT
160 QSortTracks( *tracks, 0, tracks->GetEntriesFast() );
162 nTracks = tracks->GetEntriesFast();
163 if( !nTracks ) return 0;
169 //-------------------------------------------------------------------
170 TObjArray* AliAnalyseLeadingTrackUE::GetMinMaxRegion(TList *transv1, TList *transv2)
173 // Returns two lists of particles, one for MIN and one for MAX region
174 Double_t sumpT1 = 0.;
175 Double_t sumpT2 = 0.;
177 Int_t particles1 = transv1->GetEntries();
178 Int_t particles2 = transv2->GetEntries();
180 // Loop on transverse region 1
181 for (Int_t i=0; i<particles1; i++){
182 AliVParticle *part = (AliVParticle*)transv1->At(i);
183 sumpT1 += part->Pt();
186 // Loop on transverse region 2
187 for (Int_t i=0; i<particles2; i++){
188 AliVParticle *part = (AliVParticle*)transv2->At(i);
189 sumpT2 += part->Pt();
192 TObjArray *regionParticles = new TObjArray;
193 if ( sumpT2 >= sumpT1 ){
194 regionParticles->AddLast(transv1); // MIN
195 regionParticles->AddLast(transv2); // MAX
197 regionParticles->AddLast(transv2); // MIN
198 regionParticles->AddLast(transv1); // MAX
201 return regionParticles;
204 //-------------------------------------------------------------------
205 Int_t AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
208 //Returns the number of particles in AliAODMCParticle array or AliAODTracks or AliESDTracks
212 if (obj->InheritsFrom("TClonesArray")){ // MC particles
213 TClonesArray *arrayMC = dynamic_cast<TClonesArray*>(obj);
214 nTracks = arrayMC->GetEntriesFast();
215 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
216 TObjArray *array = dynamic_cast<TObjArray*>(obj);
217 nTracks = array->GetEntriesFast();
218 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD tracks
219 AliAODEvent *aodEvent = dynamic_cast<AliAODEvent*>(obj);
220 nTracks = aodEvent->GetNTracks();
221 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD tracks
222 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*>(obj);
223 nTracks = esdEvent->GetNumberOfTracks();
225 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
233 //-------------------------------------------------------------------
234 AliVParticle* AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries)
236 // Returns track or MC particle at position "ipart" if passes selection criteria
237 AliVParticle *part=0;
239 if (obj->InheritsFrom("TClonesArray")){ // AOD-MC PARTICLE
240 TClonesArray *arrayMC = dynamic_cast<TClonesArray*>(obj);
241 part = (AliVParticle*)arrayMC->At( ipart );
243 // eventually only primaries
244 if (onlyprimaries && !( ((AliAODMCParticle*)part)->IsPhysicalPrimary()) )return 0;
245 // eventually only hadrons
247 Int_t pdgCode = ((AliAODMCParticle*)part)->GetPdgCode();
248 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
249 TMath::Abs(pdgCode)==2212 || // Proton
250 TMath::Abs(pdgCode)==321; // Kaon
251 if (!isHadron) return 0;
254 }else if (obj->InheritsFrom("TObjArray")){ // list of AliVParticle
255 TObjArray *array = dynamic_cast<TObjArray*>(obj);
256 part = (AliVParticle*)array->At( ipart );
258 }else if (obj->InheritsFrom("AliMCEvent")){ // MC PARTICLE
259 AliMCEvent* mcEvent = dynamic_cast<AliMCEvent*>(obj);
260 part = mcEvent->GetTrack( ipart );
262 // eventually only primaries
263 if (onlyprimaries && !( mcEvent->IsPhysicalPrimary(ipart)) )return 0;
264 // eventually only hadrons
267 Int_t pdgCode = part->GetPdgCode();
268 Bool_t isHadron = TMath::Abs(pdgCode)==211 || // Pion
269 TMath::Abs(pdgCode)==2212 || // Proton
270 TMath::Abs(pdgCode)==321; // Kaon
271 if (!isHadron) return 0;
275 }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
276 AliAODEvent *aodEvent = dynamic_cast<AliAODEvent*>(obj);
277 part = aodEvent->GetTrack(ipart);
278 // track selection cuts
279 if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0;
280 //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0;
281 // only primary candidates
282 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
283 // eventually only hadrons
285 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
286 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
287 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
288 if (!isHadron) return 0;
291 }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
292 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*>(obj);
293 part = esdEvent->GetTrack(ipart);
295 // track selection cuts
296 if (!( ApplyCuts(part, fFilterBit)) )return 0;
298 // only primary candidates (does not exist for ESD tracks??????)
299 //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
301 // eventually only hadrons
304 Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
305 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kKaon ||
306 ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
307 if (!isHadron) return 0;
311 if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
316 if (!part->Charge())return 0;
322 //-------------------------------------------------------------------
323 void AliAnalyseLeadingTrackUE::QSortTracks(TObjArray &a, Int_t first, Int_t last)
325 // Sort array of TObjArray of tracks by Pt using a quicksort algorithm.
328 static int i; // "static" to save stack space
331 while (last - first > 1) {
335 while (++i < last && ((AliVParticle*)a[i])->Pt() > ((AliVParticle*)a[first])->Pt() )
337 while (--j > first && ((AliVParticle*)a[j])->Pt() < ((AliVParticle*)a[first])->Pt() )
353 if (j - first < last - (j + 1)) {
354 QSortTracks(a, first, j);
355 first = j + 1; // QSortTracks(j + 1, last);
357 QSortTracks(a, j + 1, last);
358 last = j; // QSortTracks(first, j);
363 //____________________________________________________________________
364 TObjArray* AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, TObject* obj, TObject* arrayMC, Bool_t onlyprimaries)
367 // Assign particles to towards, away or transverse regions.
368 // Returns a lists of particles for each region.
370 static const Double_t k60rad = 60.*TMath::Pi()/180.;
371 static const Double_t k120rad = 120.*TMath::Pi()/180.;
373 // Define output lists of particles
374 TList *toward = new TList();
375 TList *away = new TList();
376 // Two transverse regions, for the moment those are not yet MIN and MAX!!!
377 // MIN and MAX can be sorted in GetMinMaxRegion function
378 TList *transverse1 = new TList();
379 TList *transverse2 = new TList();
381 TObjArray *regionParticles = new TObjArray;
382 regionParticles->AddLast(toward);
383 regionParticles->AddLast(away);
384 regionParticles->AddLast(transverse1);
385 regionParticles->AddLast(transverse2);
388 return regionParticles;
390 // Switch to vector for leading particle
391 TVector3 leadVect(leading->Px(),leading->Py(),leading->Pz());
393 Int_t nTracks = NParticles(obj);
394 if( !nTracks ) return 0;
396 for (Int_t ipart=0; ipart<nTracks; ++ipart) {
397 AliVParticle* part = ParticleWithCuts(obj, ipart);
399 //Switch to vectors for particles
400 TVector3 partVect(part->Px(), part->Py(), part->Pz());
403 if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
404 // transverse regions
405 if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
406 if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1; //right
408 if (TMath::Abs(leadVect.DeltaPhi(partVect)) < k60rad ) region = 2; //forward
409 if (TMath::Abs(leadVect.DeltaPhi(partVect)) > k120rad ) region = -2; //backward
411 // skip leading particle
415 if (!region)continue;
416 if (arrayMC && arrayMC->InheritsFrom("TClonesArray") && obj->InheritsFrom("AliAODEvent")){
417 Int_t label = ((AliAODTrack*)part)->GetLabel();
418 // re-define part as the matched MC particle
419 part = (AliAODMCParticle*)ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries);
421 // skip leading particle
425 if (arrayMC && arrayMC->InheritsFrom("AliMCEvent") && obj->InheritsFrom("AliESDEvent")){
426 Int_t label = ((AliESDtrack*)part)->GetLabel();
427 // look for the matched MC particle (but do not re-define part)
428 if (!ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries)) continue;
431 if ( region == 1 ) transverse1->Add(part);
432 if ( region == -1 ) transverse2->Add(part);
433 if ( region == 2 ) toward->Add(part);
434 if ( region == -2 ) away->Add(part);
436 }//end loop on tracks
438 return regionParticles;
443 //____________________________________________________________________
444 Bool_t AliAnalyseLeadingTrackUE::TriggerSelection(const TObject* obj)
447 //Use AliPhysicsSelection to select good events
448 if( !obj->InheritsFrom("AliAODInputHandler") ) { // not needed for AOD input
449 if (!(((AliInputEventHandler*)obj)->IsEventSelected()&AliVEvent::kMB))return kFALSE;
456 //____________________________________________________________________
457 Bool_t AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntracks, Double_t zed)
460 //Require 1 vertex (no TPC stand-alone) with a minimum number of tracks and z-coordinate in a limited range
462 if (obj->InheritsFrom("AliAODEvent")){
463 Int_t nVertex = ((AliAODEvent*)obj)->GetNumberOfVertices();
465 AliAODVertex* vertex = (AliAODVertex*)((AliAODEvent*)obj)->GetPrimaryVertex();
466 Int_t nTracksPrim = vertex->GetNContributors();
467 Double_t zVertex = vertex->GetZ();
468 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
469 // Reject TPC only vertex
470 TString name(vertex->GetName());
471 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
473 // Select a quality vertex by number of tracks?
474 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
475 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
478 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
479 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
481 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
483 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
488 if (obj->InheritsFrom("AliMCEvent"))
490 if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
492 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
497 // ESD case for DCA studies
498 if (obj->InheritsFrom("AliESDEvent")){
499 AliESDVertex* vertex = (AliESDVertex*)((AliESDEvent*)obj)->GetPrimaryVertex();
501 Int_t nTracksPrim = vertex->GetNContributors();
502 Double_t zVertex = vertex->GetZ();
503 if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
504 // Reject SPD or TPC only vertex
505 TString name(vertex->GetName());
506 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
508 // Select a quality vertex by number of tracks?
509 if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
510 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
513 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
514 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
516 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
518 if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");