1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Drawing nice pictures containing
19 // - Signal/Background
21 // More Post Analysis code will be added in time
23 // Autor: Markus Fasel
32 #include "AliCFContainer.h"
33 #include "AliCFEffGrid.h"
35 #include "AliHFEcontainer.h"
36 #include "AliHFEcuts.h"
37 #include "AliHFEpostAnalysis.h"
39 ClassImp(AliHFEpostAnalysis)
41 //____________________________________________________________
42 AliHFEpostAnalysis::AliHFEpostAnalysis():
46 fEfficiencyContainer(NULL),
47 fPIDperformance(NULL),
48 fSignalToBackgroundMC(NULL)
51 // Default Constructor
55 //____________________________________________________________
56 AliHFEpostAnalysis::AliHFEpostAnalysis(const AliHFEpostAnalysis &ref):
58 fResults(ref.fResults),
59 fAnalysisObjects(ref.fAnalysisObjects),
60 fEfficiencyContainer(ref.fEfficiencyContainer),
61 fPIDperformance(ref.fPIDperformance),
62 fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
69 //____________________________________________________________
70 AliHFEpostAnalysis& AliHFEpostAnalysis::operator=(const AliHFEpostAnalysis &ref){
72 // Assignment Operator
74 TObject::operator=(ref);
75 fResults = ref.fResults;
76 fAnalysisObjects = ref.fAnalysisObjects;
77 fPIDperformance = ref.fPIDperformance;
78 fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
83 //____________________________________________________________
84 AliHFEpostAnalysis::~AliHFEpostAnalysis(){
86 // Do not delete objects where we are not owner
88 if(fResults) delete fResults;
91 //____________________________________________________________
92 Int_t AliHFEpostAnalysis::SetTaskQA(const TList *input){
94 // Publish the results to the post analysis
97 fPIDperformance = dynamic_cast<THnSparseF *>(input->FindObject("PIDperformance"));
99 AliError("Histogram fPIDperformance not found in the List of Outputs");
101 SETBIT(fAnalysisObjects, kPIDperf);
104 fSignalToBackgroundMC = dynamic_cast<THnSparseF *>(input->FindObject("SignalToBackgroundMC"));
105 if(!fSignalToBackgroundMC){
106 AliError("Histogram fSignalToBackgroundMC not found in the list of outputs");
108 SETBIT(fAnalysisObjects, kSigBackg);
111 AliInfo(Form("Found %d analysis objects", nFound));
115 //____________________________________________________________
116 void AliHFEpostAnalysis::StoreOutput(const char *filename){
118 // Save the results produced in a rootfile
121 TFile *outfile = new TFile(filename, "RECREATE");
123 fResults->Write("HFEresults", TObject::kSingleKey);
129 //____________________________________________________________
130 void AliHFEpostAnalysis::DrawMCSignal2Background(){
132 // Draw the MC signal/background plots
134 if(!fSignalToBackgroundMC) return;
136 // First Select everything within the first ITS Layer
137 fSignalToBackgroundMC->GetAxis(5)->SetRange(2,2);
138 TH1 *hEff[3], *hSB[3];
139 // Select for different charge
140 hEff[0] = CreateHistoSignalToBackgroundMC(0, 0);
141 hEff[1] = CreateHistoSignalToBackgroundMC(0, 1);
142 hEff[2] = CreateHistoSignalToBackgroundMC(0, 2);
144 hSB[0] = CreateHistoSignalToBackgroundMC(1, 0);
145 hSB[1] = CreateHistoSignalToBackgroundMC(1, 1);
146 hSB[2] = CreateHistoSignalToBackgroundMC(1, 2);
149 fSignalToBackgroundMC->GetAxis(5)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetNbins());
152 TCanvas *cMCSB = new TCanvas("cMCSB", "MC Sig/Backg studies", 800, 400);
155 TH1 **sample[2] = {&hEff[0], &hSB[0]};
156 const char *chargename[3] = {"All Charges", "Negative Charge", "Positive Charge"};
157 for(Int_t isample = 0; isample < 2; isample++){
158 leg = new TLegend(0.7, 0.1, 0.89, 0.3);
159 leg->SetBorderSize(1);
160 leg->SetFillColor(kWhite);
161 cMCSB->cd(isample + 1);
162 for(Int_t icharge = 0; icharge < 3; icharge++){
163 sample[isample][icharge]->Draw(icharge > 0? "psame" : "p");
164 leg->AddEntry(sample[isample][icharge], chargename[icharge], "p");
171 //____________________________________________________________
172 TH1 *AliHFEpostAnalysis::CreateHistoSignalToBackgroundMC(Int_t mode, Int_t charge){
174 // Make Efficiency / SB histograms for different charges
176 TH1 *hNom = NULL, *hDenom = NULL;
177 if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(charge, charge);
178 // For Signal electrons we project axis 4 to everything > 0
179 fSignalToBackgroundMC->GetAxis(4)->SetRange(2,3);
180 hNom = fSignalToBackgroundMC->Projection(0);
181 hNom->SetName("nom");
182 fSignalToBackgroundMC->GetAxis(4)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetLast() + 1);
183 if(mode == 1) fSignalToBackgroundMC->GetAxis(4)->SetRange(1,1);
184 hDenom = fSignalToBackgroundMC->Projection(0);
185 hDenom->SetName("denom");
186 if(mode == 1) fSignalToBackgroundMC->GetAxis(4)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetLast() + 1);
187 if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(0, fSignalToBackgroundMC->GetAxis(3)->GetLast() + 1);
189 TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
191 TString hname, cname;
192 hname = mode ? "sigToBack" : "sigEff";
193 Color_t mycolor = kBlack;
195 case 0: mycolor = kBlue; cname = "All"; break;
196 case 1: mycolor = kBlack; cname = "Neg"; break;
197 case 2: mycolor = kRed; cname ="Pos"; break;
201 hEff->SetName(hname);
202 hEff->SetTitle(mode ? "Signal/Background" : "Signal/(Signal+Background)");
203 hEff->Divide(hDenom);
206 hEff->GetXaxis()->SetTitle("p_{T} / GeV/c");
207 hEff->GetYaxis()->SetTitle("Efficiency");
208 hEff->SetStats(kFALSE);
209 hEff->SetLineColor(kBlack);
210 hEff->SetLineWidth(1);
211 hEff->SetMarkerStyle(22);
212 hEff->SetMarkerColor(mycolor);
215 delete hNom; delete hDenom;
219 //____________________________________________________________
220 void AliHFEpostAnalysis::DrawEfficiency(){
222 // Draw the Efficiency
224 // + InAcceptance / Generated
225 // + Signal / Generated
226 // + Selected / Generated
227 // + Selected / InAcceptance (Reconstructible)
229 TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600);
231 if(!fEfficiencyContainer) return;
232 AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("trackContCombined", "MC + Rec(reco) Track Information", "MCTrackCont:recTrackContReco");
233 AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *tracks);
234 effCalc->CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
235 TH1 *effReconstructibleP = effCalc->Project(0);
236 effReconstructibleP->SetName("effReconstructibleP");
237 effReconstructibleP->SetTitle("Efficiency of reconstructible tracks");
238 effReconstructibleP->GetXaxis()->SetTitle("p_{T} / GeV/c");
239 effReconstructibleP->GetYaxis()->SetTitle("Efficiency");
240 effReconstructibleP->GetYaxis()->SetRangeUser(0.,1.);
241 effReconstructibleP->SetMarkerStyle(22);
242 effReconstructibleP->SetMarkerColor(kBlue);
243 effReconstructibleP->SetLineColor(kBlack);
244 effReconstructibleP->SetStats(kFALSE);
246 effReconstructibleP->Draw("e");
247 effCalc->CalculateEfficiency(AliHFEcuts::kStepMCGeneratedZOutNoPileUpCentralityFine, AliHFEcuts::kStepMCGenerated);
248 TH1 *effSignal = effCalc->Project(0);
249 effSignal->SetName("effSignal");
250 effSignal->SetTitle("Efficiency of Signal Electrons");
251 effSignal->GetXaxis()->SetTitle("p_{T} / GeV/c");
252 effSignal->GetYaxis()->SetTitle("Efficiency");
253 effSignal->GetYaxis()->SetRangeUser(0., 1.);
254 effSignal->SetMarkerStyle(22);
255 effSignal->SetMarkerColor(kBlue);
256 effSignal->SetLineColor(kBlack);
257 effSignal->SetStats(kFALSE);
259 effSignal->Draw("e");
260 effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCGenerated);
261 TH1 *effPIDP = effCalc->Project(0);
262 effPIDP->SetName("effPIDP");
263 effPIDP->SetTitle("Efficiency of selected tracks");
264 effPIDP->GetXaxis()->SetTitle("p_{T} / GeV/c");
265 effPIDP->GetYaxis()->SetTitle("Efficiency");
266 effPIDP->GetYaxis()->SetRangeUser(0.,1.);
267 effPIDP->SetMarkerStyle(22);
268 effPIDP->SetMarkerColor(kBlue);
269 effPIDP->SetLineColor(kBlack);
270 effPIDP->SetStats(kFALSE);
273 effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCInAcceptance);
274 TH1 *effPIDAcc = effCalc->Project(0);
275 effPIDAcc->SetName("effPIDAcc");
276 effPIDAcc->SetTitle("Efficiency of selected tracks in acceptance");
277 effPIDAcc->GetXaxis()->SetTitle("p_{T} / GeV/c");
278 effPIDAcc->GetYaxis()->SetTitle("Efficiency");
279 effPIDAcc->GetYaxis()->SetRangeUser(0.,1.);
280 effPIDAcc->SetMarkerStyle(22);
281 effPIDAcc->SetMarkerColor(kBlue);
282 effPIDAcc->SetLineColor(kBlack);
283 effPIDAcc->SetStats(kFALSE);
285 effPIDAcc->Draw("e");
289 //____________________________________________________________
290 void AliHFEpostAnalysis::DrawPIDperformance(){
292 // Plotting Ratio histograms
293 // + All electrons / all candidates (Purity for Electrons)
294 // + All signal electrons / all electrons (Purity for signals)
297 if(!fPIDperformance) return;
299 TH1 *electronPurity[3], *signalPurity[3], *fakeContamination[3];
300 electronPurity[0] = CreateHistoPIDperformance(0, 0);
301 electronPurity[1] = CreateHistoPIDperformance(0, 1);
302 electronPurity[2] = CreateHistoPIDperformance(0, 2);
304 signalPurity[0] = CreateHistoPIDperformance(1, 0);
305 signalPurity[1] = CreateHistoPIDperformance(1, 1);
306 signalPurity[2] = CreateHistoPIDperformance(1, 2);
308 fakeContamination[0] = CreateHistoPIDperformance(2, 0);
309 fakeContamination[1] = CreateHistoPIDperformance(2, 1);
310 fakeContamination[2] = CreateHistoPIDperformance(2, 2);
313 TCanvas *cRatios = new TCanvas("cRatios", "Ratio Plots", 800, 600);
314 const char *chargename[3] = {"All Charges", "Negative Charge", "Positive Charge"};
315 cRatios->Divide(2,2);
316 TH1 **sample[3] = {&electronPurity[0], &signalPurity[0], &fakeContamination[0]};
318 for(Int_t isample = 0; isample < 3; isample++){
319 cRatios->cd(isample + 1);
320 leg = new TLegend(0.7, 0.1, 0.89, 0.3);
321 leg->SetBorderSize(1);
322 leg->SetFillColor(kWhite);
323 for(Int_t icharge = 0; icharge < 3; icharge++){
324 leg->AddEntry(sample[isample][icharge], chargename[icharge], "p");
325 sample[isample][icharge]->Draw(icharge > 0 ? "esame" : "e");
332 //____________________________________________________________
333 TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){
335 // Make Histograms for PID performance plots
337 fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
338 fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
340 TH1 *hNom = NULL, *hDenom = NULL;
341 TString hname, htitle, cname;
342 Color_t mycolor = kBlack;
343 if(charge) fPIDperformance->GetAxis(3)->SetRange(charge, charge);
344 // Normalisation by all candidates - no restriction in axis 4 - only for mode == 1
345 if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,3);
346 hDenom = fPIDperformance->Projection(0);
348 hDenom->SetName("hDenom");
349 if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins() + 1);
350 // Nominator need a restriction in the 4th axis
352 case 0: // Electron purity
353 fPIDperformance->GetAxis(4)->SetRange(2,3);
354 hname = "electronPurity";
355 htitle = "Electron Purity";
357 case 1: // Signal purity
358 fPIDperformance->GetAxis(4)->SetRange(3,3); // here signal not divided into charm and beauty
359 hname = "signalPurity";
360 htitle = "Signal Purity";
362 case 2: // Fake contamination
363 fPIDperformance->GetAxis(4)->SetRange(1,1);
364 hname = "fakeContamination";
365 htitle = "Contamination of misidentified hadrons";
384 hNom = fPIDperformance->Projection(0);
386 hNom->SetName("hNom");
388 fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
389 if(charge) fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
391 // Create Efficiency histogram
392 TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
394 hEff->SetName(hname.Data());
395 hEff->SetTitle(htitle.Data());
396 hEff->Divide(hDenom);
398 hEff->GetXaxis()->SetTitle("p_{T} / GeV/c");
399 hEff->GetYaxis()->SetTitle(mode < 2 ? "Purity / %" : "Contamination / %");
400 hEff->GetYaxis()->SetRangeUser(0., 100.);
401 hEff->SetStats(kFALSE);
402 hEff->SetLineColor(kBlack);
403 hEff->SetLineWidth(1);
404 hEff->SetMarkerColor(mycolor);
405 hEff->SetMarkerStyle(22);
406 delete hNom; delete hDenom;
411 //____________________________________________________________
412 void AliHFEpostAnalysis::DrawCutEfficiency(Bool_t MC, Int_t source){
414 // Calculate efficiency for each cut step
415 // Starting from MC steps
417 TCanvas *output = new TCanvas("effCut", "Cut Step efficiency", 800, 600);
419 TLegend *leg = new TLegend(0.6, 0.7, 0.89, 0.89);
420 leg->SetHeader("Cut Step:");
421 leg->SetBorderSize(0);
422 leg->SetFillColor(kWhite);
423 leg->SetFillStyle(0);
425 AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("mergedTracks", "Container for MC and reconstructed Track information", "MCTrackCont:recTrackContReco");
426 Int_t nStepMC = fEfficiencyContainer->GetCFContainer("MCTrackCont")->GetNStep();
427 AliDebug(1, Form("Number of MC Cut Steps: %d", nStepMC));
428 const Int_t markerStart = 24;
429 const Int_t colorStart = 1;
433 if(source > -1 && source < 4){
434 AliInfo(Form("Setting source to %d", source));
435 for(Int_t istep = 0; istep < tracks->GetNStep(); istep++) tracks->GetAxis(4, istep)->SetRange(source + 1, source + 1);
438 AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *tracks);
439 Bool_t first = kTRUE;
440 // Calculate efficiency for MC Steps
441 Int_t histcounter = 0;
444 // Draw plots related to MC values
446 effcalc.CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
447 hTemp = effcalc.Project(0);
448 hTemp->SetName(Form("hEff%d", histcounter));
449 hTemp->SetTitle("Cut Step Efficiency");
450 hTemp->SetMarkerColor(colorStart + histcounter);
451 hTemp->SetMarkerStyle(markerStart + histcounter);
452 hTemp->GetXaxis()->SetTitle("p / GeV/c");
453 hTemp->GetYaxis()->SetTitle("Efficiency");
454 hTemp->GetYaxis()->SetRangeUser(0., 2.);
455 hTemp->SetStats(kFALSE);
457 leg->AddEntry(hTemp, tracks->GetStepTitle(AliHFEcuts::kStepMCInAcceptance), "p");
459 effcalc.CalculateEfficiency(nStepMC, AliHFEcuts::kStepMCGenerated);
460 hTemp = effcalc.Project(0);
461 hTemp->SetName("hEff2");
462 hTemp->SetTitle("Cut Step Efficiency");
463 hTemp->SetMarkerColor(colorStart + histcounter);
464 hTemp->SetMarkerStyle(markerStart + histcounter);
465 hTemp->GetXaxis()->SetTitle("p / GeV/c");
466 hTemp->GetYaxis()->SetTitle("Efficiency");
467 hTemp->GetYaxis()->SetRangeUser(0., 2.);
468 hTemp->SetStats(kFALSE);
469 hTemp->Draw("epsame");
470 leg->AddEntry(hTemp, tracks->GetStepTitle(nStepMC), "p");
474 for(Int_t istep = nStepMC+1; istep < tracks->GetNStep(); istep++){
475 effcalc.CalculateEfficiency(istep, istep - 1);
476 hTemp = effcalc.Project(0);
477 hTemp->SetName(Form("hEff%d", istep));
478 hTemp->SetTitle("Cut Step Efficiency");
479 hTemp->SetMarkerColor(colorStart + histcounter);
480 hTemp->SetMarkerStyle(markerStart + histcounter);
481 hTemp->SetStats(kFALSE);
482 hTemp->Draw(first ? "ep" : "epsame");
483 hTemp->GetXaxis()->SetTitle("P / GeV/c");
484 hTemp->GetYaxis()->SetTitle("Efficiency");
485 hTemp->GetYaxis()->SetRangeUser(0., 2.);
486 leg->AddEntry(hTemp, tracks->GetStepTitle(istep), "p");