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),
42 fHistNMatchCent_trk(0),
46 // Default constructor.
48 for(Int_t i=0; i<8; i++) {
50 fHistEsubPchRat[i] = 0;
51 for(Int_t j=0; j<4; j++) {
52 fHistNCellsEnergy[i][j] = 0;
55 fHistMatchEvsP[i] = 0;
56 fHistMatchdRvsEP[i] = 0;
57 fHistNMatchEnergy[i] = 0;
59 for(Int_t j=0; j<9; j++) {
60 for(Int_t k=0; k<2; k++) {
61 fHistMatchEtaPhi[i][j][k] = 0;
67 //________________________________________________________________________
68 AliHadCorrTask::AliHadCorrTask(const char *name) :
69 AliAnalysisTaskEmcal(name, kFALSE),
70 fOutCaloName("CaloClustersCorr"),
78 fHistNclusMatchvsCent(0),
83 fHistNMatchCent_trk(0),
88 // Standard constructor.
90 for(Int_t i=0; i<8; i++) {
92 fHistEsubPchRat[i] = 0;
93 for(Int_t j=0; j<3; j++) {
97 fHistMatchEvsP[i] = 0;
98 fHistMatchdRvsEP[i] = 0;
101 for(Int_t j=0; j<9; j++) {
102 for(Int_t k=0; k<2; k++) {
103 fHistMatchEtaPhi[i][j][k] = 0;
107 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
110 //________________________________________________________________________
111 AliHadCorrTask::AliHadCorrTask(const char *name, Bool_t histo) :
112 AliAnalysisTaskEmcal(name, histo),
113 fOutCaloName("CaloClustersCorr"),
121 fHistNclusMatchvsCent(0),
126 fHistNMatchCent_trk(0),
128 fHistNoMatchEtaPhi(0)
131 // Standard constructor.
133 for(Int_t i=0; i<8; i++) {
135 fHistMatchEvsP[i] = 0;
136 fHistMatchdRvsEP[i] = 0;
137 for(Int_t j=0; j<3; j++) {
138 fHistNCellsEnergy[i][j] = 0;
142 fHistEsubPchRat[i] = 0;
143 for(Int_t j=0; j<9; j++) {
144 for(Int_t k=0; k<2; k++) {
145 fHistMatchEtaPhi[i][j][k] = 0;
150 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
153 //________________________________________________________________________
154 AliHadCorrTask::~AliHadCorrTask()
159 //________________________________________________________________________
160 Int_t AliHadCorrTask::GetMomBin(Double_t p) const
167 else if (p>=0.5 && p<1.0)
169 else if (p>=1.0 && p<1.5)
171 else if (p>=1.5 && p<2.)
173 else if (p>=2. && p<3.)
175 else if (p>=3. && p<4.)
177 else if (p>=4. && p<5.)
179 else if (p>=5. && p<8.)
187 //________________________________________________________________________
188 Double_t AliHadCorrTask::GetEtaSigma(Int_t pbin) const
192 Double_t EtaSigma[9]={0.0097,0.0075,0.0059,0.0055,0.0053,0.005,0.005,0.0045,0.0042};
193 return 2.0*EtaSigma[pbin];
196 //________________________________________________________________________
197 Double_t AliHadCorrTask::GetPhiMean(Int_t pbin, Int_t centbin) const
202 Double_t PhiMean[9]={0.036,
211 return PhiMean[pbin];
212 } else if (centbin==1) {
213 Double_t PhiMean[9]={0.036,
222 return PhiMean[pbin];
223 } else if (centbin==2) {
224 Double_t PhiMean[9]={0.036,
233 return PhiMean[pbin];
234 } else if (centbin==3) {
235 Double_t PhiMean[9]={0.036,
244 return PhiMean[pbin];
245 } else if (centbin==4) {
246 Double_t PhiMean[9]={0.036,
255 return PhiMean[pbin]*(-1.);
256 } else if (centbin==5) {
257 Double_t PhiMean[9]={0.036,
266 return PhiMean[pbin]*(-1.);
267 } else if (centbin==6) {
268 Double_t PhiMean[9]={0.036,
277 return PhiMean[pbin]*(-1.);
278 } else if (centbin==7) {
279 Double_t PhiMean[9]={0.036,
288 return PhiMean[pbin]*(-1.);
294 //________________________________________________________________________
295 Double_t AliHadCorrTask::GetPhiSigma(Int_t pbin, Int_t centbin) const
300 Double_t PhiSigma[9]={0.0221,
309 return 2.*PhiSigma[pbin];
310 } else if (centbin==1) {
311 Double_t PhiSigma[9]={0.0217,
320 return 2.*PhiSigma[pbin];
321 } else if (centbin==2) {
322 Double_t PhiSigma[9]={0.0211,
331 return 2.*PhiSigma[pbin];
332 } else if (centbin==3) {
333 Double_t PhiSigma[9]={0.0215,
342 return 2.*PhiSigma[pbin];
343 } else if (centbin==4) {
344 Double_t PhiSigma[9]={0.0199,
353 return 2.*PhiSigma[pbin];
354 } else if (centbin==5) {
355 Double_t PhiSigma[9]={0.0200,
364 return 2.*PhiSigma[pbin];
365 } else if (centbin==6) {
366 Double_t PhiSigma[9]={0.0202,
375 return 2.*PhiSigma[pbin];
376 } else if (centbin==7) {
377 Double_t PhiSigma[9]={0.0205,
386 return 2.*PhiSigma[pbin];
392 //________________________________________________________________________
393 void AliHadCorrTask::UserCreateOutputObjects()
395 // Create my user objects.
397 AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
399 AliError("Input handler not available!");
403 if (handler->InheritsFrom("AliESDInputHandler")) {
404 fOutClusters = new TClonesArray("AliESDCaloCluster");
405 } else if (handler->InheritsFrom("AliAODInputHandler")) {
406 fOutClusters = new TClonesArray("AliAODCaloCluster");
408 AliError("Input handler not recognized!");
411 fOutClusters->SetName(fOutCaloName);
417 fOutput = new TList();
422 for(Int_t icent=0; icent<8; ++icent) {
423 for(Int_t ipt=0; ipt<9; ++ipt) {
424 for(Int_t ieta=0; ieta<2; ++ieta) {
425 name = Form("fHistMatchEtaPhi_%i_%i_%i",icent,ipt,ieta);
426 fHistMatchEtaPhi[icent][ipt][ieta] = new TH2F(name, name, 200, -0.1, 0.1, 400, -0.2, 0.2);
427 fOutput->Add(fHistMatchEtaPhi[icent][ipt][ieta]);
431 for(Int_t itrk=0; itrk<4; ++itrk) {
432 name = Form("fHistNCellsEnergy_%i_%i",icent,itrk);
433 fHistNCellsEnergy[icent][itrk] = new TH2F(name, name, 1000, 0, 100, 101, -0.5, 100.5);
434 fOutput->Add(fHistNCellsEnergy[icent][itrk]);
437 name = Form("fHistEsubPch_%i",icent);
438 fHistEsubPch[icent]=new TH1F(name, name, 400, 0., 100.);
439 fOutput->Add(fHistEsubPch[icent]);
441 name = Form("fHistEsubPchRat_%i",icent);
442 fHistEsubPchRat[icent]=new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
443 fOutput->Add(fHistEsubPchRat[icent]);
446 name = Form("fHistMatchEvsP_%i",icent);
447 fHistMatchEvsP[icent] = new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
448 fOutput->Add(fHistMatchEvsP[icent]);
450 name = Form("fHistMatchdRvsEP_%i",icent);
451 fHistMatchdRvsEP[icent] = new TH2F(name, name, 1000, 0., 1., 1000, 0., 10.);
452 fOutput->Add(fHistMatchdRvsEP[icent]);
454 name = Form("fHistNMatchEnergy_%i",icent);
455 fHistNMatchEnergy[icent] = new TH2F(name, name, 1000, 0, 100, 101, -0.5, 100.5);
456 fOutput->Add(fHistNMatchEnergy[icent]);
460 fHistCentrality = new TH1F("fHistCentrality", "Centrality", 100, 0, 100);
461 fHistNclusvsCent = new TH1F("Nclusvscent", "NclusVsCent", 100, 0, 100);
462 fHistNclusMatchvsCent = new TH1F("NclusMatchvscent", "NclusMatchVsCent", 100, 0, 100);
463 fHistEbefore = new TH1F("Ebefore", "Ebefore", 100, 0, 100);
464 fHistEafter = new TH1F("Eafter", "Eafter", 100, 0, 100);
465 fHistEoPCent = new TH2F("EoPCent", "EoPCent", 100, 0, 100, 1000, 0, 10);
466 fHistNMatchCent = new TH2F("NMatchesCent", "NMatchesCent", 100, 0, 100, 11, -0.5, 10.5);
467 fHistNMatchCent_trk = new TH2F("NMatchesCent_trk", "NMatchesCent_trk", 100, 0, 100, 11, -0.5, 10.5);
468 fHistNoMatchEtaPhi = new TH2F("NoMatchEtaPhi", "NoMatchEtaPhi", 200, -1, 1, 90, 1, 4);
470 fOutput->Add(fHistNclusMatchvsCent);
471 fOutput->Add(fHistNclusvsCent);
472 fOutput->Add(fHistEbefore);
473 fOutput->Add(fHistEafter);
474 fOutput->Add(fHistEoPCent);
475 fOutput->Add(fHistNMatchCent);
476 fOutput->Add(fHistNMatchCent_trk);
477 fOutput->Add(fHistCentrality);
478 fOutput->Add(fHistNoMatchEtaPhi);
480 PostData(1, fOutput);
483 //________________________________________________________________________
484 void AliHadCorrTask::DoTrackClusLoop()
486 // Do the track cluster loop.
488 const Int_t Ntrks = fTracks->GetEntries();
490 // loop over all tracks
491 for (Int_t t = 0; t < Ntrks; ++t) {
492 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(t));
496 AliVTrack *track = emctrack->GetTrack();
499 if (!AcceptTrack(track))
502 Int_t Nclus = emctrack->GetNumberOfMatchedObj();
505 // loop over matched clusters
506 for (Int_t i = 0; i < Nclus; ++i) {
507 Int_t c = emctrack->GetMatchedObjId(i);
508 AliEmcalParticle *emccluster = static_cast<AliEmcalParticle*>(fCaloClusters->At(c));
512 AliVCluster *cluster = emccluster->GetCluster();
516 Double_t etadiff = 999;
517 Double_t phidiff = 999;
518 AliPicoTrack::GetEtaPhiDiff(track, cluster, phidiff, etadiff);
520 if (TMath::Abs(phidiff) < 0.050 && TMath::Abs(etadiff) < 0.025) // pp cuts!!!
524 fHistNMatchCent_trk->Fill(fCent, Nmatches);
526 if(Nmatches == 0 && track->Pt() > 2.0)
527 fHistNoMatchEtaPhi->Fill(track->GetTrackEtaOnEMCal(), track->GetTrackPhiOnEMCal());
531 //________________________________________________________________________
532 void AliHadCorrTask::DoMatchedTracksLoop(AliEmcalParticle *emccluster, Double_t &totalTrkP, Int_t &Nmatches)
534 // Do the loop over matched tracks for cluster emccluster.
536 AliVCluster *cluster = emccluster->GetCluster();
537 Int_t iClus = emccluster->IdInCollection();
538 Double_t energyclus = cluster->E();
540 // loop over matched tracks
541 const Int_t Ntrks = emccluster->GetNumberOfMatchedObj();
542 for (Int_t i = 0; i < Ntrks; ++i) {
543 Int_t iTrack = emccluster->GetMatchedObjId(i);
544 Double_t dR = emccluster->GetMatchedObjDistance(i);
546 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iTrack));
550 AliVTrack *track = emctrack->GetTrack();
553 if (!AcceptTrack(track))
556 Double_t etadiff = 999;
557 Double_t phidiff = 999;
558 AliPicoTrack::GetEtaPhiDiff(track, cluster, phidiff, etadiff);
560 Double_t mom = track->P();
561 Int_t mombin = GetMomBin(mom);
562 Int_t centbinch = fCentBin;
563 if (track->Charge()<0)
568 if(track->Eta() > 0) etabin=1;
570 fHistMatchEtaPhi[centbinch][mombin][etabin]->Fill(etadiff, phidiff);
573 Double_t etaCut = 0.0;
574 Double_t phiCutlo = 0.0;
575 Double_t phiCuthi = 0.0;
578 phiCutlo = -fPhiMatch;
579 phiCuthi = fPhiMatch;
582 phiCutlo = GetPhiMean(mombin, centbinch) - GetPhiSigma(mombin, fCentBin);
583 phiCuthi = GetPhiMean(mombin, centbinch) + GetPhiSigma(mombin, fCentBin);
590 etaCut = GetEtaSigma(mombin);
593 if ((phidiff < phiCuthi && phidiff > phiCutlo) && TMath::Abs(etadiff) < etaCut) {
594 if ((fDoTrackClus && (track->GetEMCALcluster()) == iClus) || !fDoTrackClus) {
596 totalTrkP += track->P();
599 if (fHadCorr > 1 && mombin > -1) {
600 fHistMatchdRvsEP[fCentBin]->Fill(dR, energyclus / mom);
608 //________________________________________________________________________
609 Bool_t AliHadCorrTask::Run()
611 // Run the hadronic correction
613 // post output in event if not yet present
614 if (!(InputEvent()->FindListObject(fOutCaloName)))
615 InputEvent()->AddObject(fOutClusters);
618 fOutClusters->Delete();
621 Bool_t esdMode = kTRUE;
622 if (dynamic_cast<AliAODEvent*>(InputEvent()))
625 if (esdMode) { // optimization in case autobranch loading is off
626 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
627 if (fCaloName == "CaloClusters")
628 am->LoadBranch("CaloClusters");
629 if (fTracksName == "Tracks")
630 am->LoadBranch("Tracks");
631 am->LoadBranch("Centrality");
635 fHistCentrality->Fill(fCent);
637 const Int_t Nclus = fCaloClusters->GetEntries();
639 if (fDoTrackClus && fCreateHisto)
642 // loop over all clusters
643 for (Int_t iClus = 0, clusCount=0; iClus < Nclus; ++iClus) {
644 AliEmcalParticle *emccluster = static_cast<AliEmcalParticle*>(fCaloClusters->At(iClus));
648 AliVCluster *cluster = emccluster->GetCluster();
651 if (!AcceptCluster(cluster))
654 Double_t energyclus = 0;
655 fHistEbefore->Fill(fCent, cluster->E());
657 // apply correction / subtraction
659 // to subtract only the closest track set fHadCor to a %
660 // to subtract all tracks within the cut set fHadCor to %+1
662 energyclus = ApplyHadCorrAllTracks(emccluster, fHadCorr - 1);
664 energyclus = ApplyHadCorrOneTrack(emccluster, fHadCorr);
670 if (energyclus > 0) { // create corrected cluster
673 AliESDCaloCluster *ec = dynamic_cast<AliESDCaloCluster*>(cluster);
676 oc = new ((*fOutClusters)[clusCount]) AliESDCaloCluster(*ec);
678 AliAODCaloCluster *ac = dynamic_cast<AliAODCaloCluster*>(cluster);
681 oc = new ((*fOutClusters)[clusCount]) AliAODCaloCluster(*ac);
683 oc->SetE(energyclus);
688 fHistEafter->Fill(fCent, energyclus);
695 //________________________________________________________________________
696 Double_t AliHadCorrTask::ApplyHadCorrOneTrack(AliEmcalParticle *emccluster, Double_t hadCorr)
698 // Apply the hadronic correction with one track only.
700 AliVCluster *cluster = emccluster->GetCluster();
702 Double_t energyclus = cluster->E();
703 Int_t iMin = emccluster->GetMatchedObjId();
708 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iMin));
712 Int_t cid = emctrack->GetMatchedObjId();
716 AliVTrack *track = emctrack->GetTrack();
720 Double_t mom = track->P();
724 Double_t dRmin = emccluster->GetMatchedObjDistance();
725 Double_t dEtaMin = 1e9;
726 Double_t dPhiMin = 1e9;
727 AliPicoTrack::GetEtaPhiDiff(track, cluster, dPhiMin, dEtaMin);
729 Int_t mombin = GetMomBin(mom);
730 Int_t centbinch = fCentBin;
731 if (track->Charge()<0)
734 // Plot some histograms if switched on
740 fHistMatchEtaPhi[centbinch][mombin][etabin]->Fill(dEtaMin, dPhiMin);
743 fHistMatchEvsP[fCentBin]->Fill(energyclus, energyclus / mom);
744 fHistEoPCent->Fill(fCent, energyclus / mom);
745 fHistMatchdRvsEP[fCentBin]->Fill(dRmin, energyclus / mom);
749 // Define eta/phi cuts
750 Double_t etaCut = 0.0;
751 Double_t phiCutlo = 0.0;
752 Double_t phiCuthi = 0.0;
754 phiCutlo = -fPhiMatch;
755 phiCuthi = fPhiMatch;
758 phiCutlo = GetPhiMean(mombin, centbinch) - GetPhiSigma(mombin, fCentBin);
759 phiCuthi = GetPhiMean(mombin, centbinch) + GetPhiSigma(mombin, fCentBin);
765 etaCut = GetEtaSigma(mombin);
768 // Apply the correction if the track is in the eta/phi window
769 if ((dPhiMin < phiCuthi && dPhiMin > phiCutlo) && TMath::Abs(dEtaMin) < etaCut) {
771 if ((fDoTrackClus && (track->GetEMCALcluster()) == emccluster->IdInCollection()) || !fDoTrackClus) {
772 energyclus -= hadCorr * mom;
779 //________________________________________________________________________
780 Double_t AliHadCorrTask::ApplyHadCorrAllTracks(AliEmcalParticle *emccluster, Double_t hadCorr)
782 // Apply the hadronic correction with all tracks.
784 AliVCluster *cluster = emccluster->GetCluster();
786 Double_t energyclus = cluster->E();
787 Double_t cNcells = cluster->GetNCells();
789 Double_t totalTrkP = 0.0; // count total track momentum
790 Int_t Nmatches = 0; // count total number of matches
792 // Do the loop over the matched tracks and get the number of matches and the total momentum
793 DoMatchedTracksLoop(emccluster, totalTrkP, Nmatches);
795 Double_t Esub = hadCorr * totalTrkP;
799 EoP = energyclus / totalTrkP;
801 // Plot some histograms if switched on
803 fHistNclusvsCent->Fill(fCent);
804 fHistNMatchCent->Fill(fCent, Nmatches);
805 fHistNMatchEnergy[fCentBin]->Fill(energyclus, Nmatches);
808 fHistNclusMatchvsCent->Fill(fCent);
811 fHistNCellsEnergy[fCentBin][0]->Fill(energyclus, cNcells);
812 else if(Nmatches == 1)
813 fHistNCellsEnergy[fCentBin][1]->Fill(energyclus, cNcells);
814 else if(Nmatches == 2)
815 fHistNCellsEnergy[fCentBin][2]->Fill(energyclus, cNcells);
817 fHistNCellsEnergy[fCentBin][3]->Fill(energyclus, cNcells);
820 fHistEoPCent->Fill(fCent, EoP);
821 fHistMatchEvsP[fCentBin]->Fill(energyclus, EoP);
825 Int_t iMin = emccluster->GetMatchedObjId();
826 AliEmcalParticle *emctrack = static_cast<AliEmcalParticle*>(fTracks->At(iMin));
827 AliVTrack *track = emctrack->GetTrack();
828 Int_t centbinchm = fCentBin;
829 if (track->Charge()<0)
833 fHistEsubPchRat[centbinchm]->Fill(totalTrkP, Esub / totalTrkP);
835 fHistEsubPch[centbinchm]->Fill(totalTrkP, Esub);
842 Double_t clusEexcl = fEexclCell * cNcells;
844 if (energyclus < clusEexcl)
845 clusEexcl = energyclus;
847 if (Esub > energyclus)
850 //applying Peter's proposed algorithm
851 //Never subtract the full energy of the cluster
852 if ((energyclus - Esub) < clusEexcl)
853 Esub = (energyclus - clusEexcl);
855 //apply the correction
861 void AliHadCorrTask::Terminate(Option_t *)
863 // Nothing to be done.