3 // Simulation EMCal task.
5 // Author: Saehanseul Oh
7 #include "AliAnalysisTaskSOH.h"
12 #include "AliAnalysisManager.h"
13 #include "AliAnalysisTask.h"
14 #include "AliEMCALRecoUtils.h"
15 #include "AliEMCALTrack.h"
16 #include "AliESDCaloCluster.h"
17 #include "AliESDEvent.h"
18 #include "AliESDInputHandler.h"
19 #include "AliESDtrack.h"
20 #include "AliESDtrackCuts.h"
21 #include "AliExternalTrackParam.h"
23 #include "AliMCEvent.h"
25 ClassImp(AliAnalysisTaskSOH)
27 //________________________________________________________________________
28 AliAnalysisTaskSOH::AliAnalysisTaskSOH() :
33 fHybridTrackCuts1(0x0),
34 fHybridTrackCuts2(0x0),
44 fHScaleFactor100HC(0),
46 fHEMCalResponsePion(0x0),
47 fHEMCalResponseElec(0x0),
48 fHEMCalResponseProton(0x0),
49 fHEMCalRecdPhidEta(0x0),
50 fHEMCalRecdPhidEtaP(0x0),
51 fHEMCalRecdPhidEtaM(0x0),
52 fHEMCalRecdPhidEta_Truth(0x0),
53 fHEMCalRecdPhidEtaP_Truth(0x0),
54 fHEMCalRecdPhidEtaM_Truth(0x0),
55 fHEMCalRecdPhidEtaposEta(0x0),
56 fHEMCalRecdPhidEtanegEta(0x0),
57 fHPhotonEdiff100HC(0x0),
58 fHPhotonEdiff0HC(0x0),
66 //________________________________________________________________________
67 AliAnalysisTaskSOH::AliAnalysisTaskSOH(const char *name) :
68 AliAnalysisTaskSE(name),
72 fHybridTrackCuts1(0x0),
73 fHybridTrackCuts2(0x0),
83 fHScaleFactor100HC(0),
85 fHEMCalResponsePion(0x0),
86 fHEMCalResponseElec(0x0),
87 fHEMCalResponseProton(0x0),
88 fHEMCalRecdPhidEta(0x0),
89 fHEMCalRecdPhidEtaP(0x0),
90 fHEMCalRecdPhidEtaM(0x0),
91 fHEMCalRecdPhidEta_Truth(0x0),
92 fHEMCalRecdPhidEtaP_Truth(0x0),
93 fHEMCalRecdPhidEtaM_Truth(0x0),
94 fHEMCalRecdPhidEtaposEta(0x0),
95 fHEMCalRecdPhidEtanegEta(0x0),
96 fHPhotonEdiff100HC(0x0),
97 fHPhotonEdiff0HC(0x0),
102 // Output slot #1 writes into a TH1 container
103 DefineOutput(1, TList::Class());
107 //________________________________________________________________________
108 AliAnalysisTaskSOH::~AliAnalysisTaskSOH()
112 delete fEsdTrackCuts;
113 delete fHybridTrackCuts1;
114 delete fHybridTrackCuts2;
115 delete fTrackIndices;
116 delete fClusterIndices;
117 delete fClusterArray;
121 //________________________________________________________________________
122 void AliAnalysisTaskSOH::UserCreateOutputObjects()
124 // Create histograms, called once.
128 fOutputList = new TList();
129 fOutputList->SetOwner(1);
131 fHEventStat = new TH1F("fHEventStat","Event statistics for analysis",8,0,8);
132 fHEventStat->GetXaxis()->SetBinLabel(1,"Event");
133 fHEventStat->GetXaxis()->SetBinLabel(2,"cluster");
134 fHEventStat->GetXaxis()->SetBinLabel(3,"good cluster");
135 fHEventStat->GetXaxis()->SetBinLabel(4,"cls/0-truth");
136 fHEventStat->GetXaxis()->SetBinLabel(5,"cls/1-truth");
137 fHEventStat->GetXaxis()->SetBinLabel(6,"cls/2-truth");
138 fHEventStat->GetXaxis()->SetBinLabel(7,"cls/2-goodtruth");
139 fHEventStat->GetXaxis()->SetBinLabel(8,"cls/>3-truth");
140 fOutputList->Add(fHEventStat);
142 fHTrkEffParGenPt = new TH1F("fHTrkEffParGenPt", "Particle level truth p_{T} distribution of generated primary charged pions;p_{T}^{gen} (GeV/c)",500,0.0,50.0);
143 fOutputList->Add(fHTrkEffParGenPt);
145 fHTrkEffDetGenPt = new TH1F("fHTrkEffDetGenPt", "Detector level truth p_{T} distribution of primary charged pions;p_{T}^{gen} (GeV/c)",500,0.0,50.0);
146 fOutputList->Add(fHTrkEffDetGenPt);
148 fHTrkEffDetRecPt = new TH1F("fHTrkEffDetRecPt", "Reconstructed track p_{T} distribution of primary charged pions;p_{T}^{rec} (GeV/c)",500,0.0,50.0);
149 fOutputList->Add(fHTrkEffDetRecPt);
151 fHScaleFactor = new TH1F("fHScaleFactor", "Scale factor distribution without hadronic correction;Scale factor",100,0,10);
152 fOutputList->Add(fHScaleFactor);
154 fHScaleFactor100HC = new TH1F("fHScaleFactor100HC", "Scale factor distribution with 100% hadronic correction;Scale factor",100,0,10);
155 fOutputList->Add(fHScaleFactor100HC);
157 fHEOverPVsPt = new TH2F("fHEOverPVsPt", "E/P vs track p_{T}; p_{T} (GeV/c); E/P", 200 , 0, 4, 200, 0, 3.2);
158 fOutputList->Add(fHEOverPVsPt);
160 fHEMCalResponsePion = new TH2F("fHEMCalResponsePion", "Pion E/P vs track p_{T}; p_{T} (GeV/c); E/P", 100 , 0, 4, 100, 0, 3.2);
161 fOutputList->Add(fHEMCalResponsePion);
163 fHEMCalResponseElec = new TH2F("fHEMCalResponseElec", "Electron E/P vs track p_{T}; p_{T} (GeV/c); E/P", 100 , 0, 4, 100, 0, 3.2);
164 fOutputList->Add(fHEMCalResponseElec);
166 fHEMCalResponseProton = new TH2F("fHEMCalResponseProton", "Proton E/P vs track p_{T}; p_{T} (GeV/c); E/P", 100 , 0, 4, 100, 0, 3.2);
167 fOutputList->Add(fHEMCalResponseProton);
169 fHEMCalRecdPhidEta = new TH2F("fHEMCalRecdPhidEta","EMCAL Cluster-Track #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
170 fOutputList->Add(fHEMCalRecdPhidEta);
172 fHEMCalRecdPhidEtaP = new TH2F("fHEMCalRecdPhidEtaP","EMCAL Charge+ Cluster-Track #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
173 fOutputList->Add(fHEMCalRecdPhidEtaP);
175 fHEMCalRecdPhidEtaM = new TH2F("fHEMCalRecdPhidEtaM","EMCAL Charge- Cluster-Track #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
176 fOutputList->Add(fHEMCalRecdPhidEtaM);
178 fHEMCalRecdPhidEta_Truth = new TH2F("fHEMCalRecdPhidEta_Truth","EMCAL Cluster-Track(Truth matched) #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
179 fOutputList->Add(fHEMCalRecdPhidEta_Truth);
181 fHEMCalRecdPhidEtaP_Truth = new TH2F("fHEMCalRecdPhidEtaP_Truth","EMCAL Charge+ Cluster-Track(Truth matched) #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
182 fOutputList->Add(fHEMCalRecdPhidEtaP_Truth);
184 fHEMCalRecdPhidEtaM_Truth = new TH2F("fHEMCalRecdPhidEtaM_Truth","EMCAL Charge- Cluster-Track(Truth matched) #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
185 fOutputList->Add(fHEMCalRecdPhidEtaM_Truth);
187 fHEMCalRecdPhidEtaposEta = new TH2F("fHEMCalRecdPhidEtaposEta","(+eta track) EMCAL Cluster-Track #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
188 fOutputList->Add(fHEMCalRecdPhidEtaposEta);
190 fHEMCalRecdPhidEtanegEta = new TH2F("fHEMCalRecdPhidEtanegEta","(-eta track) EMCAL Cluster-Track #Delta#phi-#Delta#eta; #Delta#eta; #Delta#phi",1000,-0.1,0.1,1000,-0.5,0.5);
191 fOutputList->Add(fHEMCalRecdPhidEtanegEta);
193 fHPhotonEdiff100HC = new TH2F("fHPhotonEdiff100HC","Photon (E_{Truth}- E_{calc,100% HC})/E_{Truth} vs. E_{Truth}; E_{Truth} (GeV); (E_{Truth}- E_{calc,100% HC})/E_{Truth}",500,0,5,500,0,1.1);
194 fOutputList->Add(fHPhotonEdiff100HC);
196 fHPhotonEdiff0HC = new TH2F("fHPhotonEdiff0HC","Photon (E_{Truth}- E_{calc,0% HC})/E_{Truth} vs. E_{Truth}; E_{Truth} (GeV); (E_{Truth}- E_{cls})/E_{Truth}",500,0,5,500,-5.1,1.1);
197 fOutputList->Add(fHPhotonEdiff0HC);
199 fHPhotonEVsClsE = new TH2F("fHPhotonEVsClsE","Cluster E vs. photon E_{Truth}; photon E_{Truth} (GeV); Cluster E (GeV)",500,0,5,500,0,5);
200 fOutputList->Add(fHPhotonEVsClsE);
202 fTrackIndices = new TArrayI();
203 fClusterIndices = new TArrayI();
205 fClusterArray = new TObjArray();
206 fClusterArray->SetOwner(1);
208 PostData(1, fOutputList);
211 //________________________________________________________________________
212 void AliAnalysisTaskSOH::UserExec(Option_t *)
214 // Main loop, called for each event.
217 fESD = dynamic_cast<AliESDEvent*>(InputEvent());
219 printf("ERROR: fESD not available\n");
225 printf("ERROR: fMC not available\n");
229 fHEventStat->Fill(0.5);
232 fTrackIndices->Reset();
234 fClusterIndices->Reset();
236 fClusterArray->Delete();
241 ProcessScaleFactor();
243 PostData(1, fOutputList);
246 //________________________________________________________________________
247 void AliAnalysisTaskSOH::ProcessTrack()
251 fTrackIndices->Set(fESD->GetNumberOfTracks());
252 AliDebug(3,Form("%s:%d Selecting tracks",(char*)__FILE__,__LINE__));
257 Float_t ClsPos[3] = {-999,-999,-999};
258 Double_t emcTrkpos[3] = {-999,-999,-999};
260 for(Int_t itr=0; itr<fESD->GetNumberOfTracks(); itr++)
262 AliESDtrack *esdtrack = fESD->GetTrack(itr);
263 if(!esdtrack)continue;
264 AliESDtrack *newTrack = GetAcceptTrack(esdtrack);
265 if(!newTrack) continue;
268 Int_t clsIndex = newTrack->GetEMCALcluster();
269 if(newTrack->GetEMCALcluster()>-1)
271 AliESDCaloCluster *cluster = fESD->GetCaloCluster(clsIndex);
272 if(IsGoodCluster(cluster))
276 cluster->GetPosition(ClsPos);
277 TVector3 VClsPos(ClsPos[0], ClsPos[1], ClsPos[2]);
279 AliEMCALTrack EMCTrk(*newTrack);
280 if(!EMCTrk.PropagateToGlobal(ClsPos[0], ClsPos[1], ClsPos[2], 0.0, 0.0)) {
283 EMCTrk.GetXYZ(emcTrkpos);
284 TVector3 VemcTrkPos(emcTrkpos[0],emcTrkpos[1],emcTrkpos[2]);
286 Double_t dPhi = VClsPos.Phi() - VemcTrkPos.Phi();
287 if (dPhi < -1*TMath::Pi()) dPhi += (2*TMath::Pi());
288 else if (dPhi > TMath::Pi()) dPhi -= (2*TMath::Pi());
290 Double_t dEta = VClsPos.Eta() - VemcTrkPos.Eta();
292 fHEMCalRecdPhidEta->Fill(dEta, dPhi);
294 if((newTrack->GetLabel())>-1 && (newTrack->GetLabel()) < fMC->GetNumberOfTracks())
296 AliVParticle *vParticle = fMC->GetTrack(newTrack->GetLabel());
297 if(IsGoodMcParticle(vParticle, newTrack->GetLabel()))
299 fHEMCalRecdPhidEta_Truth->Fill(dEta, dPhi);
300 if(vParticle->Charge() > 0) fHEMCalRecdPhidEtaP_Truth->Fill(dEta, dPhi);
301 if(vParticle->Charge() < 0) fHEMCalRecdPhidEtaM_Truth->Fill(dEta, dPhi);
305 if(esdtrack->Charge() > 0) {fHEMCalRecdPhidEtaP->Fill(dEta, dPhi);}
306 if(esdtrack->Charge() < 0) {fHEMCalRecdPhidEtaM->Fill(dEta, dPhi);}
308 if(VemcTrkPos.Eta() > 0) fHEMCalRecdPhidEtaposEta->Fill(dEta, dPhi);
309 if(VemcTrkPos.Eta() < 0) fHEMCalRecdPhidEtanegEta->Fill(dEta, dPhi);
312 if(newTrack->P()>0) fHEOverPVsPt->Fill(newTrack->Pt(),clsE/newTrack->P());
315 Int_t ipart = newTrack->GetLabel();
316 if(ipart>-1 && ipart<fMC->GetNumberOfTracks())
318 AliVParticle* vParticle = fMC->GetTrack(ipart);
319 if(isMth && vParticle)
321 if(TMath::Abs(vParticle->PdgCode())==211)
323 fHEMCalResponsePion->Fill(newTrack->Pt(),clsE/newTrack->P());
325 if(TMath::Abs(vParticle->PdgCode())==11)
327 fHEMCalResponseElec->Fill(newTrack->Pt(),clsE/newTrack->P());
329 if(TMath::Abs(vParticle->PdgCode())==2212)
331 fHEMCalResponseProton->Fill(newTrack->Pt(),clsE/newTrack->P());
336 fTrackIndices->AddAt(itr,nTracks);
340 fTrackIndices->Set(nTracks);
343 //________________________________________________________________________
344 void AliAnalysisTaskSOH::ProcessCluster()
349 TLorentzVector gamma;
350 Double_t vertex[3] = {0, 0, 0};
351 fESD->GetVertex()->GetXYZ(vertex);
352 const Int_t nCaloClusters = fESD->GetNumberOfCaloClusters();
353 fClusterIndices->Set(nCaloClusters);
355 for(Int_t itr=0; itr<nCaloClusters; itr++)
357 fHEventStat->Fill(1.5);
358 AliESDCaloCluster *cluster = fESD->GetCaloCluster(itr);
359 if(!IsGoodCluster(cluster)) continue;
360 cluster->GetMomentum(gamma, vertex);
361 if (gamma.Pt() < 0.15) continue;
362 fHEventStat->Fill(2.5);
364 TArrayI *MCLabels = cluster->GetLabelsArray();
366 if(MCLabels->GetSize() == 0) fHEventStat->Fill(3.5);
367 if(MCLabels->GetSize() == 1) fHEventStat->Fill(4.5);
368 if(MCLabels->GetSize() == 2)
370 fHEventStat->Fill(5.5);
371 AliVParticle* vParticle1 = fMC->GetTrack(MCLabels->GetAt(0));
372 AliVParticle* vParticle2 = fMC->GetTrack(MCLabels->GetAt(1));
373 if(IsGoodMcParticle(vParticle1, MCLabels->GetAt(0)) && IsGoodMcParticle(vParticle2, MCLabels->GetAt(1)))
375 fHEventStat->Fill(6.5);
376 if((vParticle1->PdgCode()==22) && (vParticle2->PdgCode()==22)) {;}
377 else if((vParticle1->PdgCode()!=22) && (vParticle2->PdgCode()!=22)) {;}
380 fClusterIndices->AddAt(itr,nCluster);
385 if(MCLabels->GetSize() > 2) fHEventStat->Fill(7.5);
387 AliESDCaloCluster *newCluster = new AliESDCaloCluster(*cluster);
390 TArrayI arrayTrackMatched(fTrackIndices->GetSize());
391 Int_t nGoodMatch = 0;
393 for(Int_t j=0; j<fTrackIndices->GetSize(); j++)
395 AliESDtrack *trk = fESD->GetTrack(fTrackIndices->At(j));
396 if(itr==trk->GetEMCALcluster())
398 arrayTrackMatched[nGoodMatch] = j;
404 arrayTrackMatched.Set(nGoodMatch);
405 newCluster->AddTracksMatched(arrayTrackMatched);
407 Double_t clsE = newCluster->E();
408 Double_t newE = clsE-subE;
410 newCluster->SetDispersion(newE);
411 fClusterArray->Add(newCluster);
414 fClusterIndices->Set(nCluster);
416 //________________________________________________________________________
417 void AliAnalysisTaskSOH::ProcessMc()
421 for(Int_t ipart=0; ipart<fMC->GetNumberOfTracks(); ipart++)
423 AliVParticle* vParticle = fMC->GetTrack(ipart);
424 if(!IsGoodMcParticle(vParticle, ipart)) continue;
425 Int_t pdgCode = vParticle->PdgCode();
428 if(TMath::Abs(vParticle->Eta())<0.9)
430 if(TMath::Abs(pdgCode==211)) fHTrkEffParGenPt->Fill(vParticle->Pt());
431 for(Int_t j=0; j<fTrackIndices->GetSize(); j++)
433 AliESDtrack *esdtrack = fESD->GetTrack(fTrackIndices->At(j));
434 if(esdtrack && esdtrack->GetLabel()==ipart)
436 if(TMath::Abs(pdgCode==211))
438 fHTrkEffDetGenPt->Fill(vParticle->Pt());
439 fHTrkEffDetRecPt->Fill(esdtrack->Pt());
442 //cluster E vs. truth photon energy
443 for(Int_t k=0; k<fClusterIndices->GetSize(); k++)
445 AliESDCaloCluster *cluster = fESD->GetCaloCluster(fClusterIndices->At(k));
446 Double_t clsE = cluster->E();
447 TArrayI *MCLabels = cluster->GetLabelsArray();
448 AliVParticle* vParticle1 = fMC->GetTrack(MCLabels->GetAt(0));
449 AliVParticle* vParticle2 = fMC->GetTrack(MCLabels->GetAt(1));
451 if(vParticle1->PdgCode()==22 && vParticle2 == vParticle)
453 fHPhotonEdiff0HC->Fill(vParticle1->E(), (vParticle1->E() - clsE)/vParticle1->E());
454 fHPhotonEVsClsE->Fill(vParticle1->E(), clsE);
455 if((clsE - esdtrack->E())<0) fHPhotonEdiff100HC->Fill(vParticle1->E(), 1);
456 else fHPhotonEdiff100HC->Fill(vParticle1->E(), (vParticle1->E() + esdtrack->E() - clsE)/vParticle1->E());
459 if(vParticle2->PdgCode()==22 && vParticle1 == vParticle)
461 fHPhotonEdiff0HC->Fill(vParticle2->E(), (vParticle2->E() - clsE)/vParticle2->E());
462 fHPhotonEVsClsE->Fill(vParticle2->E(), clsE);
463 if((clsE-esdtrack->E())<0) fHPhotonEdiff100HC->Fill(vParticle2->E(), 1);
464 else fHPhotonEdiff100HC->Fill(vParticle2->E(), (vParticle2->E() + esdtrack->E() - clsE)/vParticle2->E());
474 //________________________________________________________________________
475 void AliAnalysisTaskSOH::ProcessScaleFactor()
479 const Double_t phiMax = 180 * TMath::DegToRad();
480 const Double_t phiMin = 80 * TMath::DegToRad();
481 const Double_t TPCArea= 2*TMath::Pi()*1.8;
482 const Double_t EMCArea = (phiMax-phiMin)*1.4;
487 for(Int_t j=0; j<fTrackIndices->GetSize(); j++)
489 AliESDtrack *trk = fESD->GetTrack(fTrackIndices->At(j));
490 Double_t eta = trk->Eta();
491 Double_t phi = trk->Phi();
492 if(TMath::Abs(eta)<0.9) PtTPC += trk->Pt();
493 if(TMath::Abs(eta)<0.7 && phi > phiMin && phi < phiMax ) PtEMC += trk->Pt();
496 Double_t EtWithHadCorr = 0;
497 Double_t EtWithoutHadCorr = 0;
498 Double_t vertex[3] = {0, 0, 0};
499 fESD->GetVertex()->GetXYZ(vertex);
500 TLorentzVector gamma;
502 for(Int_t i=0; i<fClusterArray->GetEntriesFast(); i++)
504 AliESDCaloCluster *cluster = (AliESDCaloCluster*)fClusterArray->At(i);
505 cluster->GetMomentum(gamma, vertex);
506 Double_t sinTheta = TMath::Sqrt(1-TMath::Power(gamma.CosTheta(),2));
507 EtWithoutHadCorr += cluster->E() * sinTheta;
508 EtWithHadCorr += cluster->GetDispersion() * sinTheta;
513 fHScaleFactor->Fill((PtEMC+EtWithoutHadCorr)/EMCArea * TPCArea/PtTPC);
514 fHScaleFactor100HC->Fill((PtEMC+EtWithHadCorr)/EMCArea * TPCArea/PtTPC);
518 //________________________________________________________________________
519 AliESDtrack *AliAnalysisTaskSOH::GetAcceptTrack(AliESDtrack *esdtrack)
521 // Get accepted track.
523 static AliESDtrack newTrack;
524 if(fEsdTrackCuts->AcceptTrack(esdtrack))
526 esdtrack->Copy(newTrack);
527 newTrack.SetTRDQuality(0);
529 else if(fHybridTrackCuts1->AcceptTrack(esdtrack))
531 if(esdtrack->GetConstrainedParam())
533 esdtrack->Copy(newTrack);
534 const AliExternalTrackParam* constrainParam = esdtrack->GetConstrainedParam();
535 newTrack.Set(constrainParam->GetX(),constrainParam->GetAlpha(),constrainParam->GetParameter(),constrainParam->GetCovariance());
536 newTrack.SetTRDQuality(1);
541 else if(fHybridTrackCuts2->AcceptTrack(esdtrack))
543 if(esdtrack->GetConstrainedParam())
545 esdtrack->Copy(newTrack);
546 const AliExternalTrackParam* constrainParam = esdtrack->GetConstrainedParam();
547 newTrack.Set(constrainParam->GetX(),constrainParam->GetAlpha(),constrainParam->GetParameter(),constrainParam->GetCovariance());
548 newTrack.SetTRDQuality(2);
561 //________________________________________________________________________
562 Bool_t AliAnalysisTaskSOH::IsGoodMcParticle(AliVParticle* vParticle, Int_t ipart)
564 // Return true if good MC particle.
566 if(!vParticle) return kFALSE;
567 if(!fMC->IsPhysicalPrimary(ipart)) return kFALSE;
568 if (TMath::Abs(vParticle->Eta())>2) return kFALSE;
569 if(vParticle->Pt()<0.15) return kFALSE;
573 //________________________________________________________________________
574 Bool_t AliAnalysisTaskSOH::IsGoodCluster(AliESDCaloCluster *cluster)
576 // Return true if good cluster.
578 if(!cluster) return kFALSE;
579 if (!cluster->IsEMCAL()) return kFALSE;
583 //________________________________________________________________________
584 void AliAnalysisTaskSOH::Terminate(Option_t *)
586 // Terminate analysis.