1 //_________________________________________________________________________
2 // Utility Class for transverse energy studies
3 // Base class for ESD analysis
4 // - reconstruction output
7 //*-- Authors: Oystein Djuvsland (Bergen), David Silvermyr (ORNL)
8 //_________________________________________________________________________
10 #include "AliAnalysisEtReconstructed.h"
11 #include "AliAnalysisEtCuts.h"
12 #include "AliESDtrack.h"
13 #include "AliEMCALTrack.h"
14 #include "AliESDCaloCluster.h"
16 #include "TGeoGlobalMagField.h"
18 #include "AliVEvent.h"
19 #include "AliESDEvent.h"
20 #include "AliESDtrackCuts.h"
21 #include "AliVParticle.h"
22 #include "TDatabasePDG.h"
24 #include "AliESDpid.h"
30 #include "AliAnalysisHadEtCorrections.h"
31 #include "AliAnalysisEtSelector.h"
33 #include "AliCentrality.h"
34 #include "AliPHOSGeoUtils.h"
35 #include "AliPHOSGeometry.h"
40 ClassImp(AliAnalysisEtReconstructed);
43 AliAnalysisEtReconstructed::AliAnalysisEtReconstructed() :
47 ,fHistChargedPionEnergyDeposit(0)
48 ,fHistProtonEnergyDeposit(0)
49 ,fHistAntiProtonEnergyDeposit(0)
50 ,fHistChargedKaonEnergyDeposit(0)
51 ,fHistMuonEnergyDeposit(0)
52 ,fHistRemovedEnergy(0)
54 ,fEMinCorrection(1.0/0.89)
55 ,fRecEffCorrection(1.0)
61 ,fHistChargedEnergyRemoved(0)
62 ,fHistNeutralEnergyRemoved(0)
63 ,fHistGammaEnergyAdded(0)
68 AliAnalysisEtReconstructed::~AliAnalysisEtReconstructed()
71 delete fHistChargedPionEnergyDeposit; /** Energy deposited in calorimeter by charged pions */
72 delete fHistProtonEnergyDeposit; /** Energy deposited in calorimeter by protons */
73 delete fHistAntiProtonEnergyDeposit; /** Energy deposited in calorimeter by anti-protons */
74 delete fHistChargedKaonEnergyDeposit; /** Energy deposited in calorimeter by charged kaons */
75 delete fHistMuonEnergyDeposit; /** Energy deposited in calorimeter by muons */
77 delete fHistRemovedEnergy; // removed energy
81 Int_t AliAnalysisEtReconstructed::AnalyseEvent(AliVEvent* ev)
87 AliFatal("ERROR: Event does not exist");
91 AliESDEvent *event = dynamic_cast<AliESDEvent*>(ev);
93 AliFatal("ERROR: ESD Event does not exist");
96 fSelector->SetEvent(event);
97 if (!fMatrixInitialized)
99 for (Int_t mod=0; mod<5; mod++) {
100 if (!event->GetPHOSMatrix(mod)) continue;
101 fGeoUtils->SetMisalMatrix(event->GetPHOSMatrix(mod),mod) ;
102 // std::cout << event->GetPHOSMatrix(mod) << std::endl;
103 Printf("PHOS geo matrix %p for module # %d is set\n", event->GetPHOSMatrix(mod), mod);
105 fMatrixInitialized = kTRUE;
111 cent = fCentrality->GetCentralityClass10("V0M");
112 fCentClass = fCentrality->GetCentralityClass10("V0M");
115 //Double_t protonMass = fgProtonMass;
117 for (Int_t iCluster = 0; iCluster < event->GetNumberOfCaloClusters(); iCluster++)
119 AliESDCaloCluster* cluster = event->GetCaloCluster(iCluster);
122 AliError(Form("ERROR: Could not get cluster %d", iCluster));
127 if(cluster->IsEMCAL()) continue;
129 if(!fSelector->CutMinEnergy(*cluster)) continue;
131 if (!fSelector->CutDistanceToBadChannel(*cluster)) continue;
136 cluster->GetPosition(pos);
139 Double_t distance = cluster->GetEmcCpvDistance();
140 Int_t trackMatchedIndex = cluster->GetTrackMatchedIndex();
141 if ( cluster->IsEMCAL() ) {
142 distance = CalcTrackClusterDistance(pos, &trackMatchedIndex, event);
145 Bool_t matched = false;
149 matched = !fSelector->CutTrackMatching(*cluster, r);
154 if (cluster->GetNTracksMatched() > 0 && trackMatchedIndex>=0)
156 AliVTrack *track = event->GetTrack(trackMatchedIndex);
158 AliError("Error: track does not exist");
161 const Double_t *pidWeights = track->PID();
163 Double_t maxpidweight = 0;
168 for (Int_t p =0; p < AliPID::kSPECIES; p++)
170 if (pidWeights[p] > maxpidweight)
172 maxpidweight = pidWeights[p];
176 if (fCuts->GetHistMakeTreeDeposit() && fTreeDeposit)
178 fEnergyDeposited = cluster->E();
179 fEnergyTPC = track->E();
180 fCharge = track->Charge();
181 fParticlePid = maxpid;
182 fPidProb = maxpidweight;
183 AliESDtrack *esdTrack = dynamic_cast<AliESDtrack*>(track);
185 AliError("Error: track does not exist");
188 if (esdTrack) fTrackPassedCut = fEsdtrackCutsTPC->AcceptTrack(esdTrack);
189 fTreeDeposit->Fill();
193 if (maxpidweight > fPidCut)
195 Float_t dist = TMath::Sqrt(pos[0]*pos[0] + pos[1]*pos[1]);
197 Float_t theta = TMath::ATan(pos[2]/dist)+TMath::Pi()/2;
199 Float_t et = cluster->E() * TMath::Sin(theta);
200 if (maxpid == AliPID::kProton)
203 if (track->Charge() == 1)
206 fHistProtonEnergyDeposit->Fill(cluster->E(), track->E());
208 else if (track->Charge() == -1)
211 fHistAntiProtonEnergyDeposit->Fill(cluster->E(), track->E());
214 else if (maxpid == AliPID::kPion)
217 fHistChargedPionEnergyDeposit->Fill(cluster->E(), track->E());
219 else if (maxpid == AliPID::kKaon)
222 fHistChargedKaonEnergyDeposit->Fill(cluster->E(), track->E());
224 else if (maxpid == AliPID::kMuon)
226 fHistMuonEnergyDeposit->Fill(cluster->E(), track->E());
237 //std::cout << x++ << std::endl;
238 fSparseClusters[0] = AliPID::kPhoton;
239 fSparseClusters[1] = 0;
241 //if (cluster->E() > fSingleCellEnergyCut && cluster->GetNCells() == fCuts->GetCommonSingleCell()) continue;
242 //if (cluster->E() < fClusterEnergyCut) continue;
243 cluster->GetPosition(pos);
247 fClusterPosition->Fill(p2.Phi(), p2.PseudoRapidity());
249 fTotNeutralEt += CalculateTransverseEnergy(cluster);
250 fNeutralMultiplicity++;
255 fChargedEnergyRemoved = GetChargedContribution(fNeutralMultiplicity);
256 fNeutralEnergyRemoved = GetNeutralContribution(fNeutralMultiplicity);
257 fHistChargedEnergyRemoved->Fill(fChargedEnergyRemoved, fNeutralMultiplicity);
258 fHistNeutralEnergyRemoved->Fill(fNeutralEnergyRemoved, fNeutralMultiplicity);
260 fGammaEnergyAdded = GetGammaContribution(fNeutralMultiplicity);
261 fHistGammaEnergyAdded->Fill(fGammaEnergyAdded, fNeutralMultiplicity);
263 Double_t removedEnergy = GetChargedContribution(fNeutralMultiplicity) + GetNeutralContribution(fNeutralMultiplicity) - GetGammaContribution(fNeutralMultiplicity);
264 fHistRemovedEnergy->Fill(removedEnergy);
266 fTotNeutralEt = fGeomCorrection * fEMinCorrection * (fTotNeutralEt - removedEnergy);
267 fTotNeutralEtAcc = fTotNeutralEt;
268 fTotEt = fTotChargedEt + fTotNeutralEt;
269 fTotEtAcc = fTotChargedEtAcc + fTotNeutralEtAcc;
271 fSparseEt[0] = fTotEt;
272 fSparseEt[1] = fTotNeutralEt;
273 fSparseEt[2] = fTotChargedEtAcc;
274 fSparseEt[3] = fMultiplicity;
275 fSparseEt[4] = fNeutralMultiplicity;
276 fSparseEt[5] = fChargedMultiplicity;
279 // Fill the histograms...
285 bool AliAnalysisEtReconstructed::CheckGoodVertex(AliVParticle* track)
291 AliError("ERROR: no track");
294 AliESDtrack *esdTrack = dynamic_cast<AliESDtrack*>(track);
296 AliError("ERROR: no track");
299 esdTrack->GetImpactParametersTPC(bxy,bz);
302 bool status = (TMath::Abs(track->Xv()) < fCuts->GetReconstructedVertexXCut()) &&
303 (TMath::Abs(track->Yv()) < fCuts->GetReconstructedVertexYCut()) &&
304 (TMath::Abs(track->Zv()) < fCuts->GetReconstructedVertexZCut()) &&
305 (TMath::Abs(bxy) < fCuts->GetReconstructedIPxyCut()) &&
306 (TMath::Abs(bz) < fCuts->GetReconstructedIPzCut());
311 void AliAnalysisEtReconstructed::Init()
313 AliAnalysisEt::Init();
314 fPidCut = fCuts->GetReconstructedPidCut();
315 TGeoGlobalMagField::Instance()->SetField(new AliMagF("Maps","Maps", 1., 1., AliMagF::k5kG));
317 cout<<"Warning! You have not set corrections. Your code will crash. You have to set the corrections."<<endl;
319 //fGeoUtils = new AliPHOSGeoUtils("PHOS", "noCPV");
320 fGeoUtils = AliPHOSGeometry::GetInstance("IHEP");
321 // ifstream f("badchannels.txt", ios::in);
322 TFile *f = TFile::Open("badchannels.root", "READ");
324 fBadMapM2 = (TH2I*)f->Get("bad_channels_m2");
325 fBadMapM3 = (TH2I*)f->Get("bad_channels_m3");
326 fBadMapM4 = (TH2I*)f->Get("bad_channels_m4");
329 bool AliAnalysisEtReconstructed::TrackHitsCalorimeter(AliVParticle* track, Double_t magField)
330 { // propagate track to detector radius
333 cout<<"Warning: track empty"<<endl;
336 AliESDtrack *esdTrack= dynamic_cast<AliESDtrack*>(track);
338 AliError("ERROR: no ESD track");
341 // Printf("Propagating track: eta: %f, phi: %f, pt: %f", esdTrack->Eta(), esdTrack->Phi(), esdTrack->Pt());
343 Bool_t prop = esdTrack->PropagateTo(fDetectorRadius, magField);
345 // if (prop) Printf("Track propagated, eta: %f, phi: %f, pt: %f", esdTrack->Eta(), esdTrack->Phi(), esdTrack->Pt());
347 TMath::Abs(esdTrack->Eta()) < fEtaCutAcc &&
348 esdTrack->Phi() > fPhiCutAccMin*TMath::Pi()/180. &&
349 esdTrack->Phi() < fPhiCutAccMax*TMath::Pi()/180.;
352 void AliAnalysisEtReconstructed::FillOutputList(TList* list)
353 { // add some extra histograms to the ones from base class
354 AliAnalysisEt::FillOutputList(list);
356 list->Add(fHistChargedPionEnergyDeposit);
357 list->Add(fHistProtonEnergyDeposit);
358 list->Add(fHistAntiProtonEnergyDeposit);
359 list->Add(fHistChargedKaonEnergyDeposit);
360 list->Add(fHistMuonEnergyDeposit);
362 list->Add(fHistRemovedEnergy);
363 list->Add(fClusterPosition);
365 list->Add(fHistChargedEnergyRemoved);
366 list->Add(fHistNeutralEnergyRemoved);
367 list->Add(fHistGammaEnergyAdded);
370 void AliAnalysisEtReconstructed::CreateHistograms()
371 { // add some extra histograms to the ones from base class
372 AliAnalysisEt::CreateHistograms();
374 Int_t nbinsEt = 1000;
378 // possibly change histogram limits
380 nbinsEt = fCuts->GetHistNbinsParticleEt();
381 minEt = fCuts->GetHistMinParticleEt();
382 maxEt = fCuts->GetHistMaxParticleEt();
386 histname = "fHistChargedPionEnergyDeposit" + fHistogramNameSuffix;
387 fHistChargedPionEnergyDeposit = new TH2F(histname.Data(), "Energy deposited by #pi^{+/-}", nbinsEt, minEt, maxEt, nbinsEt, minEt, maxEt);
388 fHistChargedPionEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
389 fHistChargedPionEnergyDeposit->SetYTitle("Energy of track");
391 histname = "fHistProtonEnergyDeposit" + fHistogramNameSuffix;
392 fHistProtonEnergyDeposit = new TH2F(histname.Data(), "Energy deposited by protons", nbinsEt, minEt, maxEt, nbinsEt, minEt, maxEt);
393 fHistProtonEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
394 fHistProtonEnergyDeposit->SetYTitle("Energy of track");
396 histname = "fHistAntiProtonEnergyDeposit" + fHistogramNameSuffix;
397 fHistAntiProtonEnergyDeposit = new TH2F(histname.Data(), "Energy deposited by anti-protons", nbinsEt, minEt, maxEt, nbinsEt, minEt, maxEt);
398 fHistAntiProtonEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
399 fHistAntiProtonEnergyDeposit->SetYTitle("Energy of track");
401 histname = "fHistChargedKaonEnergyDeposit" + fHistogramNameSuffix;
402 fHistChargedKaonEnergyDeposit = new TH2F(histname.Data(), "Energy deposited by K^{+/-}", nbinsEt, minEt, maxEt, nbinsEt, minEt, maxEt);
403 fHistChargedKaonEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
404 fHistChargedKaonEnergyDeposit->SetYTitle("Energy of track");
406 histname = "fHistMuonEnergyDeposit" + fHistogramNameSuffix;
407 fHistMuonEnergyDeposit = new TH2F(histname.Data(), "Energy deposited by #mu^{+/-}", nbinsEt, minEt, maxEt, nbinsEt, minEt, maxEt);
408 fHistMuonEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
409 fHistMuonEnergyDeposit->SetYTitle("Energy of track");
411 histname = "fHistRemovedEnergy" + fHistogramNameSuffix;
412 fHistRemovedEnergy = new TH1F(histname.Data(), histname.Data(), 1000, 0, 20);
413 //fHistMuonEnergyDeposit->SetXTitle("Energy deposited in calorimeter");
414 //fHistMuonEnergyDeposit->SetYTitle("Energy of track");
416 histname = "fClusterPosition" + fHistogramNameSuffix;
417 fClusterPosition = new TH2D(histname.Data(), "Position of accepted neutral clusters",1000, -2.0, -.5, 1000, -.13 , 0.13);
418 fClusterPosition->SetXTitle("Energy deposited in calorimeter");
419 fClusterPosition->SetYTitle("Energy of track");
422 histname = "fHistChargedEnergyRemoved" + fHistogramNameSuffix;
423 fHistChargedEnergyRemoved = new TH2D(histname.Data(), histname.Data(), 1000, .0, 30, 100, -0.5 , 99.5);
425 histname = "fHistNeutralEnergyRemoved" + fHistogramNameSuffix;
426 fHistNeutralEnergyRemoved = new TH2D(histname.Data(), histname.Data(), 1000, .0, 30, 100, -0.5 , 99.5);
428 histname = "fHistGammaEnergyAdded" + fHistogramNameSuffix;
429 fHistGammaEnergyAdded = new TH2D(histname.Data(), histname.Data(), 1000, .0, 30, 100, -0.5 , 99.5);
435 AliAnalysisEtReconstructed::CalcTrackClusterDistance(const Float_t clsPos[3],
437 const AliESDEvent *event)
438 { // calculate distance between cluster and closest track
440 Double_t trkPos[3] = {0,0,0};
442 Int_t bestTrkMatchId = -1;
443 Double_t distance = 9999; // init to a big number
446 Double_t distX = 0, distY = 0, distZ = 0;
448 for (Int_t iTrack = 0; iTrack < event->GetNumberOfTracks(); iTrack++) {
449 AliESDtrack *track = event->GetTrack(iTrack);
451 AliError(Form("ERROR: Could not get track %d", iTrack));
455 // check for approx. eta and phi range before we propagate..
458 AliEMCALTrack *emctrack = new AliEMCALTrack(*track);
459 if (!emctrack->PropagateToGlobal(clsPos[0],clsPos[1],clsPos[2],0.,0.) ) {
462 emctrack->GetXYZ(trkPos);
465 distX = clsPos[0]-trkPos[0];
466 distY = clsPos[1]-trkPos[1];
467 distZ = clsPos[2]-trkPos[2];
468 dist = TMath::Sqrt(distX*distX + distY*distY + distZ*distZ);
470 if (dist < distance) {
472 bestTrkMatchId = iTrack;
476 // printf("CalcTrackClusterDistance: bestTrkMatch %d origTrkMatch %d distance %f\n", bestTrkMatchId, *trkMatchId, distance);
477 *trkMatchId = bestTrkMatchId;
482 Bool_t AliAnalysisEtReconstructed::TooCloseToBadChannel(const AliESDCaloCluster &cluster) const
486 cluster.GetPosition(gPos);
488 TVector3 glVec(gPos);
489 fGeoUtils->GlobalPos2RelId(glVec, relId);
492 fGeoUtils->Global2Local(locVec, glVec, relId[0]);
493 // std::cout << fGeoUtils << std::endl;
494 //std::cout << relId[0] << " " << cluster.IsPHOS() << std::endl;
495 //std::cout << locVec[0] << " " << " " << locVec[1] << " " << locVec[2] << std::endl;
496 for (Int_t x = 0; x < fBadMapM2->GetNbinsX(); x++)
498 for (Int_t z = 0; z < fBadMapM2->GetNbinsY(); z++)
502 if (fBadMapM2->GetBinContent(x+1, z+1) != 0)
512 fGeoUtils->RelPosInModule(tmpRel, tmpX, tmpZ);
514 Float_t distance = TMath::Sqrt((tmpX-locVec[0])*(tmpX-locVec[0]) + (tmpZ - locVec[2])*(tmpZ-locVec[2]));
515 //Float_t distance = TMath::Sqrt((x-relId[3])*(x-relId[3]) + (z - relId[2])*(z-relId[2]));
517 if (distance < fCuts->GetPhosBadDistanceCut())
519 // std::cout << "Module 2, position: " << locVec[0] << ", " << locVec[2] << ", distance to bad channel: " << distance << ", number of cells: " << cluster.GetNCells() << std::endl;
526 if (fBadMapM3->GetBinContent(x+1, z+1) != 0)
536 fGeoUtils->RelPosInModule(tmpRel, tmpX, tmpZ);
538 Float_t distance = TMath::Sqrt((tmpX-locVec[0])*(tmpX-locVec[0]) + (tmpZ - locVec[2])*(tmpZ-locVec[2]));
540 // Float_t distance = TMath::Sqrt((x-locVec[0])*(x-locVec[0]) + (z - locVec[2])*(z-locVec[2]));
541 //Float_t distance = TMath::Sqrt((x-relId[3])*(x-relId[3]) + (z - relId[2])*(z-relId[2]));
542 if (distance < fCuts->GetPhosBadDistanceCut())
544 // std::cout << "Module 3, position: " << locVec[0] << ", " << locVec[2] << ", distance to bad channel: " << distance << ", number of cells: " << cluster.GetNCells() << std::endl;
551 if (fBadMapM4->GetBinContent(x+1, z+1) != 0)
561 fGeoUtils->RelPosInModule(tmpRel, tmpX, tmpZ);
563 Float_t distance = TMath::Sqrt((tmpX-locVec[0])*(tmpX-locVec[0]) + (tmpZ - locVec[2])*(tmpZ-locVec[2]));
565 // Float_t distance = TMath::Sqrt((x-locVec[0])*(x-locVec[0]) + (z - locVec[2])*(z-locVec[2]));
566 //Float_t distance = TMath::Sqrt((x-relId[3])*(x-relId[3]) + (z - relId[2])*(z-relId[2]));
567 if (distance < fCuts->GetPhosBadDistanceCut())
569 // std::cout << "Module 4, position: " << locVec[0] << ", " << locVec[2] << ", distance to bad channel: " << distance << ", number of cells: " << cluster.GetNCells() << std::endl;
587 Bool_t AliAnalysisEtReconstructed::TooCloseToBadChannel(const AliESDCaloCluster &cluster) const
592 cluster.GetPosition(gPos);
594 TVector3 glVec(gPos);
595 fGeoUtils->GlobalPos2RelId(glVec, relId);
597 fGeoUtils->Global2Local(locVec, glVec, relId[0]);
599 std::vector<Int_t>::const_iterator badIt;
601 for (Int_t x = 0; x < fBadMapM2->GetNbinsX(); x++)
603 for (Int_t z = 0; z < fBadMapM2->GetNbinsY(); z++)
607 if (fBadMapM2->GetBinContent(x+1, z+1) != 0)
610 Float_t distance = TMath::Sqrt((x-locVec[0])*(x-locVec[0]) + (z - locVec[2])*(z-locVec[2]));
611 if (distance < fCuts->GetPhosBadDistanceCut())
619 if (fBadMapM3->GetBinContent(x+1, z+1) != 0)
622 Float_t distance = TMath::Sqrt((x-locVec[0])*(x-locVec[0]) + (z - locVec[2])*(z-locVec[2]));
623 if (distance < fCuts->GetPhosBadDistanceCut())
631 if (fBadMapM4->GetBinContent(x+1, z+1) != 0)
634 Float_t distance = TMath::Sqrt((x-locVec[0])*(x-locVec[0]) + (z - locVec[2])*(z-locVec[2]));
635 if (distance < fCuts->GetPhosBadDistanceCut())