3 // Emcal jet finder task.
5 // Authors: C.Loizides, S.Aiola
8 #include <TClonesArray.h>
10 #include <TLorentzVector.h>
12 #include "AliAnalysisManager.h"
13 #include "AliCentrality.h"
14 #include "AliEMCALGeometry.h"
15 #include "AliEmcalJet.h"
16 #include "AliFJWrapper.h"
17 #include "AliVCluster.h"
18 #include "AliVParticle.h"
19 #include "AliVEvent.h"
20 #include "AliESDEvent.h"
21 #include "AliMCEvent.h"
23 #include "AliEmcalJetTask.h"
25 ClassImp(AliEmcalJetTask)
27 //________________________________________________________________________
28 AliEmcalJetTask::AliEmcalJetTask() :
29 AliAnalysisTaskSE("AliEmcalJetTask"),
30 fTracksName("Tracks"),
31 fCaloName("CaloClusters"),
43 // Default constructor.
46 //________________________________________________________________________
47 AliEmcalJetTask::AliEmcalJetTask(const char *name) :
48 AliAnalysisTaskSE(name),
49 fTracksName("Tracks"),
50 fCaloName("CaloClusters"),
62 // Standard constructor.
64 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
67 //________________________________________________________________________
68 AliEmcalJetTask::~AliEmcalJetTask()
73 //________________________________________________________________________
74 void AliEmcalJetTask::UserCreateOutputObjects()
76 // Create user objects.
78 fJets = new TClonesArray("AliEmcalJet");
79 fJets->SetName(fJetsName);
82 //_____________________________________________________
83 TString AliEmcalJetTask::GetBeamType()
85 // Get beam type : pp-AA-pA
86 // ESDs have it directly, AODs get it from hardcoded run number ranges
90 AliESDEvent *esd = dynamic_cast<AliESDEvent*>(fEvent);
92 const AliESDRun *run = esd->GetESDRun();
93 beamType = run->GetBeamType();
97 Int_t runNumber = fEvent->GetRunNumber();
98 if ((runNumber >= 136851 && runNumber <= 139517) || // LHC10h
99 (runNumber >= 166529 && runNumber <= 170593)) // LHC11h
113 //________________________________________________________________________
114 void AliEmcalJetTask::UserExec(Option_t *)
116 // Main loop, called for each event.
119 fEvent = InputEvent();
122 AliError("Could not retrieve event! Returning");
126 // add jets to event if not yet there
127 if (!(fEvent->FindListObject(fJetsName)))
128 fEvent->AddObject(fJets);
133 // get input collections
134 TClonesArray *tracks = 0;
135 TClonesArray *clus = 0;
136 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
138 if ((fType == 0) || (fType == 1)) {
139 if (fTracksName == "Tracks")
140 am->LoadBranch("Tracks");
141 tracks = dynamic_cast<TClonesArray*>(fEvent->FindListObject(fTracksName));
143 AliError(Form("Pointer to tracks %s == 0", fTracksName.Data()));
147 if ((fType == 0) || (fType == 2)) {
148 if (fCaloName == "CaloClusters")
149 am->LoadBranch("CaloClusters");
150 clus = dynamic_cast<TClonesArray*>(fEvent->FindListObject(fCaloName));
152 AliError(Form("Pointer to clus %s == 0", fCaloName.Data()));
161 if (GetBeamType() == "A-A") {
162 AliCentrality *centrality = InputEvent()->GetCentrality();
165 cent = centrality->GetCentralityPercentile("V0M");
167 cent = 99; // probably pp data
170 AliWarning(Form("Centrality negative: %f, assuming 99", cent));
175 FindJets(tracks, clus, fAlgo, fRadius, cent);
178 //________________________________________________________________________
179 void AliEmcalJetTask::Terminate(Option_t *)
181 // Called once at the end of the analysis.
184 //________________________________________________________________________
185 void AliEmcalJetTask::FindJets(TObjArray *tracks, TObjArray *clus, Int_t algo, Double_t radius, Float_t /*cent*/)
189 if (!tracks && !clus)
193 fastjet::JetAlgorithm jalgo(fastjet::kt_algorithm);
196 jalgo = fastjet::antikt_algorithm;
199 AliFJWrapper fjw(name, name);
200 fjw.SetAreaType(fastjet::active_area_explicit_ghosts);
202 fjw.SetAlgorithm(jalgo);
207 const Int_t Ntracks = tracks->GetEntries();
208 for (Int_t iTracks = 0; iTracks < Ntracks; ++iTracks) {
209 AliVParticle *t = dynamic_cast<AliVParticle*>(tracks->At(iTracks));
213 if (t->Pt() < fMinJetTrackPt)
215 fjw.AddInputVector(t->Px(), t->Py(), t->Pz(), t->P(), iTracks + 100); // offset of 100 for consistency with cluster ids
220 Double_t vertex[3] = {0, 0, 0};
221 fEvent->GetPrimaryVertex()->GetXYZ(vertex);
222 const Int_t Nclus = clus->GetEntries();
223 for (Int_t iClus = 0; iClus < Nclus; ++iClus) {
224 AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(iClus));
229 TLorentzVector nPart;
230 c->GetMomentum(nPart, vertex);
231 if (nPart.Pt() < fMinJetClusPt)
233 fjw.AddInputVector(nPart.Px(), nPart.Py(), nPart.Pz(), nPart.P(), -iClus - 100); // offset of 100 to skip ghost particles uid = -1
241 AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
243 AliFatal("Can not create geometry");
247 std::vector<fastjet::PseudoJet> jets_incl = fjw.GetInclusiveJets();
248 for (UInt_t ij=0, jetCount=0; ij<jets_incl.size(); ++ij) {
249 if (jets_incl[ij].perp()<fMinJetPt)
251 if (fjw.GetJetArea(ij)<fMinJetArea)
253 AliEmcalJet *jet = new ((*fJets)[jetCount])
254 AliEmcalJet(jets_incl[ij].perp(), jets_incl[ij].eta(), jets_incl[ij].phi(), jets_incl[ij].m());
255 Double_t vertex[3] = {0, 0, 0};
256 fEvent->GetPrimaryVertex()->GetXYZ(vertex);
257 vector<fastjet::PseudoJet> constituents = fjw.GetJetConstituents(ij);
260 Double_t neutralE = 0;
269 jet->SetNumberOfTracks(constituents.size());
270 jet->SetNumberOfClusters(constituents.size());
271 for(UInt_t ic = 0; ic < constituents.size(); ++ic) {
272 Int_t uid = constituents[ic].user_index();
274 if ((uid == -1) && (constituents[ic].kt2() < 1e-25)) { //ghost particle
276 Double_t gphi = constituents[ic].phi() * TMath::RadToDeg();
277 Double_t geta = constituents[ic].eta();
278 if ((gphi > geom->GetArm1PhiMin()) && (gphi < geom->GetArm1PhiMax()) &&
279 (geta > geom->GetArm1EtaMin()) && (geta < geom->GetArm1EtaMax()))
282 } else if (uid > 0) {
283 Int_t tid = uid - 100;
284 AliVParticle *t = static_cast<AliVParticle*>(tracks->At(tid));
286 if (t->Charge() == 0) {
297 if (t->InheritsFrom("AliMCParticle") || t->GetLabel() == 100) // MC particle
300 jet->AddTrackAt(tid, nt);
304 Int_t cid = -uid - 100;
305 AliVCluster *c = static_cast<AliVCluster*>(clus->At(cid));
308 c->GetMomentum(nP, vertex);
313 if (c->Chi2() == 100) // MC particle
316 jet->AddClusterAt(cid, nc);
322 jet->SetNumberOfTracks(nt);
323 jet->SetNumberOfClusters(nc);
324 jet->SortConstituents();
325 jet->SetMaxNeutralPt(maxNe);
326 jet->SetMaxChargedPt(maxCh);
327 jet->SetNEF(neutralE / jet->E());
328 jet->SetArea(fjw.GetJetArea(ij));
329 jet->SetNumberOfCharged(ncharged);
330 jet->SetNumberOfNeutrals(nneutral);
333 jet->SetAreaEmc(fjw.GetJetArea(ij) * gemc / gall);
336 if ((jet->Phi() > geom->GetArm1PhiMin() * TMath::DegToRad()) &&
337 (jet->Phi() < geom->GetArm1PhiMax() * TMath::DegToRad()) &&
338 (jet->Eta() > geom->GetArm1EtaMin()) &&
339 (jet->Eta() < geom->GetArm1EtaMax()))
340 jet->SetAxisInEmcal(kTRUE);