3 // Emcal jet finder task.
5 // Authors: C.Loizides, S.Aiola
8 #include "AliEmcalJetTask.h"
11 #include <TClonesArray.h>
13 #include <TLorentzVector.h>
15 #include "AliAnalysisManager.h"
16 #include "AliCentrality.h"
17 #include "AliEMCALGeometry.h"
18 #include "AliESDEvent.h"
19 #include "AliEmcalJet.h"
20 #include "AliEmcalParticle.h"
21 #include "AliFJWrapper.h"
22 #include "AliMCEvent.h"
23 #include "AliVCluster.h"
24 #include "AliVEvent.h"
25 #include "AliVParticle.h"
27 ClassImp(AliEmcalJetTask)
29 //________________________________________________________________________
30 AliEmcalJetTask::AliEmcalJetTask() :
31 AliAnalysisTaskSE("AliEmcalJetTask"),
32 fTracksName("Tracks"),
33 fCaloName("CaloClusters"),
41 fPhiMax(TMath::TwoPi()),
56 // Default constructor.
59 //________________________________________________________________________
60 AliEmcalJetTask::AliEmcalJetTask(const char *name) :
61 AliAnalysisTaskSE(name),
62 fTracksName("Tracks"),
63 fCaloName("CaloClusters"),
71 fPhiMax(TMath::TwoPi()),
86 // Standard constructor.
88 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
91 //________________________________________________________________________
92 AliEmcalJetTask::~AliEmcalJetTask()
97 //________________________________________________________________________
98 void AliEmcalJetTask::UserCreateOutputObjects()
100 // Create user objects.
102 fJets = new TClonesArray("AliEmcalJet");
103 fJets->SetName(fJetsName);
106 //________________________________________________________________________
107 void AliEmcalJetTask::UserExec(Option_t *)
109 // Main loop, called for each event.
120 //________________________________________________________________________
121 void AliEmcalJetTask::Terminate(Option_t *)
123 // Called once at the end of the analysis.
126 //________________________________________________________________________
127 void AliEmcalJetTask::FindJets()
131 if (!fTracks && !fClus)
135 fastjet::JetAlgorithm jalgo(fastjet::kt_algorithm);
138 jalgo = fastjet::antikt_algorithm;
142 AliFJWrapper fjw(name, name);
143 fjw.SetAreaType(fastjet::active_area_explicit_ghosts);
144 fjw.SetGhostArea(fGhostArea);
146 fjw.SetAlgorithm(jalgo);
150 // get primary vertex
151 Double_t vertex[3] = {0, 0, 0};
152 fEvent->GetPrimaryVertex()->GetXYZ(vertex);
154 if ((fIsMcPart || fType == 0 || fType == 1) && fTracks) {
155 const Int_t Ntracks = fTracks->GetEntries();
156 for (Int_t iTracks = 0; iTracks < Ntracks; ++iTracks) {
157 AliVParticle *t = static_cast<AliVParticle*>(fTracks->At(iTracks));
160 if (fIsMcPart && fType == 1 && t->Charge() == 0)
162 if (fIsMcPart && fType == 2 && t->Charge() != 0)
164 if (t->Pt() < fMinJetTrackPt)
166 Double_t eta = t->Eta();
167 Double_t phi = t->Phi();
168 if ((eta<fEtaMin) || (eta>fEtaMax) ||
169 (phi<fPhiMin) || (phi>fPhiMax))
172 // offset of 100 for consistency with cluster ids
173 fjw.AddInputVector(t->Px(), t->Py(), t->Pz(), t->P(), iTracks + 100);
177 if ((fType == 0 || fType == 2) && fClus) {
178 const Int_t Nclus = fClus->GetEntries();
179 for (Int_t iClus = 0; iClus < Nclus; ++iClus) {
181 Double_t cEta=0,cPhi=0,cPt=0;
182 Double_t cPx=0,cPy=0,cPz=0;
184 AliEmcalParticle *ep = static_cast<AliEmcalParticle*>(fClus->At(iClus));
187 c = ep->GetCluster();
197 c = static_cast<AliVCluster*>(fClus->At(iClus));
201 c->GetMomentum(nP, vertex);
211 if (cPt < fMinJetClusPt)
213 if ((cEta<fEtaMin) || (cEta>fEtaMax) ||
214 (cPhi<fPhiMin) || (cPhi>fPhiMax))
216 // offset of 100 to skip ghost particles uid = -1
217 fjw.AddInputVector(cPx, cPy, cPz, TMath::Sqrt(cPx*cPx+cPy*cPy+cPz*cPz), -iClus - 100);
225 AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
227 AliFatal(Form("%s: Can not create geometry", GetName()));
231 // loop over fastjet jets
232 std::vector<fastjet::PseudoJet> jets_incl = fjw.GetInclusiveJets();
233 for (UInt_t ij=0, jetCount=0; ij<jets_incl.size(); ++ij) {
234 if (jets_incl[ij].perp()<fMinJetPt)
236 if (fjw.GetJetArea(ij)<fMinJetArea)
239 AliEmcalJet *jet = new ((*fJets)[jetCount])
240 AliEmcalJet(jets_incl[ij].perp(), jets_incl[ij].eta(), jets_incl[ij].phi(), jets_incl[ij].m());
242 // loop over constituents
243 std::vector<fastjet::PseudoJet> constituents(fjw.GetJetConstituents(ij));
244 jet->SetNumberOfTracks(constituents.size());
245 jet->SetNumberOfClusters(constituents.size());
249 Double_t neutralE = 0;
260 for(UInt_t ic = 0; ic < constituents.size(); ++ic) {
261 Int_t uid = constituents[ic].user_index();
263 if ((uid == -1) /*&& (constituents[ic].kt2() < 1e-25)*/) { //ghost particle
265 Double_t gphi = constituents[ic].phi();
267 gphi += TMath::TwoPi();
268 gphi *= TMath::RadToDeg();
269 Double_t geta = constituents[ic].eta();
270 if ((gphi > geom->GetArm1PhiMin()) && (gphi < geom->GetArm1PhiMax()) &&
271 (geta > geom->GetArm1EtaMin()) && (geta < geom->GetArm1EtaMax()))
273 } else if ((uid > 0) && fTracks) { // track constituent
274 Int_t tid = uid - 100;
275 AliVParticle *t = static_cast<AliVParticle*>(fTracks->At(tid));
278 Double_t cEta = t->Eta();
279 Double_t cPhi = t->Phi();
280 Double_t cPt = t->Pt();
281 Double_t cP = t->P();
282 if (t->Charge() == 0) {
293 if (fIsMcPart || t->GetLabel() >= 0) // check if MC particle
297 cPhi += TMath::TwoPi();
298 cPhi *= TMath::RadToDeg();
299 if ((cPhi > geom->GetArm1PhiMin()) && (cPhi < geom->GetArm1PhiMax()) &&
300 (cEta > geom->GetArm1EtaMin()) && (cEta < geom->GetArm1EtaMax())) {
305 jet->AddTrackAt(tid, nt);
307 } else if (fClus) { // cluster constituent
308 Int_t cid = -uid - 100;
310 Double_t cEta=0,cPhi=0,cPt=0,cP=0;
312 AliEmcalParticle *ep = static_cast<AliEmcalParticle*>(fClus->At(cid));
315 c = ep->GetCluster();
323 c = static_cast<AliVCluster*>(fClus->At(cid));
327 c->GetMomentum(nP, vertex);
338 if (c->GetLabel() >= 0) // MC particle
342 cPhi += TMath::TwoPi();
343 cPhi *= TMath::RadToDeg();
344 if ((cPhi > geom->GetArm1PhiMin()) && (cPhi < geom->GetArm1PhiMax()) &&
345 (cEta > geom->GetArm1EtaMin()) && (cEta < geom->GetArm1EtaMax())) {
350 jet->AddClusterAt(cid, nc);
354 AliError(Form("%s: No logical way to end up here.", GetName()));
357 } /* end of constituent loop */
359 jet->SetNumberOfTracks(nt);
360 jet->SetNumberOfClusters(nc);
361 jet->SortConstituents();
362 jet->SetMaxNeutralPt(maxNe);
363 jet->SetMaxChargedPt(maxCh);
364 jet->SetNEF(neutralE / jet->E());
365 fastjet::PseudoJet area(fjw.GetJetAreaVector(ij));
366 jet->SetArea(area.perp());
367 jet->SetAreaEta(area.eta());
368 jet->SetAreaPhi(area.phi());
369 jet->SetNumberOfCharged(ncharged);
370 jet->SetNumberOfNeutrals(nneutral);
373 jet->SetPtEmc(emcpt);
376 jet->SetAreaEmc(fjw.GetJetArea(ij) * gemc / gall);
379 if ((jet->Phi() > geom->GetArm1PhiMin() * TMath::DegToRad()) &&
380 (jet->Phi() < geom->GetArm1PhiMax() * TMath::DegToRad()) &&
381 (jet->Eta() > geom->GetArm1EtaMin()) &&
382 (jet->Eta() < geom->GetArm1EtaMax()))
383 jet->SetAxisInEmcal(kTRUE);
389 //________________________________________________________________________
390 Bool_t AliEmcalJetTask::DoInit()
392 // Init. Return true if successful.
394 // get input collections
395 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
398 fEvent = InputEvent();
400 AliError(Form("%s: Could not retrieve event! Returning", GetName()));
404 // add jets to event if not yet there
406 if (!(fEvent->FindListObject(fJetsName)))
407 fEvent->AddObject(fJets);
409 AliError(Form("%s: Object with name %s already in event! Returning", GetName(), fJetsName.Data()));
413 if (fTracksName == "Tracks")
414 am->LoadBranch("Tracks");
415 if (!fTracks && !fTracksName.IsNull()) {
416 fTracks = dynamic_cast<TClonesArray*>(fEvent->FindListObject(fTracksName));
418 AliError(Form("%s: Pointer to tracks %s == 0", GetName(), fTracksName.Data()));
423 TClass cls(fTracks->GetClass()->GetName());
424 if (cls.InheritsFrom("AliMCParticle"))
428 if (fCaloName == "CaloClusters")
429 am->LoadBranch("CaloClusters");
430 if (!fClus && !fCaloName.IsNull()) {
431 fClus = dynamic_cast<TClonesArray*>(fEvent->FindListObject(fCaloName));
433 AliError(Form("%s: Pointer to clus %s == 0", GetName(), fCaloName.Data()));
438 TClass cls(fClus->GetClass()->GetName());
439 if (cls.InheritsFrom("AliEmcalParticle"))