3 // Hadronic correction task.
5 // Author: R.Reed, C.Loizides
8 #include <TClonesArray.h>
12 #include <TLorentzVector.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 "AliPicoTrack.h"
21 #include "AliVEventHandler.h"
23 #include "AliHadCorrTask.h"
25 ClassImp(AliHadCorrTask)
27 //________________________________________________________________________
28 AliHadCorrTask::AliHadCorrTask() :
29 AliAnalysisTaskSE("AliHadCorrTask"),
42 fHistNclusMatchvsCent(0),
47 fHistNMatchCent_trk(0),
50 // Default constructor.
52 for(Int_t i=0; i<8; i++) {
54 fHistMatchEvsP[i] = 0;
55 fHistMatchdRvsEP[i] = 0;
56 for(Int_t j=0; j<3; j++) {
57 fHistEsubPch[i][j] = 0;
58 fHistEsubPchRat[i][j] = 0;
61 for(Int_t j=0; j<9; j++) {
62 fHistMatchEtaPhi[i][j] = 0;
68 //________________________________________________________________________
69 AliHadCorrTask::AliHadCorrTask(const char *name) :
70 AliAnalysisTaskSE(name),
71 fTracksName("Tracks"),
72 fCaloName("CaloClusters"),
73 fOutCaloName("CaloClustersCorr"),
83 fHistNclusMatchvsCent(0),
88 fHistNMatchCent_trk(0),
92 // Standard constructor.
94 for(Int_t i=0; i<8; i++) {
96 fHistMatchEvsP[i] = 0;
97 fHistMatchdRvsEP[i] = 0;
98 for(Int_t j=0; j<3; j++) {
99 fHistEsubPch[i][j] = 0;
100 fHistEsubPchRat[i][j] = 0;
103 for(Int_t j=0; j<9; j++) {
104 fHistMatchEtaPhi[i][j] = 0;
108 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
111 //________________________________________________________________________
112 AliHadCorrTask::AliHadCorrTask(const char *name, Bool_t histo) :
113 AliAnalysisTaskSE(name),
114 fTracksName("Tracks"),
115 fCaloName("CaloClusters"),
116 fOutCaloName("CaloClustersCorr"),
126 fHistNclusMatchvsCent(0),
131 fHistNMatchCent_trk(0),
135 // Standard constructor.
137 for(Int_t i=0; i<8; i++) {
139 fHistMatchEvsP[i] = 0;
140 fHistMatchdRvsEP[i] = 0;
141 for(Int_t j=0; j<3; j++) {
142 fHistEsubPch[i][j] = 0;
143 fHistEsubPchRat[i][j] = 0;
146 for(Int_t j=0; j<9; j++) {
147 fHistMatchEtaPhi[i][j] = 0;
151 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.";
154 DefineOutput(1, TList::Class());
157 //________________________________________________________________________
158 AliHadCorrTask::~AliHadCorrTask()
163 //________________________________________________________________________
164 Int_t AliHadCorrTask::GetCentBin(Double_t cent) const
166 // Get centrality bin.
169 if (cent>=0 && cent<10)
171 else if (cent>=10 && cent<30)
173 else if (cent>=30 && cent<50)
175 else if (cent>=50 && cent<=100)
181 //________________________________________________________________________
182 Int_t AliHadCorrTask::GetMomBin(Double_t p) const
189 else if (p>=0.5 && p<1.0)
191 else if (p>=1.0 && p<1.5)
193 else if (p>=1.5 && p<2.)
195 else if (p>=2. && p<3.)
197 else if (p>=3. && p<4.)
199 else if (p>=4. && p<5.)
201 else if (p>=5. && p<8.)
209 //________________________________________________________________________
210 Double_t AliHadCorrTask::GetEtaSigma(Int_t pbin) const
213 Double_t EtaSigma[9]={0.0097,0.0075,0.0059,0.0055,0.0053,0.005,0.005,0.045,0.042};
214 return 2.0*EtaSigma[pbin];
216 //________________________________________________________________________
217 Double_t AliHadCorrTask::GetPhiMean(Int_t pbin, Int_t centbin) const
221 Double_t PhiMean[9]={0.036,
230 return PhiMean[pbin];
231 }else if(centbin==1){
232 Double_t PhiMean[9]={0.036,
241 return PhiMean[pbin];
242 }else if(centbin==2){
243 Double_t PhiMean[9]={0.036,
252 return PhiMean[pbin];
253 }else if(centbin==3){
254 Double_t PhiMean[9]={0.036,
263 return PhiMean[pbin];
264 }else if(centbin==4){
265 Double_t PhiMean[9]={0.036,
274 return PhiMean[pbin]*(-1.);
275 }else if(centbin==5){
276 Double_t PhiMean[9]={0.036,
285 return PhiMean[pbin]*(-1.);
286 }else if(centbin==6){
287 Double_t PhiMean[9]={0.036,
296 return PhiMean[pbin]*(-1.);
297 }else if(centbin==7){
298 Double_t PhiMean[9]={0.036,
307 return PhiMean[pbin]*(-1.);
313 //________________________________________________________________________
314 Double_t AliHadCorrTask::GetPhiSigma(Int_t pbin, Int_t centbin) const
318 Double_t PhiSigma[9]={0.0221,
327 return 2.*PhiSigma[pbin];
328 }else if(centbin==1){
329 Double_t PhiSigma[9]={0.0217,
338 return 2.*PhiSigma[pbin];
339 }else if(centbin==2){
340 Double_t PhiSigma[9]={0.0211,
349 return 2.*PhiSigma[pbin];
350 }else if(centbin==3){
351 Double_t PhiSigma[9]={0.0215,
360 return 2.*PhiSigma[pbin];
361 }else if(centbin==4){
362 Double_t PhiSigma[9]={0.0199,
371 return 2.*PhiSigma[pbin];
372 }else if(centbin==5){
373 Double_t PhiSigma[9]={0.0200,
382 return 2.*PhiSigma[pbin];
383 }else if(centbin==6){
384 Double_t PhiSigma[9]={0.0202,
393 return 2.*PhiSigma[pbin];
394 }else if(centbin==7){
395 Double_t PhiSigma[9]={0.0205,
404 return 2.*PhiSigma[pbin];
411 //________________________________________________________________________
412 void AliHadCorrTask::UserCreateOutputObjects()
414 // Create my user objects.
416 AliVEventHandler* handler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
418 AliError("Input handler not available!");
422 if (handler->InheritsFrom("AliESDInputHandler")) {
423 fOutClusters = new TClonesArray("AliESDCaloCluster");
424 } else if (handler->InheritsFrom("AliAODInputHandler")) {
425 fOutClusters = new TClonesArray("AliAODCaloCluster");
427 AliError("Input handler not recognized!");
430 fOutClusters->SetName(fOutCaloName);
436 fOutputList = new TList();
437 fOutputList->SetOwner();
440 PostData(1, fOutputList);
444 for(Int_t icent=0; icent<8; ++icent) {
445 for(Int_t ipt=0; ipt<9; ++ipt) {
446 TString name(Form("fHistMatchEtaPhi_%i_%i",icent,ipt));
447 fHistMatchEtaPhi[icent][ipt] = new TH2F(name, name, 400, -0.2, 0.2, 1600, -0.8, 0.8);
448 fOutputList->Add(fHistMatchEtaPhi[icent][ipt]);
452 TString name(Form("fHistMatchEvsP_%i",icent));
453 fHistMatchEvsP[icent] = new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
454 fOutputList->Add(fHistMatchEvsP[icent]);
456 name = Form("fHistMatchdRvsEP_%i",icent);
457 fHistMatchdRvsEP[icent] = new TH2F(name, name, 1000, 0., 1., 1000, 0., 10.);
458 fOutputList->Add(fHistMatchdRvsEP[icent]);
460 for(Int_t itrk=0; itrk<3; ++itrk){
461 name = Form("fHistEsubPch_%i_%i",icent,itrk);
462 fHistEsubPch[icent][itrk]=new TH1F(name, name, 400, 0., 100.);
463 fHistEsubPch[icent][itrk]->Sumw2();
464 fOutputList->Add(fHistEsubPch[icent][itrk]);
466 name = Form("fHistEsubPchRat_%i_%i",icent,itrk);
467 fHistEsubPchRat[icent][itrk]=new TH2F(name, name, 400, 0., 200., 1000, 0., 10.);
468 fOutputList->Add(fHistEsubPchRat[icent][itrk]);
473 fHistCentrality = new TH1F("fHistCentrality", "Centrality", 100, 0, 100);
475 fHistNclusvsCent = new TH1F("Nclusvscent", "NclusVsCent", 100, 0, 100);
476 fHistNclusMatchvsCent = new TH1F("NclusMatchvscent", "NclusMatchVsCent", 100, 0, 100);
477 fHistEbefore = new TH1F("Ebefore", "Ebefore", 100, 0, 100);
478 fHistEafter = new TH1F("Eafter", "Eafter", 100, 0, 100);
479 fHistEoPCent = new TH2F("EoPCent", "EoPCent", 100, 0, 100, 1000, 0, 10);
480 fHistNMatchCent = new TH2F("NMatchesCent", "NMatchesCent", 100, 0, 100, 101, -0.5, 100.5);
481 fHistNMatchCent_trk = new TH2F("NMatchesCent_trk", "NMatchesCent_trk", 100, 0, 100, 101, -0.5, 100.5);
482 fOutputList->Add(fHistNclusMatchvsCent);
483 fOutputList->Add(fHistNclusvsCent);
484 fOutputList->Add(fHistEbefore);
485 fOutputList->Add(fHistEafter);
486 fOutputList->Add(fHistEoPCent);
487 fOutputList->Add(fHistNMatchCent);
488 fOutputList->Add(fHistNMatchCent_trk);
489 fOutputList->Add(fHistCentrality);
491 PostData(1, fOutputList);
494 //________________________________________________________________________
495 void AliHadCorrTask::UserExec(Option_t *)
497 // Execute per event.
499 // post output in event if not yet present
500 if (!(InputEvent()->FindListObject(fOutCaloName)))
501 InputEvent()->AddObject(fOutClusters);
504 fOutClusters->Delete();
507 Bool_t esdMode = kTRUE;
508 if (dynamic_cast<AliAODEvent*>(InputEvent()))
511 // optimization in case autobranch loading is off
512 AliAnalysisManager *am = AliAnalysisManager::GetAnalysisManager();
513 if (fCaloName == "CaloClusters")
514 am->LoadBranch("CaloClusters");
515 if (fTracksName == "Tracks")
516 am->LoadBranch("Tracks");
517 am->LoadBranch("Centrality");
519 TList *l = InputEvent()->GetList();
524 AliCentrality *centrality = InputEvent()->GetCentrality() ;
527 cent = centrality->GetCentralityPercentile("V0M");
529 cent=99; // probably pp data
532 AliError(Form("Centrality negative: %f", cent));
536 Int_t centbin = GetCentBin(cent);
539 fHistCentrality->Fill(cent);
541 // get input collections
542 TClonesArray *tracks = 0;
543 TClonesArray *clus = 0;
545 tracks = dynamic_cast<TClonesArray*>(l->FindObject(fTracksName));
547 AliError(Form("Pointer to tracks %s == 0", fTracksName.Data() ));
550 clus = dynamic_cast<TClonesArray*>(l->FindObject(fCaloName));
552 AliError(Form("Pointer to clus %s == 0", fCaloName.Data() ));
556 // get primary vertex
557 Double_t vertex[3] = {0, 0, 0};
558 InputEvent()->GetPrimaryVertex()->GetXYZ(vertex);
560 // loop over clusters and tracks
561 const Int_t Nclus = clus->GetEntries();
562 const Int_t Ntrks = tracks->GetEntries();
565 for(Int_t t = 0; t<Ntrks; ++t) {
566 AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
570 Double_t dEtaMin = 1e9;
571 Double_t dPhiMin = 1e9;
573 for(Int_t i=0; i < Nclus; ++i) {
574 AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
577 Double_t etadiff=999;
578 Double_t phidiff=999;
579 AliPicoTrack::GetEtaPhiDiff(track,c,phidiff,etadiff);
580 Double_t dR = TMath::Sqrt(etadiff*etadiff+phidiff*phidiff);
581 Double_t dRmin = TMath::Sqrt(dEtaMin*dEtaMin+dPhiMin*dPhiMin);
589 if (TMath::Abs(phidiff)<0.05 && TMath::Abs(etadiff)<0.025) { // pp cuts!!!
595 fHistNMatchCent_trk->Fill(cent,Nmatches);
597 track->SetEMCALcluster(imin);
602 for (Int_t iClus = 0, clusCount=0; iClus < Nclus; ++iClus) {
603 AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(iClus));
609 // make primary particle out of cluster
610 TLorentzVector nPart;
611 c->GetMomentum(nPart, vertex);
613 Double_t etclus = nPart.Pt();
617 Double_t energyclus = nPart.P();
619 // reset cluster/track matching
620 c->SetEmcCpvDistance(-1);
621 c->SetTrackDistance(999,999);
623 // run cluster-track matching
625 Double_t dEtaMin = 1e9;
626 Double_t dPhiMin = 1e9;
627 Double_t dRmin = 1e9;
628 Double_t totalTrkP = 0.0; // count total track momentum
629 Int_t Nmatches = 0; // count total number of matches
630 for (Int_t t = 0; t<Ntrks; ++t) {
632 AliVTrack *track = dynamic_cast<AliVTrack*>(tracks->At(t));
636 if (!track->IsEMCAL())
638 if (track->Pt() < fMinPt)
641 Double_t etadiff = 999;
642 Double_t phidiff = 999;
643 AliPicoTrack::GetEtaPhiDiff(track, c, phidiff, etadiff);
644 Double_t dR = TMath::Sqrt(etadiff * etadiff + phidiff * phidiff);
652 Double_t mom = track->P();
653 Int_t mombin = GetMomBin(mom);
654 Int_t centbinch = centbin;
655 if (track->Charge() == -1 || track->Charge() == 255)
659 if (fHadCorr > 1 && mombin > -1) {
660 fHistMatchEtaPhi[centbinch][mombin]->Fill(etadiff, phidiff);
661 fHistMatchdRvsEP[centbin]->Fill(dR, energyclus / mom);
665 Double_t EtaCut = 0.0;
666 Double_t PhiCutlo = 0.0;
667 Double_t PhiCuthi = 0.0;
669 PhiCutlo = -fPhiMatch;
670 PhiCuthi = fPhiMatch;
673 PhiCutlo = GetPhiMean(mombin,centbinch)-GetPhiSigma(mombin,centbin);
674 PhiCuthi = GetPhiMean(mombin,centbinch)+GetPhiSigma(mombin,centbin);
681 EtaCut = GetEtaSigma(mombin);
684 if ((phidiff < PhiCuthi && phidiff > PhiCutlo) && TMath::Abs(etadiff) < EtaCut) {
685 if((fDoTrackClus && (track->GetEMCALcluster()) == iClus) || !fDoTrackClus){
687 totalTrkP += track->P();
692 // store closest track
693 c->SetEmcCpvDistance(imin);
694 c->SetTrackDistance(dPhiMin, dEtaMin);
697 fHistNclusvsCent->Fill(cent);
698 fHistEbefore->Fill(cent, energyclus);
699 fHistNMatchCent->Fill(cent, Nmatches);
702 fHistNclusMatchvsCent->Fill(cent);
705 // apply correction / subtraction
707 // to subtract only the closest track set fHadCor to a %
708 // to subtract all tracks within the cut set fHadCor to %+1
711 Double_t EoP = energyclus / totalTrkP;
712 Double_t Esub = (fHadCorr-1)*totalTrkP;
713 if (Esub > energyclus)
717 fHistEoPCent->Fill(cent, EoP);
718 fHistMatchEvsP[centbin]->Fill(energyclus, EoP);
720 if (Nmatches == 1) fHistEsubPchRat[centbin][0]->Fill(totalTrkP,Esub/totalTrkP);
721 else if(Nmatches == 2) fHistEsubPchRat[centbin][1]->Fill(totalTrkP,Esub/totalTrkP);
722 else fHistEsubPchRat[centbin][2]->Fill(totalTrkP,Esub/totalTrkP);
724 if(Nmatches==1) fHistEsubPch[centbin][0]->Fill(totalTrkP,Esub);
725 else if(Nmatches==2) fHistEsubPch[centbin][1]->Fill(totalTrkP,Esub);
726 else fHistEsubPch[centbin][2]->Fill(totalTrkP,Esub);
729 energyclus -= (fHadCorr - 1) * totalTrkP;
731 else if (imin >= 0) {
732 AliVTrack *t = dynamic_cast<AliVTrack*>(tracks->At(imin));
734 Double_t mom = t->P();
735 Int_t mombin = GetMomBin(mom);
736 Int_t centbinch = centbin;
737 if (t->Charge() == -1 || t->Charge() == 255)
741 fHistMatchEtaPhi[centbinch][mombin]->Fill(dEtaMin, dPhiMin);
744 fHistMatchEvsP[centbin]->Fill(energyclus, energyclus / mom);
745 fHistEoPCent->Fill(cent, energyclus / mom);
746 fHistMatchdRvsEP[centbin]->Fill(dRmin, energyclus / mom);
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, centbin);
759 PhiCuthi = GetPhiMean(mombin, centbinch) + GetPhiSigma(mombin, centbin);
766 EtaCut = GetEtaSigma(mombin);
769 if ((dPhiMin<PhiCuthi && dPhiMin>PhiCutlo) && TMath::Abs(dEtaMin) < EtaCut) {
771 if((fDoTrackClus && (t->GetEMCALcluster()) == iClus) || !fDoTrackClus){
772 energyclus -= fHadCorr * t->P();
783 fHistEafter->Fill(cent, energyclus);
785 if (energyclus > 0) { // create corrected cluster
788 oc = new ((*fOutClusters)[clusCount]) AliESDCaloCluster(*(dynamic_cast<AliESDCaloCluster*>(c)));
790 oc = new ((*fOutClusters)[clusCount]) AliAODCaloCluster(*(dynamic_cast<AliAODCaloCluster*>(c)));
792 oc->SetE(energyclus);
798 PostData(1, fOutputList);
801 //________________________________________________________________________
802 void AliHadCorrTask::Terminate(Option_t *)
804 // Nothing to be done.