3 // Hadronic correction task.
5 // Author: R.Reed, C.Loizides
8 #include <TClonesArray.h>
12 #include <TLorentzVector.h>
13 #include <TParticle.h>
14 #include "AliAODCaloCluster.h"
15 #include "AliAODEvent.h"
16 #include "AliAnalysisManager.h"
17 #include "AliCentrality.h"
18 #include "AliESDCaloCluster.h"
19 #include "AliESDtrack.h"
20 #include "AliFJWrapper.h"
21 #include "AliPicoTrack.h"
22 #include "AliVEventHandler.h"
23 #include "AliHadCorrTask.h"
25 ClassImp(AliHadCorrTask)
27 //________________________________________________________________________
28 AliHadCorrTask::AliHadCorrTask() :
29 AliAnalysisTaskSE("AliHadCorrTask"),
40 fHistNclusMatchvsCent(0),
46 // Default constructor.
48 for(Int_t i=0; i<8; i++) {
50 fHistMatchEvsP[i] = 0;
51 fHistMatchdRvsEP[i] = 0;
54 for(Int_t j=0; j<5; j++) {
55 fHistMatchEtaPhi[i][j] = 0;
60 //________________________________________________________________________
61 AliHadCorrTask::AliHadCorrTask(const char *name) :
62 AliAnalysisTaskSE(name),
63 fTracksName("Tracks"),
64 fCaloName("CaloClusters"),
65 fOutCaloName("CaloClustersCorr"),
73 fHistNclusMatchvsCent(0),
79 // Standard constructor.
81 for(Int_t i=0; i<8; i++) {
84 fHistMatchdRvsEP[i]=0;
87 for(Int_t j=0; j<5; j++) {
88 fHistMatchEtaPhi[i][j] = 0;
92 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
94 DefineInput(0,TChain::Class());
95 DefineOutput(1,TList::Class());
98 //________________________________________________________________________
99 AliHadCorrTask::~AliHadCorrTask()
104 //________________________________________________________________________
105 Int_t AliHadCorrTask::GetCentBin(Double_t cent) const
107 // Get centrality bin.
110 if (cent>=0 && cent<10)
112 else if (cent>=10 && cent<30)
114 else if (cent>=30 && cent<50)
116 else if (cent>=50 && cent<=100)
122 //________________________________________________________________________
123 Int_t AliHadCorrTask::GetMomBin(Double_t p) const
130 else if (p>=0.5 && p<2.)
132 else if (p>=2. && p<3.)
134 else if (p>=3. && p<5.)
142 //________________________________________________________________________
143 void AliHadCorrTask::UserCreateOutputObjects()
145 // Create my user objects.
147 AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
149 AliError("Input handler not available!");
153 if (handler->InheritsFrom("AliESDInputHandler")) {
154 fOutClusters = new TClonesArray("AliESDCaloCluster");
155 } else if (handler->InheritsFrom("AliAODInputHandler")) {
156 fOutClusters = new TClonesArray("AliAODCaloCluster");
158 AliError("Input handler not recognized!");
161 fOutClusters->SetName(fOutCaloName);
164 fOutputList = new TList();
165 fOutputList->SetOwner();
167 for(Int_t icent=0; icent<8; ++icent) {
168 for(Int_t ipt=0; ipt<5; ++ipt) {
169 TString name(Form("fHistMatchEtaPhi_%i_%i",icent,ipt));
170 fHistMatchEtaPhi[icent][ipt] = new TH2F(name, name, 400, -0.2, 0.2, 1600, -0.8, 0.8);
171 fOutputList->Add(fHistMatchEtaPhi[icent][ipt]);
175 TString name(Form("fHistMatchEvsP_%i",icent));
176 fHistMatchEvsP[icent] = new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
177 fOutputList->Add(fHistMatchEvsP[icent]);
179 name = Form("fHistMatchdRvsEP_%i",icent);
180 fHistMatchdRvsEP[icent] = new TH2F(name, name, 1000, 0., 1., 1000, 0., 10.);
181 fOutputList->Add(fHistMatchdRvsEP[icent]);
183 name = Form("fHistEsubPch_%i",icent);
184 fHistEsubPch[icent]=new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
185 fOutputList->Add(fHistEsubPch[icent]);
189 fHistNclusvsCent = new TH1F("Nclusvscent", "NclusVsCent", 100, 0, 100);
190 fHistNclusMatchvsCent = new TH1F("NclusMatchvscent", "NclusMatchVsCent", 100, 0, 100);
191 fHistEbefore = new TH1F("Ebefore", "Ebefore", 100, 0, 100);
192 fHistEafter = new TH1F("Eafter", "Eafter", 100, 0, 100);
193 fHistEoPCent = new TH2F("EoPCent", "EoPCent", 100, 0, 100, 1000, 0, 10);
194 fHistNMatchCent = new TH2F("NMatchesCent", "NMatchesCent", 100, 0, 100, 101, -0.5, 100.5);
195 fOutputList->Add(fHistNclusMatchvsCent);
196 fOutputList->Add(fHistNclusvsCent);
197 fOutputList->Add(fHistEbefore);
198 fOutputList->Add(fHistEafter);
199 fOutputList->Add(fHistEoPCent);
200 fOutputList->Add(fHistNMatchCent);
202 PostData(1, fOutputList);
205 //________________________________________________________________________
206 void AliHadCorrTask::UserExec(Option_t *)
208 // Execute per event.
210 // post output in event if not yet present
211 if (!(InputEvent()->FindListObject(fOutCaloName)))
212 InputEvent()->AddObject(fOutClusters);
215 fOutClusters->Delete();
218 Bool_t esdMode = kTRUE;
219 if (dynamic_cast<AliAODEvent*>(InputEvent()))
222 // optimization in case autobranch loading is off
223 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
224 if (fCaloName == "CaloClusters")
225 am->LoadBranch("CaloClusters");
226 if (fTracksName == "Tracks")
227 am->LoadBranch("Tracks");
231 AliCentrality *centrality = InputEvent()->GetCentrality() ;
233 cent = centrality->GetCentralityPercentile("V0M");
235 cent=99; // probably pp data
237 AliError(Form("Centrality negative: %f", cent));
240 Int_t centbin = GetCentBin(cent);
242 // get input collections
243 TClonesArray *tracks = 0;
244 TClonesArray *clus = 0;
245 TList *l = InputEvent()->GetList();
247 tracks = dynamic_cast<TClonesArray*>(l->FindObject(fTracksName));
249 AliError(Form("Pointer to tracks %s == 0", fTracksName.Data() ));
252 clus = dynamic_cast<TClonesArray*>(l->FindObject(fCaloName));
254 AliError(Form("Pointer to clus %s == 0", fCaloName.Data() ));
258 // get primary vertex
259 Double_t vertex[3] = {0, 0, 0};
260 InputEvent()->GetPrimaryVertex()->GetXYZ(vertex);
262 // loop over clusters and tracks
263 const Int_t Nclus = clus->GetEntries();
264 const Int_t Ntrks = tracks->GetEntries();
266 for (Int_t iClus = 0, clusCount=0; iClus < Nclus; ++iClus) {
267 AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(iClus));
273 // make primary particle out of cluster
274 TLorentzVector nPart;
275 c->GetMomentum(nPart, vertex);
277 Double_t etclus = nPart.Pt();
281 Double_t energyclus = nPart.P();
283 // reset cluster/track matching
284 c->SetEmcCpvDistance(-1);
285 c->SetTrackDistance(999,999);
287 // run cluster-track matching
289 Double_t dEtaMin = 1e9;
290 Double_t dPhiMin = 1e9;
291 Double_t dRmin = 1e9;
292 Double_t totalTrkP = 0.0; // count total track momentum
293 Int_t Nmatches = 0; // count total number of matches
294 for (Int_t t = 0; t<Ntrks; ++t) {
295 AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
298 if (!track->IsEMCAL())
300 if (track->Pt()<fMinPt)
302 Double_t etadiff=999;
303 Double_t phidiff=999;
304 AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
305 Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
314 Double_t mom = track->P();
315 Int_t mombin = GetMomBin(mom);
316 Int_t centbinch = centbin;
317 if (track->Charge()==-1)
320 fHistMatchEtaPhi[centbinch][mombin]->Fill(etadiff,phidiff);
321 fHistMatchdRvsEP[centbin]->Fill(dR,energyclus/mom);
324 if (TMath::Abs(phidiff)<fPhiMatch && TMath::Abs(etadiff)<fEtaMatch) {
326 totalTrkP += track->P();
330 // store closest track
331 c->SetEmcCpvDistance(imin);
332 c->SetTrackDistance(dPhiMin, dEtaMin);
334 fHistNclusvsCent->Fill(cent);
335 fHistEbefore->Fill(cent,energyclus);
336 fHistNMatchCent->Fill(cent,Nmatches);
338 fHistNclusMatchvsCent->Fill(cent);
340 // apply correction / subtraction
342 // to subtract only the closest track set fHadCor to a %
343 // to subtract all tracks within the cut set fHadCor to %+1
346 Double_t EoP = energyclus/totalTrkP;
347 Double_t Esub = (fHadCorr-1)*totalTrkP;
350 fHistEoPCent->Fill(cent,EoP);
351 fHistMatchEvsP[centbin]->Fill(energyclus,EoP);
352 fHistEsubPch[centbin]->Fill(totalTrkP,Esub/totalTrkP);
354 energyclus -= (fHadCorr-1)*totalTrkP;
355 } else if (imin>=0) {
356 AliVTrack *t = dynamic_cast<AliVTrack*>(tracks->At(imin));
358 Double_t mom = t->P();
359 Int_t mombin = GetMomBin(mom);
360 Int_t centbinch = centbin;
363 fHistMatchEtaPhi[centbinch][mombin]->Fill(dEtaMin,dPhiMin);
365 fHistEoPCent->Fill(cent,energyclus/mom);
366 fHistMatchEvsP[centbin]->Fill(energyclus,energyclus/mom);
367 fHistMatchdRvsEP[centbin]->Fill(dRmin,energyclus/mom);
369 if (TMath::Abs(dPhiMin)<fPhiMatch && TMath::Abs(dEtaMin)<fEtaMatch) {
370 energyclus -= fHadCorr*t->P();
377 fHistEafter->Fill(cent,energyclus);
379 if (energyclus>0) { // create corrected cluster
382 oc = new ((*fOutClusters)[clusCount]) AliESDCaloCluster(*(dynamic_cast<AliESDCaloCluster*>(c)));
384 oc = new ((*fOutClusters)[clusCount]) AliAODCaloCluster(*(dynamic_cast<AliAODCaloCluster*>(c)));
386 oc->SetE(energyclus);
392 //________________________________________________________________________
393 void AliHadCorrTask::Terminate(Option_t *)
395 // Nothing to be done.