3 // Hadronic correction task.
5 // Author: R.Reed, C.Loizides, S.Aiola
8 #include <TClonesArray.h>
13 #include "AliAnalysisManager.h"
14 #include "AliAODEvent.h"
15 #include "AliAODCaloCluster.h"
16 #include "AliESDCaloCluster.h"
17 #include "AliVTrack.h"
18 #include "AliPicoTrack.h"
19 #include "AliVEventHandler.h"
20 #include "AliEmcalParticle.h"
22 #include "AliHadCorrTask.h"
24 ClassImp(AliHadCorrTask)
26 //________________________________________________________________________
27 AliHadCorrTask::AliHadCorrTask() :
28 AliAnalysisTaskEmcal("AliHadCorrTask", kFALSE),
37 fHistNclusMatchvsCent(0),
44 // Default constructor.
46 for(Int_t i=0; i<8; i++) {
48 fHistEsubPchRat[i] = 0;
49 for(Int_t j=0; j<4; j++) {
50 fHistNCellsEnergy[i][j] = 0;
53 fHistMatchEvsP[i] = 0;
54 fHistMatchdRvsEP[i] = 0;
55 fHistNMatchEnergy[i] = 0;
57 for(Int_t j=0; j<9; j++) {
58 for(Int_t k=0; k<2; k++) {
59 fHistMatchEtaPhi[i][j][k] = 0;
65 //________________________________________________________________________
66 AliHadCorrTask::AliHadCorrTask(const char *name, Bool_t histo) :
67 AliAnalysisTaskEmcal(name, histo),
68 fOutCaloName("CaloClustersCorr"),
76 fHistNclusMatchvsCent(0),
83 // Standard constructor.
85 for(Int_t i=0; i<8; i++) {
87 fHistMatchEvsP[i] = 0;
88 fHistMatchdRvsEP[i] = 0;
89 for(Int_t j=0; j<3; j++) {
90 fHistNCellsEnergy[i][j] = 0;
94 fHistEsubPchRat[i] = 0;
95 for(Int_t j=0; j<9; j++) {
96 for(Int_t k=0; k<2; k++) {
97 fHistMatchEtaPhi[i][j][k] = 0;
102 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
105 //________________________________________________________________________
106 AliHadCorrTask::~AliHadCorrTask()
111 //________________________________________________________________________
112 Int_t AliHadCorrTask::GetMomBin(Double_t p) const
119 else if (p>=0.5 && p<1.0)
121 else if (p>=1.0 && p<1.5)
123 else if (p>=1.5 && p<2.)
125 else if (p>=2. && p<3.)
127 else if (p>=3. && p<4.)
129 else if (p>=4. && p<5.)
131 else if (p>=5. && p<8.)
139 //________________________________________________________________________
140 Double_t AliHadCorrTask::GetEtaSigma(Int_t pbin) const
144 Double_t EtaSigma[9]={0.0097,0.0075,0.0059,0.0055,0.0053,0.005,0.005,0.0045,0.0042};
145 return 2.0*EtaSigma[pbin];
148 //________________________________________________________________________
149 Double_t AliHadCorrTask::GetPhiMean(Int_t pbin, Int_t centbin) const
154 Double_t PhiMean[9]={0.036,
163 return PhiMean[pbin];
164 } else if (centbin==1) {
165 Double_t PhiMean[9]={0.036,
174 return PhiMean[pbin];
175 } else if (centbin==2) {
176 Double_t PhiMean[9]={0.036,
185 return PhiMean[pbin];
186 } else if (centbin==3) {
187 Double_t PhiMean[9]={0.036,
196 return PhiMean[pbin];
197 } else if (centbin==4) {
198 Double_t PhiMean[9]={0.036,
207 return PhiMean[pbin]*(-1.);
208 } else if (centbin==5) {
209 Double_t PhiMean[9]={0.036,
218 return PhiMean[pbin]*(-1.);
219 } else if (centbin==6) {
220 Double_t PhiMean[9]={0.036,
229 return PhiMean[pbin]*(-1.);
230 } else if (centbin==7) {
231 Double_t PhiMean[9]={0.036,
240 return PhiMean[pbin]*(-1.);
246 //________________________________________________________________________
247 Double_t AliHadCorrTask::GetPhiSigma(Int_t pbin, Int_t centbin) const
252 Double_t PhiSigma[9]={0.0221,
261 return 2.*PhiSigma[pbin];
262 } else if (centbin==1) {
263 Double_t PhiSigma[9]={0.0217,
272 return 2.*PhiSigma[pbin];
273 } else if (centbin==2) {
274 Double_t PhiSigma[9]={0.0211,
283 return 2.*PhiSigma[pbin];
284 } else if (centbin==3) {
285 Double_t PhiSigma[9]={0.0215,
294 return 2.*PhiSigma[pbin];
295 } else if (centbin==4) {
296 Double_t PhiSigma[9]={0.0199,
305 return 2.*PhiSigma[pbin];
306 } else if (centbin==5) {
307 Double_t PhiSigma[9]={0.0200,
316 return 2.*PhiSigma[pbin];
317 } else if (centbin==6) {
318 Double_t PhiSigma[9]={0.0202,
327 return 2.*PhiSigma[pbin];
328 } else if (centbin==7) {
329 Double_t PhiSigma[9]={0.0205,
338 return 2.*PhiSigma[pbin];
344 //________________________________________________________________________
345 void AliHadCorrTask::UserCreateOutputObjects()
347 // Create my user objects.
349 AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
351 AliError(Form("%s: Input handler not available!", GetName()));
355 if (handler->InheritsFrom("AliESDInputHandler")) {
356 fOutClusters = new TClonesArray("AliESDCaloCluster");
357 } else if (handler->InheritsFrom("AliAODInputHandler")) {
358 fOutClusters = new TClonesArray("AliAODCaloCluster");
360 AliError(Form("%s: Input handler not recognized!", GetName()));
363 fOutClusters->SetName(fOutCaloName);
369 fOutput = new TList();
374 for(Int_t icent=0; icent<8; ++icent) {
375 for(Int_t ipt=0; ipt<9; ++ipt) {
376 for(Int_t ieta=0; ieta<2; ++ieta) {
377 name = Form("fHistMatchEtaPhi_%i_%i_%i",icent,ipt,ieta);
378 fHistMatchEtaPhi[icent][ipt][ieta] = new TH2F(name, name, 200, -0.1, 0.1, 400, -0.2, 0.2);
379 fOutput->Add(fHistMatchEtaPhi[icent][ipt][ieta]);
383 for(Int_t itrk=0; itrk<4; ++itrk) {
384 name = Form("fHistNCellsEnergy_%i_%i",icent,itrk);
385 fHistNCellsEnergy[icent][itrk] = new TH2F(name, name, 1000, 0, 100, 101, -0.5, 100.5);
386 fOutput->Add(fHistNCellsEnergy[icent][itrk]);
389 name = Form("fHistEsubPch_%i",icent);
390 fHistEsubPch[icent]=new TH1F(name, name, 400, 0., 100.);
391 fOutput->Add(fHistEsubPch[icent]);
393 name = Form("fHistEsubPchRat_%i",icent);
394 fHistEsubPchRat[icent]=new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
395 fOutput->Add(fHistEsubPchRat[icent]);
398 name = Form("fHistMatchEvsP_%i",icent);
399 fHistMatchEvsP[icent] = new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
400 fOutput->Add(fHistMatchEvsP[icent]);
402 name = Form("fHistMatchdRvsEP_%i",icent);
403 fHistMatchdRvsEP[icent] = new TH2F(name, name, 1000, 0., 1., 1000, 0., 10.);
404 fOutput->Add(fHistMatchdRvsEP[icent]);
406 name = Form("fHistNMatchEnergy_%i",icent);
407 fHistNMatchEnergy[icent] = new TH2F(name, name, 1000, 0, 100, 101, -0.5, 100.5);
408 fOutput->Add(fHistNMatchEnergy[icent]);
412 fHistCentrality = new TH1F("fHistCentrality", "Centrality", 100, 0, 100);
413 fHistNclusvsCent = new TH1F("Nclusvscent", "NclusVsCent", 100, 0, 100);
414 fHistNclusMatchvsCent = new TH1F("NclusMatchvscent", "NclusMatchVsCent", 100, 0, 100);
415 fHistEbefore = new TH1F("Ebefore", "Ebefore", 100, 0, 100);
416 fHistEafter = new TH1F("Eafter", "Eafter", 100, 0, 100);
417 fHistEoPCent = new TH2F("EoPCent", "EoPCent", 100, 0, 100, 1000, 0, 10);
418 fHistNMatchCent = new TH2F("NMatchesCent", "NMatchesCent", 100, 0, 100, 11, -0.5, 10.5);
420 fOutput->Add(fHistNclusMatchvsCent);
421 fOutput->Add(fHistNclusvsCent);
422 fOutput->Add(fHistEbefore);
423 fOutput->Add(fHistEafter);
424 fOutput->Add(fHistEoPCent);
425 fOutput->Add(fHistNMatchCent);
426 fOutput->Add(fHistCentrality);
428 PostData(1, fOutput);
431 //________________________________________________________________________
432 void AliHadCorrTask::DoMatchedTracksLoop(AliEmcalParticle *emccluster, Double_t &totalTrkP, Int_t &Nmatches)
434 // Do the loop over matched tracks for cluster emccluster.
436 AliVCluster *cluster = emccluster->GetCluster();
437 Int_t iClus = emccluster->IdInCollection();
438 Double_t energyclus = cluster->E();
440 // loop over matched tracks
441 const Int_t Ntrks = emccluster->GetNumberOfMatchedObj();
442 for (Int_t i = 0; i < Ntrks; ++i) {
443 Int_t iTrack = emccluster->GetMatchedObjId(i);
444 Double_t dR = emccluster->GetMatchedObjDistance(i);
446 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iTrack));
449 AliVTrack *track = emctrack->GetTrack();
452 if (!AcceptTrack(track))
455 // check if track also points to cluster
456 if (fDoTrackClus && (track->GetEMCALcluster()) != iClus)
459 Double_t etadiff = 999;
460 Double_t phidiff = 999;
461 AliPicoTrack::GetEtaPhiDiff(track, cluster, phidiff, etadiff);
463 Double_t mom = track->P();
464 Int_t mombin = GetMomBin(mom);
465 Int_t centbinch = fCentBin;
466 if (track->Charge()<0)
471 if(track->Eta() > 0) etabin=1;
472 fHistMatchEtaPhi[centbinch][mombin][etabin]->Fill(etadiff, phidiff);
475 Double_t etaCut = 0.0;
476 Double_t phiCutlo = 0.0;
477 Double_t phiCuthi = 0.0;
480 phiCutlo = -fPhiMatch;
481 phiCuthi = +fPhiMatch;
483 phiCutlo = GetPhiMean(mombin, centbinch) - GetPhiSigma(mombin, fCentBin);
484 phiCuthi = GetPhiMean(mombin, centbinch) + GetPhiSigma(mombin, fCentBin);
490 etaCut = GetEtaSigma(mombin);
493 if ((phidiff < phiCuthi && phidiff > phiCutlo) && TMath::Abs(etadiff) < etaCut) {
495 totalTrkP += track->P();
498 if (fHadCorr > 1 && mombin > -1) {
499 fHistMatchdRvsEP[fCentBin]->Fill(dR, energyclus / mom);
506 //________________________________________________________________________
507 Bool_t AliHadCorrTask::Run()
509 // Run the hadronic correction
511 // post output in event if not yet present
512 if (!(InputEvent()->FindListObject(fOutCaloName)))
513 InputEvent()->AddObject(fOutClusters);
516 fOutClusters->Delete();
519 Bool_t esdMode = kTRUE;
520 if (dynamic_cast<AliAODEvent*>(InputEvent()))
523 if (esdMode) { // optimization in case autobranch loading is off
524 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
525 if (fCaloName == "CaloClusters")
526 am->LoadBranch("CaloClusters");
527 if (fTracksName == "Tracks")
528 am->LoadBranch("Tracks");
529 am->LoadBranch("Centrality");
533 fHistCentrality->Fill(fCent);
536 // loop over all clusters
537 const Int_t Nclus = fCaloClusters->GetEntries();
538 for (Int_t iClus = 0, clusCount=0; iClus < Nclus; ++iClus) {
539 AliEmcalParticle *emccluster = static_cast<AliEmcalParticle*>(fCaloClusters->At(iClus));
543 AliVCluster *cluster = emccluster->GetCluster();
546 if (!AcceptCluster(cluster))
549 Double_t energyclus = 0;
551 fHistEbefore->Fill(fCent, cluster->E());
553 // apply correction / subtraction
555 // to subtract only the closest track set fHadCor to a %
556 // to subtract all tracks within the cut set fHadCor to %+1
558 energyclus = ApplyHadCorrAllTracks(emccluster, fHadCorr - 1);
560 energyclus = ApplyHadCorrOneTrack(emccluster, fHadCorr);
566 if (energyclus > 0) { // create corrected cluster
569 AliESDCaloCluster *ec = dynamic_cast<AliESDCaloCluster*>(cluster);
572 oc = new ((*fOutClusters)[clusCount]) AliESDCaloCluster(*ec);
574 AliAODCaloCluster *ac = dynamic_cast<AliAODCaloCluster*>(cluster);
577 oc = new ((*fOutClusters)[clusCount]) AliAODCaloCluster(*ac);
579 oc->SetE(energyclus);
584 fHistEafter->Fill(fCent, energyclus);
591 //________________________________________________________________________
592 Double_t AliHadCorrTask::ApplyHadCorrOneTrack(AliEmcalParticle *emccluster, Double_t hadCorr)
594 // Apply the hadronic correction with one track only.
596 AliVCluster *cluster = emccluster->GetCluster();
597 Double_t energyclus = cluster->E();
598 Int_t iMin = emccluster->GetMatchedObjId();
602 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iMin));
606 // check if track also points to cluster
607 Int_t cid = emctrack->GetMatchedObjId();
608 if (fDoTrackClus && (cid!=emccluster->IdInCollection()))
611 AliVTrack *track = emctrack->GetTrack();
615 Double_t mom = track->P();
619 Double_t dRmin = emccluster->GetMatchedObjDistance();
620 Double_t dEtaMin = 1e9;
621 Double_t dPhiMin = 1e9;
622 AliPicoTrack::GetEtaPhiDiff(track, cluster, dPhiMin, dEtaMin);
624 Int_t mombin = GetMomBin(mom);
625 Int_t centbinch = fCentBin;
626 if (track->Charge()<0)
629 // plot some histograms if switched on
635 fHistMatchEtaPhi[centbinch][mombin][etabin]->Fill(dEtaMin, dPhiMin);
638 fHistMatchEvsP[fCentBin]->Fill(energyclus, energyclus / mom);
639 fHistEoPCent->Fill(fCent, energyclus / mom);
640 fHistMatchdRvsEP[fCentBin]->Fill(dRmin, energyclus / mom);
644 // define eta/phi cuts
645 Double_t etaCut = 0.0;
646 Double_t phiCutlo = 0.0;
647 Double_t phiCuthi = 0.0;
649 phiCutlo = -fPhiMatch;
650 phiCuthi = +fPhiMatch;
653 phiCutlo = GetPhiMean(mombin, centbinch) - GetPhiSigma(mombin, fCentBin);
654 phiCuthi = GetPhiMean(mombin, centbinch) + GetPhiSigma(mombin, fCentBin);
660 etaCut = GetEtaSigma(mombin);
663 // apply the correction if the track is in the eta/phi window
664 if ((dPhiMin < phiCuthi && dPhiMin > phiCutlo) && TMath::Abs(dEtaMin) < etaCut) {
665 energyclus -= hadCorr * mom;
671 //________________________________________________________________________
672 Double_t AliHadCorrTask::ApplyHadCorrAllTracks(AliEmcalParticle *emccluster, Double_t hadCorr)
674 // Apply the hadronic correction with all tracks.
676 AliVCluster *cluster = emccluster->GetCluster();
678 Double_t energyclus = cluster->E();
679 Double_t cNcells = cluster->GetNCells();
681 Double_t totalTrkP = 0.0; // count total track momentum
682 Int_t Nmatches = 0; // count total number of matches
684 // do the loop over the matched tracks and get the number of matches and the total momentum
685 DoMatchedTracksLoop(emccluster, totalTrkP, Nmatches);
687 if(fCreateHisto && Nmatches == 0) {
688 fHistNclusvsCent->Fill(fCent);
689 fHistNCellsEnergy[fCentBin][0]->Fill(energyclus, cNcells);
695 Double_t Esub = hadCorr * totalTrkP;
697 Double_t clusEexcl = fEexclCell * cNcells;
699 if (energyclus < clusEexcl)
700 clusEexcl = energyclus;
702 if (Esub > energyclus)
705 // applying Peter's proposed algorithm
706 // never subtract the full energy of the cluster
707 if ((energyclus - Esub) < clusEexcl)
708 Esub = (energyclus - clusEexcl);
710 Double_t EoP = energyclus / totalTrkP;
712 // plot some histograms if switched on
714 fHistNMatchCent->Fill(fCent, Nmatches);
715 fHistNMatchEnergy[fCentBin]->Fill(energyclus, Nmatches);
718 fHistNclusMatchvsCent->Fill(fCent);
721 fHistNCellsEnergy[fCentBin][1]->Fill(energyclus, cNcells);
722 else if(Nmatches == 2)
723 fHistNCellsEnergy[fCentBin][2]->Fill(energyclus, cNcells);
724 else if(Nmatches > 2)
725 fHistNCellsEnergy[fCentBin][3]->Fill(energyclus, cNcells);
728 fHistEoPCent->Fill(fCent, EoP);
729 fHistMatchEvsP[fCentBin]->Fill(energyclus, EoP);
733 Int_t iMin = emccluster->GetMatchedObjId();
734 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iMin));
735 AliVTrack *track = emctrack->GetTrack();
736 Int_t centbinchm = fCentBin;
737 if (track->Charge()<0)
740 fHistEsubPchRat[centbinchm]->Fill(totalTrkP, Esub / totalTrkP);
741 fHistEsubPch[centbinchm]->Fill(totalTrkP, Esub);
745 // apply the correction