Cleanup the code. Fix memory leak. Now inherit from AliAnalysisTaskSE (Antoine, Phili...
[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 /* $Id$ */
17
18 //
19 // Post analysis code
20 // Drawing nice pictures containing
21 //  - Efficiency
22 //  - Signal/Background
23 //  - PID Performance
24 //  More Post Analysis code will be added in time
25 //
26 //  Autor: Markus Fasel
27 //
28
29 #include <TAxis.h>
30 #include <TCanvas.h>
31 #include <TFile.h>
32 #include <TH1D.h>
33 #include <TLegend.h>
34 #include <TList.h>
35 #include "AliCFContainer.h"
36 #include "AliCFEffGrid.h"
37
38 #include "AliHFEcontainer.h"
39 #include "AliHFEcuts.h"
40 #include "AliHFEpostAnalysis.h"
41
42 ClassImp(AliHFEpostAnalysis)
43
44 //____________________________________________________________
45 AliHFEpostAnalysis::AliHFEpostAnalysis():
46   TObject(),
47   fResults(NULL),
48   fAnalysisObjects(0),
49   fEfficiencyContainer(NULL),
50   fPIDperformance(NULL),
51   fSignalToBackgroundMC(NULL)
52 {
53   //
54   // Default Constructor
55   //
56 }
57
58 //____________________________________________________________
59 AliHFEpostAnalysis::AliHFEpostAnalysis(const AliHFEpostAnalysis &ref):
60   TObject(ref),
61   fResults(ref.fResults),
62   fAnalysisObjects(ref.fAnalysisObjects),
63   fEfficiencyContainer(ref.fEfficiencyContainer),
64   fPIDperformance(ref.fPIDperformance),
65   fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
66 {
67   //
68   // Copy Constructor
69   //
70 }
71
72 //____________________________________________________________
73 AliHFEpostAnalysis& AliHFEpostAnalysis::operator=(const AliHFEpostAnalysis &ref){
74   //
75   // Assignment Operator
76   //
77   TObject::operator=(ref);
78   fResults = ref.fResults;
79   fAnalysisObjects = ref.fAnalysisObjects;
80   fPIDperformance = ref.fPIDperformance;
81   fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
82
83   return *this;
84 }
85
86 //____________________________________________________________
87 AliHFEpostAnalysis::~AliHFEpostAnalysis(){
88   //
89   // Do not delete objects where we are not owner
90   //
91   if(fResults) delete fResults;
92 }
93
94 //____________________________________________________________
95 Int_t AliHFEpostAnalysis::SetTaskQA(const TList *input){
96   //
97   // Publish the results to the post analysis
98   //
99   Int_t nFound = 0;
100   fPIDperformance = dynamic_cast<THnSparseF *>(input->FindObject("PIDperformance"));
101   if(!fPIDperformance){
102     AliError("Histogram fPIDperformance not found in the List of Outputs");
103   } else {
104     SETBIT(fAnalysisObjects, kPIDperf);
105     nFound++;
106   }
107   fSignalToBackgroundMC = dynamic_cast<THnSparseF *>(input->FindObject("SignalToBackgroundMC"));
108   if(!fSignalToBackgroundMC){
109     AliError("Histogram fSignalToBackgroundMC not found in the list of outputs");
110   } else {
111     SETBIT(fAnalysisObjects, kSigBackg);
112     nFound++;
113   }
114   AliInfo(Form("Found %d analysis objects", nFound));
115   return nFound;
116 }
117
118 //____________________________________________________________
119 void AliHFEpostAnalysis::StoreOutput(const char *filename){
120   //
121   // Save the results produced in a rootfile
122   //
123   if(fResults){
124     TFile *outfile = new TFile(filename, "RECREATE");
125     outfile->cd();
126     fResults->Write("HFEresults", TObject::kSingleKey);
127     outfile->Close();
128     delete outfile;
129   }
130 }
131
132 //____________________________________________________________
133 void AliHFEpostAnalysis::DrawMCSignal2Background(){
134   //
135   // Draw the MC signal/background plots
136   //
137   if(!fSignalToBackgroundMC) return;
138
139   // First Select everything within the first ITS Layer
140   fSignalToBackgroundMC->GetAxis(5)->SetRange(2,2);
141   TH1 *hEff[3], *hSB[3];
142   // Select for different charge
143   hEff[0] = CreateHistoSignalToBackgroundMC(0, 0);
144   hEff[1] = CreateHistoSignalToBackgroundMC(0, 1);
145   hEff[2] = CreateHistoSignalToBackgroundMC(0, 2);
146
147   hSB[0] = CreateHistoSignalToBackgroundMC(1, 0);
148   hSB[1] = CreateHistoSignalToBackgroundMC(1, 1);
149   hSB[2] = CreateHistoSignalToBackgroundMC(1, 2);
150  
151   // Undo projections
152   fSignalToBackgroundMC->GetAxis(5)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetNbins());
153
154   // Prepare Canvas
155   TCanvas *cMCSB = new TCanvas("cMCSB", "MC Sig/Backg studies", 800, 400);
156   cMCSB->Divide(2);
157   TLegend *leg;
158   TH1 **sample[2] = {&hEff[0], &hSB[0]};
159   const char *chargename[3] = {"All Charges", "Negative Charge", "Positive Charge"};
160   for(Int_t isample = 0; isample < 2; isample++){
161     leg = new TLegend(0.7, 0.1, 0.89, 0.3);
162     leg->SetBorderSize(1); 
163     leg->SetFillColor(kWhite);
164     cMCSB->cd(isample + 1);
165     for(Int_t icharge = 0; icharge < 3; icharge++){
166       sample[isample][icharge]->Draw(icharge > 0?  "psame" : "p");
167       leg->AddEntry(sample[isample][icharge], chargename[icharge], "p");
168     }
169     leg->Draw();
170     gPad->Update();
171   }
172 }
173
174 //____________________________________________________________
175 TH1 *AliHFEpostAnalysis::CreateHistoSignalToBackgroundMC(Int_t mode, Int_t charge){ 
176   //
177   // Make Efficiency / SB histograms for different charges
178   //
179   TH1 *hNom = NULL, *hDenom = NULL;
180   if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(charge, charge);
181   // For Signal electrons we project axis 4 to everything > 0
182   fSignalToBackgroundMC->GetAxis(4)->SetRange(2,3);
183   hNom = fSignalToBackgroundMC->Projection(0);
184   hNom->SetName("nom");
185   fSignalToBackgroundMC->GetAxis(4)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetLast() + 1);
186   if(mode == 1) fSignalToBackgroundMC->GetAxis(4)->SetRange(1,1);
187   hDenom =  fSignalToBackgroundMC->Projection(0);
188   hDenom->SetName("denom");
189   if(mode == 1)  fSignalToBackgroundMC->GetAxis(4)->SetRange(0, fSignalToBackgroundMC->GetAxis(4)->GetLast() + 1);
190   if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(0, fSignalToBackgroundMC->GetAxis(3)->GetLast() + 1);
191
192   TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
193   if(hEff){
194     TString hname, cname;
195     hname = mode ? "sigToBack" : "sigEff";
196     Color_t mycolor = kBlack;
197     switch(charge){
198       case 0: mycolor = kBlue; cname = "All"; break;
199       case 1: mycolor = kBlack; cname = "Neg"; break;
200       case 2: mycolor = kRed; cname ="Pos"; break;
201       default: break;
202     }
203     hname += cname;
204     hEff->SetName(hname);
205     hEff->SetTitle(mode ? "Signal/Background" : "Signal/(Signal+Background)");
206     hEff->Divide(hDenom);
207
208     // Make nice plots
209     hEff->GetXaxis()->SetTitle("p_{T} / GeV/c");
210     hEff->GetYaxis()->SetTitle("Efficiency");
211     hEff->SetStats(kFALSE);
212     hEff->SetLineColor(kBlack);
213     hEff->SetLineWidth(1);
214     hEff->SetMarkerStyle(22);
215     hEff->SetMarkerColor(mycolor);
216   }
217
218   delete hNom; delete hDenom;
219   return hEff;
220 }
221
222 //____________________________________________________________
223 void AliHFEpostAnalysis::DrawEfficiency(){
224   //
225   // Draw the Efficiency
226   // We show: 
227   // + InAcceptance / Generated
228   // + Signal / Generated
229   // + Selected / Generated
230   // + Selected / InAcceptance (Reconstructible)
231   //
232   TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600);
233   cEff->Divide(2,2);
234   if(!fEfficiencyContainer) return;
235   AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("trackContCombined", "MC + Rec(reco) Track Information", "MCTrackCont:recTrackContReco");
236   AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *tracks);
237   effCalc->CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
238   TH1 *effReconstructibleP = effCalc->Project(0);
239   effReconstructibleP->SetName("effReconstructibleP");
240   effReconstructibleP->SetTitle("Efficiency of reconstructible tracks");
241   effReconstructibleP->GetXaxis()->SetTitle("p_{T} / GeV/c");
242   effReconstructibleP->GetYaxis()->SetTitle("Efficiency");
243   effReconstructibleP->GetYaxis()->SetRangeUser(0.,1.);
244   effReconstructibleP->SetMarkerStyle(22);
245   effReconstructibleP->SetMarkerColor(kBlue);
246   effReconstructibleP->SetLineColor(kBlack);
247   effReconstructibleP->SetStats(kFALSE);
248   cEff->cd(1);
249   effReconstructibleP->Draw("e");
250   effCalc->CalculateEfficiency(AliHFEcuts::kStepMCGeneratedZOutNoPileUp, AliHFEcuts::kStepMCGenerated);
251   TH1 *effSignal = effCalc->Project(0);
252   effSignal->SetName("effSignal");
253   effSignal->SetTitle("Efficiency of Signal Electrons");
254   effSignal->GetXaxis()->SetTitle("p_{T} / GeV/c");
255   effSignal->GetYaxis()->SetTitle("Efficiency");
256   effSignal->GetYaxis()->SetRangeUser(0., 1.);
257   effSignal->SetMarkerStyle(22);
258   effSignal->SetMarkerColor(kBlue);
259   effSignal->SetLineColor(kBlack);
260   effSignal->SetStats(kFALSE);
261   cEff->cd(2);
262   effSignal->Draw("e");
263   effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCGenerated);
264   TH1 *effPIDP = effCalc->Project(0);
265   effPIDP->SetName("effPIDP");
266   effPIDP->SetTitle("Efficiency of selected tracks");
267   effPIDP->GetXaxis()->SetTitle("p_{T} / GeV/c");
268   effPIDP->GetYaxis()->SetTitle("Efficiency");
269   effPIDP->GetYaxis()->SetRangeUser(0.,1.);
270   effPIDP->SetMarkerStyle(22);
271   effPIDP->SetMarkerColor(kBlue);
272   effPIDP->SetLineColor(kBlack);
273   effPIDP->SetStats(kFALSE);
274   cEff->cd(3);
275   effPIDP->Draw("e");
276   effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCInAcceptance);
277   TH1 *effPIDAcc = effCalc->Project(0);
278   effPIDAcc->SetName("effPIDAcc");
279   effPIDAcc->SetTitle("Efficiency of selected tracks in acceptance");
280   effPIDAcc->GetXaxis()->SetTitle("p_{T} / GeV/c");
281   effPIDAcc->GetYaxis()->SetTitle("Efficiency");
282   effPIDAcc->GetYaxis()->SetRangeUser(0.,1.);
283   effPIDAcc->SetMarkerStyle(22);
284   effPIDAcc->SetMarkerColor(kBlue);
285   effPIDAcc->SetLineColor(kBlack);
286   effPIDAcc->SetStats(kFALSE);
287   cEff->cd(4);
288   effPIDAcc->Draw("e");
289   delete effCalc;
290 }
291
292 //____________________________________________________________
293 void AliHFEpostAnalysis::DrawPIDperformance(){
294   //
295   // Plotting Ratio histograms
296   // + All electrons / all candidates (Purity for Electrons)
297   // + All signal electrons / all electrons (Purity for signals)
298   //
299
300   if(!fPIDperformance) return;
301   // Make projection
302   TH1 *electronPurity[3], *signalPurity[3], *fakeContamination[3];
303   electronPurity[0] = CreateHistoPIDperformance(0, 0);
304   electronPurity[1] = CreateHistoPIDperformance(0, 1);
305   electronPurity[2] = CreateHistoPIDperformance(0, 2);
306
307   signalPurity[0] = CreateHistoPIDperformance(1, 0);
308   signalPurity[1] = CreateHistoPIDperformance(1, 1);
309   signalPurity[2] = CreateHistoPIDperformance(1, 2);
310
311   fakeContamination[0] = CreateHistoPIDperformance(2, 0);
312   fakeContamination[1] = CreateHistoPIDperformance(2, 1);
313   fakeContamination[2] = CreateHistoPIDperformance(2, 2);
314
315   // Draw output
316   TCanvas *cRatios = new TCanvas("cRatios", "Ratio Plots", 800, 600);
317   const char *chargename[3] = {"All Charges", "Negative Charge", "Positive Charge"};
318   cRatios->Divide(2,2);
319   TH1 **sample[3] = {&electronPurity[0], &signalPurity[0], &fakeContamination[0]};
320   TLegend *leg;
321   for(Int_t isample = 0; isample < 3; isample++){
322     cRatios->cd(isample + 1);
323     leg = new TLegend(0.7, 0.1, 0.89, 0.3);
324     leg->SetBorderSize(1);
325     leg->SetFillColor(kWhite);
326     for(Int_t icharge = 0; icharge < 3; icharge++){
327       leg->AddEntry(sample[isample][icharge], chargename[icharge], "p");
328       sample[isample][icharge]->Draw(icharge > 0 ? "esame" : "e");
329     }
330     leg->Draw();
331     gPad->Update();
332   }
333 }
334
335 //____________________________________________________________
336 TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){
337   //
338   // Make Histograms for PID performance plots
339   //
340   fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
341   fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
342
343   TH1 *hNom = NULL, *hDenom = NULL;
344   TString hname, htitle, cname;
345   Color_t mycolor = kBlack;
346   if(charge) fPIDperformance->GetAxis(3)->SetRange(charge, charge);
347   // Normalisation by all candidates - no restriction in axis 4 - only for mode == 1 
348   if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,3);
349   hDenom = fPIDperformance->Projection(0);
350   hDenom->Sumw2();
351   hDenom->SetName("hDenom");
352   if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins() + 1);
353   // Nominator need a restriction in the 4th axis
354   switch(mode){
355     case 0: // Electron purity
356       fPIDperformance->GetAxis(4)->SetRange(2,3);
357       hname = "electronPurity";
358       htitle = "Electron Purity";
359       break;
360     case 1: // Signal purity
361       fPIDperformance->GetAxis(4)->SetRange(3,3);   // here signal not divided into charm and beauty
362       hname = "signalPurity";
363       htitle = "Signal Purity";
364       break;
365     case 2: // Fake contamination
366       fPIDperformance->GetAxis(4)->SetRange(1,1);
367       hname = "fakeContamination";
368       htitle = "Contamination of misidentified hadrons";
369       break;
370     default: break;
371   }
372   switch(charge){
373     case 0: 
374       cname = "All"; 
375       mycolor = kBlue;
376       break;
377     case 1: 
378       cname = "Neg"; 
379       mycolor = kBlack;
380       break;
381     case 2: 
382       cname = "Pos"; 
383       mycolor = kRed;
384       break;
385   }
386   hname += cname;
387   hNom = fPIDperformance->Projection(0);
388   hNom->Sumw2();
389   hNom->SetName("hNom");
390   // Reset axis
391   fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
392   if(charge) fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
393
394   // Create Efficiency histogram
395   TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
396   if(hEff){
397     hEff->SetName(hname.Data());
398     hEff->SetTitle(htitle.Data());
399     hEff->Divide(hDenom);
400     hEff->Scale(100.);
401     hEff->GetXaxis()->SetTitle("p_{T} / GeV/c");
402     hEff->GetYaxis()->SetTitle(mode < 2 ? "Purity / %" : "Contamination / %");
403     hEff->GetYaxis()->SetRangeUser(0., 100.);
404     hEff->SetStats(kFALSE);
405     hEff->SetLineColor(kBlack);
406     hEff->SetLineWidth(1);
407     hEff->SetMarkerColor(mycolor);
408     hEff->SetMarkerStyle(22);
409     delete hNom; delete hDenom;
410   }
411   return hEff;
412 }
413
414 //____________________________________________________________
415 void AliHFEpostAnalysis::DrawCutEfficiency(Bool_t MC, Int_t source){
416   //
417   // Calculate efficiency for each cut step
418   // Starting from MC steps 
419   //
420   TCanvas *output = new TCanvas("effCut", "Cut Step efficiency", 800, 600);
421   output->cd();
422   TLegend *leg = new TLegend(0.6, 0.7, 0.89, 0.89);
423   leg->SetHeader("Cut Step:");
424   leg->SetBorderSize(0);
425   leg->SetFillColor(kWhite);
426   leg->SetFillStyle(0);
427
428   AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("mergedTracks", "Container for MC and reconstructed Track information", "MCTrackCont:recTrackContReco");
429   Int_t nStepMC = fEfficiencyContainer->GetCFContainer("MCTrackCont")->GetNStep();
430   AliDebug(1, Form("Number of MC Cut Steps: %d", nStepMC));
431   const Int_t markerStart = 24;
432   const Int_t colorStart = 1;
433   TH1 *hTemp = NULL;
434
435   if(MC){
436     if(source > -1 && source < 4){
437       AliInfo(Form("Setting source to %d", source))
438       for(Int_t istep = 0; istep < tracks->GetNStep(); istep++) tracks->GetAxis(4, istep)->SetRange(source + 1, source + 1);
439     }
440   }
441   AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *tracks);
442   Bool_t first = kTRUE;
443   // Calculate efficiency for MC Steps
444   Int_t histcounter = 0;
445   if(MC){
446     //
447     // Draw plots related to MC values
448     //
449     effcalc.CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
450     hTemp = effcalc.Project(0);
451     hTemp->SetName(Form("hEff%d", histcounter));
452     hTemp->SetTitle("Cut Step Efficiency");
453     hTemp->SetMarkerColor(colorStart + histcounter);
454     hTemp->SetMarkerStyle(markerStart + histcounter);
455     hTemp->GetXaxis()->SetTitle("p / GeV/c");
456     hTemp->GetYaxis()->SetTitle("Efficiency");
457     hTemp->GetYaxis()->SetRangeUser(0., 2.);
458     hTemp->SetStats(kFALSE);
459     hTemp->Draw("ep");
460     leg->AddEntry(hTemp, tracks->GetStepTitle(AliHFEcuts::kStepMCInAcceptance), "p");
461     histcounter++;
462     effcalc.CalculateEfficiency(nStepMC, AliHFEcuts::kStepMCGenerated);
463     hTemp = effcalc.Project(0);
464     hTemp->SetName("hEff2");
465     hTemp->SetTitle("Cut Step Efficiency");
466     hTemp->SetMarkerColor(colorStart + histcounter);
467     hTemp->SetMarkerStyle(markerStart + histcounter);
468     hTemp->GetXaxis()->SetTitle("p / GeV/c");
469     hTemp->GetYaxis()->SetTitle("Efficiency");
470     hTemp->GetYaxis()->SetRangeUser(0., 2.);
471     hTemp->SetStats(kFALSE);
472     hTemp->Draw("epsame");
473     leg->AddEntry(hTemp, tracks->GetStepTitle(nStepMC), "p");
474     first = kFALSE;
475     histcounter++;
476   }
477   for(Int_t istep = nStepMC+1; istep < tracks->GetNStep(); istep++){
478     effcalc.CalculateEfficiency(istep, istep - 1); 
479     hTemp = effcalc.Project(0);
480     hTemp->SetName(Form("hEff%d", istep));
481     hTemp->SetTitle("Cut Step Efficiency");
482     hTemp->SetMarkerColor(colorStart + histcounter);
483     hTemp->SetMarkerStyle(markerStart + histcounter);
484     hTemp->SetStats(kFALSE);
485     hTemp->Draw(first ? "ep" : "epsame");
486     hTemp->GetXaxis()->SetTitle("P / GeV/c");
487     hTemp->GetYaxis()->SetTitle("Efficiency");
488     hTemp->GetYaxis()->SetRangeUser(0., 2.);
489     leg->AddEntry(hTemp, tracks->GetStepTitle(istep), "p");
490     first = kFALSE;
491     histcounter++;
492   }
493   leg->Draw();
494   delete tracks;
495 }