10 #if !defined( __CINT__) || defined(__MAKECINT__) 20 #include <TParticle.h> 22 #include "AliRunLoader.h" 23 #include "AliLoader.h" 24 #include "AliESDEvent.h" 26 #include "AliESDcascade.h" 27 #include "AliESDMuonTrack.h" 28 #include "AliESDCaloCluster.h" 31 #include "AliHeader.h" 32 #include "AliGenEventHeader.h" 56 const char* xLabel = NULL,
57 const char* yLabel = NULL)
60 TH1F* result =
new TH1F(name, title, nBins, xMin, xMax);
61 result->SetOption(
"E");
62 if (xLabel) result->GetXaxis()->SetTitle(xLabel);
63 if (yLabel) result->GetYaxis()->SetTitle(yLabel);
64 result->SetMarkerStyle(kFullCircle);
81 Int_t nBins = hGen->GetNbinsX();
82 TH1* hEff =
static_cast<TH1*
>(hGen->Clone(
"hEff"));
84 hEff->SetStats(kFALSE);
86 hEff->SetMaximum(110.);
87 hEff->GetYaxis()->SetTitle(
"#epsilon [%]");
89 for (
Int_t iBin = 0; iBin <= nBins; iBin++) {
90 Double_t nGen = hGen->GetBinContent(iBin);
91 Double_t nRec = hRec->GetBinContent(iBin);
94 hEff->SetBinContent(iBin, 100. * eff);
95 Double_t error = sqrt(eff*(1.-eff) / nGen);
96 if (error == 0) error = 0.0001;
97 hEff->SetBinError(iBin, 100. * error);
99 hEff->SetBinContent(iBin, -100.);
100 hEff->SetBinError(iBin, 0);
120 static TF1* fitFunc =
new TF1(
"fitFunc",
"gaus");
121 fitFunc->SetLineWidth(2);
122 fitFunc->SetFillStyle(0);
125 if (histo->Integral() <= 50)
return false;
127 Float_t mean = histo->GetMean();
129 fitFunc->SetRange(mean - maxFitRange*rms, mean + maxFitRange*rms);
130 fitFunc->SetParameters(mean, rms);
131 histo->Fit(fitFunc,
"QRI0");
132 histo->GetFunction(
"fitFunc")->ResetBit(1<<9);
133 res = TMath::Abs(fitFunc->GetParameter(2));
134 resError = TMath::Abs(fitFunc->GetParError(2));
148 const char* esdFileName =
"AliESDs.root")
153 Int_t checkNGenLow = 1;
176 Double_t checkEMCALEnergyLow = 0.05;
177 Double_t checkEMCALEnergyHigh = 1.0;
191 AliRunLoader* runLoader = AliRunLoader::Open(gAliceFileName);
193 Error(
"CheckESD",
"getting run loader from file %s failed",
197 runLoader->LoadgAlice();
198 gAlice = runLoader->GetAliRun();
200 Error(
"CheckESD",
"no galice object found");
203 runLoader->LoadKinematics();
204 runLoader->LoadHeader();
207 TFile* esdFile = TFile::Open(esdFileName);
208 if (!esdFile || !esdFile->IsOpen()) {
209 Error(
"CheckESD",
"opening ESD file %s failed", esdFileName);
213 TTree* tree = (
TTree*) esdFile->Get(
"esdTree");
215 Error(
"CheckESD",
"no ESD tree found");
218 esd->ReadFromTree(tree);
224 TH1F* hGen =
CreateHisto(
"hGen",
"generated tracks",
225 nBinsPt, minPt, maxPt,
"p_{t} [GeV/c]",
"N");
226 TH1F* hRec =
CreateHisto(
"hRec",
"reconstructed tracks",
227 nBinsPt, minPt, maxPt,
"p_{t} [GeV/c]",
"N");
232 TH1F* hResPtInv =
CreateHisto(
"hResPtInv",
"", 100, -10, 10,
233 "(p_{t,rec}^{-1}-p_{t,sim}^{-1}) / p_{t,sim}^{-1} [%]",
"N");
234 TH1F* hResPhi =
CreateHisto(
"hResPhi",
"", 100, -20, 20,
235 "#phi_{rec}-#phi_{sim} [mrad]",
"N");
236 TH1F* hResTheta =
CreateHisto(
"hResTheta",
"", 100, -20, 20,
237 "#theta_{rec}-#theta_{sim} [mrad]",
"N");
240 Int_t partCode[AliPID::kSPECIES] =
241 {kElectron, kMuonMinus, kPiPlus, kKPlus,
kProton};
242 const char* partName[AliPID::kSPECIES+1] =
243 {
"electron",
"muon",
"pion",
"kaon",
"proton",
"other"};
244 Double_t partFrac[AliPID::kSPECIES] =
245 {0.01, 0.01, 0.85, 0.10, 0.05};
246 Int_t identified[AliPID::kSPECIES+1][AliPID::kSPECIES];
247 for (
Int_t iGen = 0; iGen < AliPID::kSPECIES+1; iGen++) {
248 for (
Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
249 identified[iGen][iRec] = 0;
252 Int_t nIdentified = 0;
255 TH2F* hDEdxRight =
new TH2F(
"hDEdxRight",
"", 300, 0, 3, 100, 0, 400);
256 hDEdxRight->SetStats(kFALSE);
257 hDEdxRight->GetXaxis()->SetTitle(
"p [GeV/c]");
258 hDEdxRight->GetYaxis()->SetTitle(
"dE/dx_{TPC}");
259 hDEdxRight->SetMarkerStyle(kFullCircle);
260 hDEdxRight->SetMarkerSize(0.4);
261 TH2F* hDEdxWrong =
new TH2F(
"hDEdxWrong",
"", 300, 0, 3, 100, 0, 400);
262 hDEdxWrong->SetStats(kFALSE);
263 hDEdxWrong->GetXaxis()->SetTitle(
"p [GeV/c]");
264 hDEdxWrong->GetYaxis()->SetTitle(
"dE/dx_{TPC}");
265 hDEdxWrong->SetMarkerStyle(kFullCircle);
266 hDEdxWrong->SetMarkerSize(0.4);
267 hDEdxWrong->SetMarkerColor(kRed);
268 TH1F* hResTOFRight =
CreateHisto(
"hResTOFRight",
"", 100, -1000, 1000,
269 "t_{TOF}-t_{track} [ps]",
"N");
270 TH1F* hResTOFWrong =
CreateHisto(
"hResTOFWrong",
"", 100, -1000, 1000,
271 "t_{TOF}-t_{track} [ps]",
"N");
272 hResTOFWrong->SetLineColor(kRed);
275 TH1F* hEPHOS =
CreateHisto(
"hEPHOS",
"PHOS", 100, 0, 50,
"E [GeV]",
"N");
276 TH1F* hEEMCAL =
CreateHisto(
"hEEMCAL",
"EMCAL", 100, 0, 50,
"E [GeV]",
"N");
279 TH1F* hPtMUON =
CreateHisto(
"hPtMUON",
"MUON", 100, 0, 20,
280 "p_{t} [GeV/c]",
"N");
283 TH1F* hMassK0 =
CreateHisto(
"hMassK0",
"K^{0}", 100, 0.4, 0.6,
284 "M(#pi^{+}#pi^{-}) [GeV/c^{2}]",
"N");
285 TH1F* hMassLambda =
CreateHisto(
"hMassLambda",
"#Lambda", 100, 1.0, 1.2,
286 "M(p#pi^{-}) [GeV/c^{2}]",
"N");
287 TH1F* hMassLambdaBar =
CreateHisto(
"hMassLambdaBar",
"#bar{#Lambda}",
289 "M(#bar{p}#pi^{+}) [GeV/c^{2}]",
"N");
292 TH1F* hMassXi =
CreateHisto(
"hMassXi",
"#Xi", 100, 1.2, 1.5,
293 "M(#Lambda#pi) [GeV/c^{2}]",
"N");
294 TH1F* hMassOmega =
CreateHisto(
"hMassOmega",
"#Omega", 100, 1.5, 1.8,
295 "M(#LambdaK) [GeV/c^{2}]",
"N");
296 Int_t nGenCascades = 0;
297 Int_t nRecCascades = 0;
300 for (
Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
301 runLoader->GetEvent(iEvent);
304 AliStack*
stack = runLoader->Stack();
305 Int_t nParticles = stack->GetNtrack();
307 runLoader->GetHeader()->GenEventHeader()->PrimaryVertex(vertex);
311 for (
Int_t iParticle = 0; iParticle < nParticles; iParticle++) {
312 TParticle* particle = stack->Particle(iParticle);
313 if (!particle)
continue;
314 if (particle->Pt() < 0.001)
continue;
315 if (TMath::Abs(particle->Eta()) > 0.9)
continue;
316 TVector3 dVertex(particle->Vx() - vertex[0],
317 particle->Vy() - vertex[1],
318 particle->Vz() - vertex[2]);
319 if (dVertex.Mag() > 0.0001)
continue;
321 switch (TMath::Abs(particle->GetPdgCode())) {
327 if (particle->Pt() > minPt) {
328 selParticles.Add(particle);
330 hGen->Fill(particle->Pt());
336 if (particle->Pt() > cutPtV0) {
338 selV0s.Add(particle);
344 if (particle->Pt() > cutPtCascade) {
346 selCascades.Add(particle);
355 tree->GetEvent(iEvent);
357 Error(
"CheckESD",
"no ESD object found for event %d", iEvent);
362 for (
Int_t iTrack = 0; iTrack < esd->GetNumberOfTracks(); iTrack++) {
363 AliESDtrack* track = esd->GetTrack(iTrack);
366 Int_t label = TMath::Abs(track->GetLabel());
367 if (label > stack->GetNtrack())
continue;
368 TParticle* particle = stack->Particle(label);
369 if (!selParticles.Contains(particle))
continue;
370 if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0)
continue;
371 if (track->GetConstrainedChi2() > 1e9)
continue;
372 selParticles.Remove(particle);
375 hRec->Fill(particle->Pt());
376 if (track->GetLabel() < 0) nFake++;
379 hResPtInv->Fill(100. * (TMath::Abs(track->GetSigned1Pt()) -
382 hResPhi->Fill(1000. * (track->Phi() - particle->Phi()));
383 hResTheta->Fill(1000. * (track->Theta() - particle->Theta()));
386 if ((track->GetStatus() & AliESDtrack::kESDpid) == 0)
continue;
388 for (
Int_t i = 0; i < AliPID::kSPECIES; i++) {
389 if (TMath::Abs(particle->GetPdgCode()) == partCode[i]) iGen = i;
391 Double_t probability[AliPID::kSPECIES];
392 track->GetESDpid(probability);
395 for (
Int_t i = 0; i < AliPID::kSPECIES; i++) {
396 probability[i] *= partFrac[i];
397 if (probability[i] > pMax) {
398 pMax = probability[i];
402 identified[iGen][iRec]++;
403 if (iGen == iRec) nIdentified++;
407 track->GetIntegratedTimes(time);
409 hDEdxRight->Fill(particle->P(), track->GetTPCsignal());
410 if ((track->GetStatus() & AliESDtrack::kTOFpid) != 0) {
411 hResTOFRight->Fill(track->GetTOFsignal() - time[iRec]);
414 hDEdxWrong->Fill(particle->P(), track->GetTPCsignal());
415 if ((track->GetStatus() & AliESDtrack::kTOFpid) != 0) {
416 hResTOFWrong->Fill(track->GetTOFsignal() - time[iRec]);
423 for (
Int_t iTrack = 0; iTrack < esd->GetNumberOfMuonTracks(); iTrack++) {
424 AliESDMuonTrack* muonTrack = esd->GetMuonTrack(iTrack);
425 Double_t ptInv = TMath::Abs(muonTrack->GetInverseBendingMomentum());
427 hPtMUON->Fill(1./ptInv);
433 for (
Int_t iV0 = 0; iV0 < esd->GetNumberOfV0s(); iV0++) {
434 AliESDv0* v0 = esd->GetV0(iV0);
435 if (v0->GetOnFlyStatus())
continue;
436 v0->ChangeMassHypothesis(kK0Short);
437 hMassK0->Fill(v0->GetEffMass());
438 v0->ChangeMassHypothesis(kLambda0);
439 hMassLambda->Fill(v0->GetEffMass());
440 v0->ChangeMassHypothesis(kLambda0Bar);
441 hMassLambdaBar->Fill(v0->GetEffMass());
443 Int_t negLabel = TMath::Abs(esd->GetTrack(v0->GetNindex())->GetLabel());
444 if (negLabel > stack->GetNtrack())
continue;
445 Int_t negMother = stack->Particle(negLabel)->GetMother(0);
446 if (negMother < 0)
continue;
447 Int_t posLabel = TMath::Abs(esd->GetTrack(v0->GetPindex())->GetLabel());
448 if (posLabel > stack->GetNtrack())
continue;
449 Int_t posMother = stack->Particle(posLabel)->GetMother(0);
450 if (negMother != posMother)
continue;
451 TParticle* particle = stack->Particle(negMother);
452 if (!selV0s.Contains(particle))
continue;
453 selV0s.Remove(particle);
458 for (
Int_t iCascade = 0; iCascade < esd->GetNumberOfCascades();
460 AliESDcascade* cascade = esd->GetCascade(iCascade);
462 cascade->ChangeMassHypothesis(v0q,kXiMinus);
463 hMassXi->Fill(cascade->GetEffMassXi());
464 cascade->ChangeMassHypothesis(v0q,kOmegaMinus);
465 hMassOmega->Fill(cascade->GetEffMassXi());
467 Int_t negLabel = TMath::Abs(esd->GetTrack(cascade->GetNindex())
469 if (negLabel > stack->GetNtrack())
continue;
470 Int_t negMother = stack->Particle(negLabel)->GetMother(0);
471 if (negMother < 0)
continue;
472 Int_t posLabel = TMath::Abs(esd->GetTrack(cascade->GetPindex())
474 if (posLabel > stack->GetNtrack())
continue;
475 Int_t posMother = stack->Particle(posLabel)->GetMother(0);
476 if (negMother != posMother)
continue;
477 Int_t v0Mother = stack->Particle(negMother)->GetMother(0);
478 if (v0Mother < 0)
continue;
479 Int_t bacLabel = TMath::Abs(esd->GetTrack(cascade->GetBindex())
481 if (bacLabel > stack->GetNtrack())
continue;
482 Int_t bacMother = stack->Particle(bacLabel)->GetMother(0);
483 if (v0Mother != bacMother)
continue;
484 TParticle* particle = stack->Particle(v0Mother);
485 if (!selCascades.Contains(particle))
continue;
486 selCascades.Remove(particle);
492 for (
Int_t iCluster=0;iCluster<esd->GetNumberOfCaloClusters();iCluster++){
493 AliESDCaloCluster * clust = esd->GetCaloCluster(iCluster);
494 if (clust->IsPHOS()) hEPHOS->Fill(clust->E());
495 if (clust->IsEMCAL()) hEEMCAL->Fill(clust->E());
502 if (nGen < checkNGenLow) {
503 Warning(
"CheckESD",
"low number of generated particles: %d",
Int_t(nGen));
508 Info(
"CheckESD",
"%d out of %d tracks reconstructed including %d " 509 "fake tracks", nRec, nGen, nFake);
513 Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGen);
515 Double_t fakeError = TMath::Sqrt(fake*(1.-fake) / nGen);
516 Info(
"CheckESD",
"eff = (%.1f +- %.1f) %% fake = (%.1f +- %.1f) %%",
517 100.*eff, 100.*effError, 100.*fake, 100.*fakeError);
519 if (eff < checkEffLow - checkEffSigma*effError) {
520 Warning(
"CheckESD",
"low efficiency: (%.1f +- %.1f) %%",
521 100.*eff, 100.*effError);
523 if (fake > checkFakeHigh + checkFakeSigma*fakeError) {
524 Warning(
"CheckESD",
"high fake: (%.1f +- %.1f) %%",
525 100.*fake, 100.*fakeError);
530 if (
FitHisto(hResPtInv, res, resError)) {
531 Info(
"CheckESD",
"relative inverse pt resolution = (%.1f +- %.1f) %%",
533 if (res > checkResPtInvHigh + checkResPtInvSigma*resError) {
534 Warning(
"CheckESD",
"bad pt resolution: (%.1f +- %.1f) %%",
539 if (
FitHisto(hResPhi, res, resError)) {
540 Info(
"CheckESD",
"phi resolution = (%.1f +- %.1f) mrad", res, resError);
541 if (res > checkResPhiHigh + checkResPhiSigma*resError) {
542 Warning(
"CheckESD",
"bad phi resolution: (%.1f +- %.1f) mrad",
547 if (
FitHisto(hResTheta, res, resError)) {
548 Info(
"CheckESD",
"theta resolution = (%.1f +- %.1f) mrad",
550 if (res > checkResThetaHigh + checkResThetaSigma*resError) {
551 Warning(
"CheckESD",
"bad theta resolution: (%.1f +- %.1f) mrad",
559 Double_t effError = TMath::Sqrt(eff*(1.-eff) / nRec);
560 Info(
"CheckESD",
"PID eff = (%.1f +- %.1f) %%",
561 100.*eff, 100.*effError);
562 if (eff < checkPIDEffLow - checkPIDEffSigma*effError) {
563 Warning(
"CheckESD",
"low PID efficiency: (%.1f +- %.1f) %%",
564 100.*eff, 100.*effError);
568 printf(
"%9s:",
"gen\\rec");
569 for (
Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
570 printf(
"%9s", partName[iRec]);
573 for (
Int_t iGen = 0; iGen < AliPID::kSPECIES+1; iGen++) {
574 printf(
"%9s:", partName[iGen]);
575 for (
Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
576 printf(
"%9d", identified[iGen][iRec]);
581 if (
FitHisto(hResTOFRight, res, resError)) {
582 Info(
"CheckESD",
"TOF resolution = (%.1f +- %.1f) ps", res, resError);
583 if (res > checkResTOFHigh + checkResTOFSigma*resError) {
584 Warning(
"CheckESD",
"bad TOF resolution: (%.1f +- %.1f) ps",
590 if (hEPHOS->Integral() < checkPHOSNLow) {
591 Warning(
"CheckESD",
"low number of PHOS particles: %d",
592 Int_t(hEPHOS->Integral()));
595 if (mean < checkPHOSEnergyLow) {
596 Warning(
"CheckESD",
"low mean PHOS energy: %.1f GeV", mean);
597 }
else if (mean > checkPHOSEnergyHigh) {
598 Warning(
"CheckESD",
"high mean PHOS energy: %.1f GeV", mean);
602 if (hEEMCAL->Integral() < checkEMCALNLow) {
603 Warning(
"CheckESD",
"low number of EMCAL particles: %d",
604 Int_t(hEEMCAL->Integral()));
607 if (mean < checkEMCALEnergyLow) {
608 Warning(
"CheckESD",
"low mean EMCAL energy: %.1f GeV", mean);
609 }
else if (mean > checkEMCALEnergyHigh) {
610 Warning(
"CheckESD",
"high mean EMCAL energy: %.1f GeV", mean);
615 if (hPtMUON->Integral() < checkMUONNLow) {
616 Warning(
"CheckESD",
"low number of MUON particles: %d",
617 Int_t(hPtMUON->Integral()));
620 if (mean < checkMUONPtLow) {
621 Warning(
"CheckESD",
"low mean MUON pt: %.1f GeV/c", mean);
622 }
else if (mean > checkMUONPtHigh) {
623 Warning(
"CheckESD",
"high mean MUON pt: %.1f GeV/c", mean);
630 Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGenV0s);
631 if (effError == 0) effError = checkV0EffLow / TMath::Sqrt(1.*nGenV0s);
632 Info(
"CheckESD",
"V0 eff = (%.1f +- %.1f) %%",
633 100.*eff, 100.*effError);
634 if (eff < checkV0EffLow - checkV0EffSigma*effError) {
635 Warning(
"CheckESD",
"low V0 efficiency: (%.1f +- %.1f) %%",
636 100.*eff, 100.*effError);
641 if (nGenCascades > 0) {
642 Double_t eff = nRecCascades*1./nGenCascades;
643 Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGenCascades);
644 if (effError == 0) effError = checkV0EffLow /
645 TMath::Sqrt(1.*nGenCascades);
646 Info(
"CheckESD",
"Cascade eff = (%.1f +- %.1f) %%",
647 100.*eff, 100.*effError);
648 if (eff < checkCascadeEffLow - checkCascadeEffSigma*effError) {
649 Warning(
"CheckESD",
"low Cascade efficiency: (%.1f +- %.1f) %%",
650 100.*eff, 100.*effError);
656 if (!gROOT->IsBatch()) {
660 hResPtInv->DrawCopy(
"E");
662 hResPhi->DrawCopy(
"E");
664 hResTheta->DrawCopy(
"E");
666 hDEdxRight->DrawCopy();
667 hDEdxWrong->DrawCopy(
"SAME");
669 hResTOFRight->DrawCopy(
"E");
670 hResTOFWrong->DrawCopy(
"SAME");
672 hEPHOS->DrawCopy(
"E");
674 hEEMCAL->DrawCopy(
"E");
676 hPtMUON->DrawCopy(
"E");
678 hMassK0->DrawCopy(
"E");
680 hMassLambda->DrawCopy(
"E");
682 hMassLambdaBar->DrawCopy(
"E");
684 hMassXi->DrawCopy(
"E");
686 hMassOmega->DrawCopy(
"E");
690 TFile* outputFile = TFile::Open(
"check.root",
"recreate");
691 if (!outputFile || !outputFile->IsOpen()) {
692 Error(
"CheckESD",
"opening output file check.root failed");
701 hResTOFRight->Write();
702 hResTOFWrong->Write();
707 hMassLambda->Write();
708 hMassLambdaBar->Write();
730 delete hMassLambdaBar;
738 runLoader->UnloadHeader();
739 runLoader->UnloadKinematics();
743 Info(
"CheckESD",
"check of ESD was successfull");
Bool_t Check(const char *gAliceFileName="galice.root", const char *esdFileName="AliESDs.root")
TH1 * CreateEffHisto(TH1 *hGen, TH1 *hRec)
TH1 * CreateHisto(const char *name, const char *title, Int_t nBins, Double_t xMin, Double_t xMax, const char *xLabel=NULL, const char *yLabel=NULL)
Bool_t FitHisto(TH1 *histo, Double_t &res, Double_t &resError)