2806b365636a66d0f2dd241ec446d818522334d8
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliHFEpostAnalysis.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15 //
16 // Post analysis code
17 // Drawing nice pictures containing
18 //  - Efficiency
19 //  - Signal/Background
20 //  - PID Performance
21 //  More Post Analysis code will be added in time
22 //
23 //  Autor: Markus Fasel
24 //
25
26 #include <TAxis.h>
27 #include <TCanvas.h>
28 #include <TFile.h>
29 #include <TH1D.h>
30 #include <TLegend.h>
31 #include <TList.h>
32 #include "AliCFContainer.h"
33 #include "AliCFEffGrid.h"
34
35 #include "AliHFEcontainer.h"
36 #include "AliHFEcuts.h"
37 #include "AliHFEpostAnalysis.h"
38
39 ClassImp(AliHFEpostAnalysis)
40
41 //____________________________________________________________
42 AliHFEpostAnalysis::AliHFEpostAnalysis():
43   TObject(),
44   fResults(NULL),
45   fAnalysisObjects(0),
46   fEfficiencyContainer(NULL),
47   fPIDperformance(NULL),
48   fSignalToBackgroundMC(NULL)
49 {
50   //
51   // Default Constructor
52   //
53 }
54
55 //____________________________________________________________
56 AliHFEpostAnalysis::AliHFEpostAnalysis(const AliHFEpostAnalysis &ref):
57   TObject(ref),
58   fResults(ref.fResults),
59   fAnalysisObjects(ref.fAnalysisObjects),
60   fEfficiencyContainer(ref.fEfficiencyContainer),
61   fPIDperformance(ref.fPIDperformance),
62   fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
63 {
64   //
65   // Copy Constructor
66   //
67 }
68
69 //____________________________________________________________
70 AliHFEpostAnalysis& AliHFEpostAnalysis::operator=(const AliHFEpostAnalysis &ref){
71   //
72   // Assignment Operator
73   //
74   TObject::operator=(ref);
75   fResults = ref.fResults;
76   fAnalysisObjects = ref.fAnalysisObjects;
77   fPIDperformance = ref.fPIDperformance;
78   fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
79
80   return *this;
81 }
82
83 //____________________________________________________________
84 AliHFEpostAnalysis::~AliHFEpostAnalysis(){
85   //
86   // Do not delete objects where we are not owner
87   //
88   if(fResults) delete fResults;
89 }
90
91 //____________________________________________________________
92 Int_t AliHFEpostAnalysis::SetTaskQA(const TList *input){
93   //
94   // Publish the results to the post analysis
95   //
96   Int_t nFound = 0;
97   fPIDperformance = dynamic_cast<THnSparseF *>(input->FindObject("PIDperformance"));
98   if(!fPIDperformance){
99     AliError("Histogram fPIDperformance not found in the List of Outputs");
100   } else {
101     SETBIT(fAnalysisObjects, kPIDperf);
102     nFound++;
103   }
104   fSignalToBackgroundMC = dynamic_cast<THnSparseF *>(input->FindObject("SignalToBackgroundMC"));
105   if(!fSignalToBackgroundMC){
106     AliError("Histogram fSignalToBackgroundMC not found in the list of outputs");
107   } else {
108     SETBIT(fAnalysisObjects, kSigBackg);
109     nFound++;
110   }
111   AliInfo(Form("Found %d analysis objects", nFound));
112   return nFound;
113 }
114
115 //____________________________________________________________
116 void AliHFEpostAnalysis::StoreOutput(const char *filename){
117   //
118   // Save the results produced in a rootfile
119   //
120   if(fResults){
121     TFile *outfile = new TFile(filename, "RECREATE");
122     outfile->cd();
123     fResults->Write("HFEresults", TObject::kSingleKey);
124     outfile->Close();
125     delete outfile;
126   }
127 }
128
129 //____________________________________________________________
130 void AliHFEpostAnalysis::DrawMCSignal2Background(){
131   //
132   // Draw the MC signal/background plots
133   //
134   if(!fSignalToBackgroundMC) return;
135
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);
143
144   hSB[0] = CreateHistoSignalToBackgroundMC(1, 0);
145   hSB[1] = CreateHistoSignalToBackgroundMC(1, 1);
146   hSB[2] = CreateHistoSignalToBackgroundMC(1, 2);
147  
148   // Undo projections
149   fSignalToBackgroundMC->GetAxis(5)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetNbins());
150
151   // Prepare Canvas
152   TCanvas *cMCSB = new TCanvas("cMCSB", "MC Sig/Backg studies", 800, 400);
153   cMCSB->Divide(2);
154   TLegend *leg;
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");
165     }
166     leg->Draw();
167     gPad->Update();
168   }
169 }
170
171 //____________________________________________________________
172 TH1 *AliHFEpostAnalysis::CreateHistoSignalToBackgroundMC(Int_t mode, Int_t charge){ 
173   //
174   // Make Efficiency / SB histograms for different charges
175   //
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);
188
189   TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
190   if(hEff){
191     TString hname, cname;
192     hname = mode ? "sigToBack" : "sigEff";
193     Color_t mycolor = kBlack;
194     switch(charge){
195       case 0: mycolor = kBlue; cname = "All"; break;
196       case 1: mycolor = kBlack; cname = "Neg"; break;
197       case 2: mycolor = kRed; cname ="Pos"; break;
198       default: break;
199     }
200     hname += cname;
201     hEff->SetName(hname);
202     hEff->SetTitle(mode ? "Signal/Background" : "Signal/(Signal+Background)");
203     hEff->Divide(hDenom);
204
205     // Make nice plots
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);
213   }
214
215   delete hNom; delete hDenom;
216   return hEff;
217 }
218
219 //____________________________________________________________
220 void AliHFEpostAnalysis::DrawEfficiency(){
221   //
222   // Draw the Efficiency
223   // We show: 
224   // + InAcceptance / Generated
225   // + Signal / Generated
226   // + Selected / Generated
227   // + Selected / InAcceptance (Reconstructible)
228   //
229   TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600);
230   cEff->Divide(2,2);
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);
245   cEff->cd(1);
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);
258   cEff->cd(2);
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);
271   cEff->cd(3);
272   effPIDP->Draw("e");
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);
284   cEff->cd(4);
285   effPIDAcc->Draw("e");
286   delete effCalc;
287 }
288
289 //____________________________________________________________
290 void AliHFEpostAnalysis::DrawPIDperformance(){
291   //
292   // Plotting Ratio histograms
293   // + All electrons / all candidates (Purity for Electrons)
294   // + All signal electrons / all electrons (Purity for signals)
295   //
296
297   if(!fPIDperformance) return;
298   // Make projection
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);
303
304   signalPurity[0] = CreateHistoPIDperformance(1, 0);
305   signalPurity[1] = CreateHistoPIDperformance(1, 1);
306   signalPurity[2] = CreateHistoPIDperformance(1, 2);
307
308   fakeContamination[0] = CreateHistoPIDperformance(2, 0);
309   fakeContamination[1] = CreateHistoPIDperformance(2, 1);
310   fakeContamination[2] = CreateHistoPIDperformance(2, 2);
311
312   // Draw output
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]};
317   TLegend *leg;
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");
326     }
327     leg->Draw();
328     gPad->Update();
329   }
330 }
331
332 //____________________________________________________________
333 TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){
334   //
335   // Make Histograms for PID performance plots
336   //
337   fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
338   fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
339
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);
347   hDenom->Sumw2();
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
351   switch(mode){
352     case 0: // Electron purity
353       fPIDperformance->GetAxis(4)->SetRange(2,3);
354       hname = "electronPurity";
355       htitle = "Electron Purity";
356       break;
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";
361       break;
362     case 2: // Fake contamination
363       fPIDperformance->GetAxis(4)->SetRange(1,1);
364       hname = "fakeContamination";
365       htitle = "Contamination of misidentified hadrons";
366       break;
367     default: break;
368   }
369   switch(charge){
370     case 0: 
371       cname = "All"; 
372       mycolor = kBlue;
373       break;
374     case 1: 
375       cname = "Neg"; 
376       mycolor = kBlack;
377       break;
378     case 2: 
379       cname = "Pos"; 
380       mycolor = kRed;
381       break;
382   }
383   hname += cname;
384   hNom = fPIDperformance->Projection(0);
385   hNom->Sumw2();
386   hNom->SetName("hNom");
387   // Reset axis
388   fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
389   if(charge) fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
390
391   // Create Efficiency histogram
392   TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
393   if(hEff){
394     hEff->SetName(hname.Data());
395     hEff->SetTitle(htitle.Data());
396     hEff->Divide(hDenom);
397     hEff->Scale(100.);
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;
407   }
408   return hEff;
409 }
410
411 //____________________________________________________________
412 void AliHFEpostAnalysis::DrawCutEfficiency(Bool_t MC, Int_t source){
413   //
414   // Calculate efficiency for each cut step
415   // Starting from MC steps 
416   //
417   TCanvas *output = new TCanvas("effCut", "Cut Step efficiency", 800, 600);
418   output->cd();
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);
424
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;
430   TH1 *hTemp = NULL;
431
432   if(MC){
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);
436     }
437   }
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;
442   if(MC){
443     //
444     // Draw plots related to MC values
445     //
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);
456     hTemp->Draw("ep");
457     leg->AddEntry(hTemp, tracks->GetStepTitle(AliHFEcuts::kStepMCInAcceptance), "p");
458     histcounter++;
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");
471     first = kFALSE;
472     histcounter++;
473   }
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");
487     first = kFALSE;
488     histcounter++;
489   }
490   leg->Draw();
491   delete tracks;
492 }