ROOT logo
/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * All rights reserved.                                                   *
 *                                                                        *
 * Primary Authors:                                                       *
 *   Artur Szostak <artursz@iafrica.com>                                  *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/// \ingroup macros
/// \file PlotEfficiency.C
/// \brief Generates efficiency plots from the histograms generated by AliAnalysisTaskLinkToMC.
/// \author Artur Szostak <artursz@iafrica.com>
///
/// This macro is used to generate efficiency plots, fake track ratio plots
/// and also calculate the total integrated efficiency and fake track ratio.
/// The histograms generated by the AliAnalysisTaskLinkToMC analysis task is
/// used as input. The macro can be run with root as follows:
/// 
///  $ root PlotEfficiency.C\(\"hists.root\"\)
///
/// where hists.root is the name of the output file containing the histograms
/// generated by the analysis task. Note that the '\' character before the '('
/// and '"' characters is required. Alternatively run the macros as follows from
/// the root command prompt:
///
///  $ root
///  .L PlotEfficiency.C
///  PlotEfficiency("hists.root")


#if !defined(__CINT__) || defined(__MAKECINT__)
#include "Riostream.h"
#include "TH1.h"
#include "TH2.h"
#include "TFile.h"
#include "TList.h"
#include "TGraphAsymmErrors.h"
#include "TCanvas.h"
#endif


void EfficiencyIntegral(const char* prefix, TH1* pass, TH1* total, double& eff, double& error, bool includeOverflow = false)
{
	/// This routine calculates the integrated efficiency for a 1D histogram.
	/// [in] \param prefix  The string to print before the calculated efficiency result.
	/// [in] \param pass  The histogram of reconstructed tracks.
	/// [in] \param total  The histogram of findable (reconstructable) tracks.
	/// [out] \param eff  Filled by the total integrated efficiency calculated.
	/// [out] \param error  Filled by the uncertainty in the efficiency value.
	/// [in] \param includeOverflow  If set then the overflow bins are also used
	///     in the calculation.
	
	TH1D passhist("temppasshist", "", 1, 0, 1);
	TH1D totalhist("temptotalhist", "", 1, 0, 1);
	if (includeOverflow)
	{
		passhist.SetBinContent(1, pass->Integral(0, pass->GetNbinsX()+1));
		totalhist.SetBinContent(1, total->Integral(0, total->GetNbinsX()+1));
	}
	else
	{
		passhist.SetBinContent(1, pass->Integral(1, pass->GetNbinsX()));
		totalhist.SetBinContent(1, total->Integral(1, total->GetNbinsX()));
	}
	TGraphAsymmErrors* effgraph = new TGraphAsymmErrors(&passhist, &totalhist);
	eff = effgraph->GetY()[0];
	double effhigh = effgraph->GetEYhigh()[0];
	double efflow = effgraph->GetEYlow()[0];
	error = effhigh > efflow ? effhigh : efflow;
	cout << prefix << eff << " + " << effhigh << " - " << efflow << endl;
}


void PlotEfficiency(const char* histfilename = "hists.root", bool includeOverflow = true)
{
	/// Opens the file containing the histograms generated by the AliAnalysisTaskLinkToMC
	/// analysis task and tries to find the first TList in the file.
	/// From the TList we try to find TH2 classes with the following names:
	/// "findableTracksHist", "foundTracksHistMC" and "fakeTracksHist"
	/// From these we plot the efficiency plots for the pT and rapidity dimension
	/// by projecting the 2D histograms. Also, the fake track ratio histograms are
	/// created. Finally the total integrated efficiency and fake track ratio is
	/// calculated and printed.
	/// \param histfilename  The name of the root file containing the histograms
	///    generated by the AliAnalysisTaskLinkToMC analysis task.
	/// \param includeOverflow  Indicates if the overflow bins should be used for
	///    for the total integral efficiency and fake track ratio calculations.
	///    The default is not to use the overflow bins.
	
	TFile file(histfilename);
	
	TList* histolist = NULL;
	TIter next(file.GetListOfKeys());
	for (TObject* key = next(); key != NULL; key = next())
	{
		TList* list = dynamic_cast<TList*>( file.Get(key->GetName()) );
		if (list != NULL)
		{
			histolist = list;
			break;
		}
	}
	
	if (histolist == NULL)
	{
		cout << "ERROR: Could not find the histogram list in file '" << histfilename << "'" << endl;
		return;
	}
	
	TH2* findableTracksHist = dynamic_cast<TH2*>( histolist->FindObject("findableTracksHist") );
	TH2* foundTracksHistMC = dynamic_cast<TH2*>( histolist->FindObject("foundTracksHistMC") );
	TH2* fakeTracksHist = dynamic_cast<TH2*>( histolist->FindObject("fakeTracksHist") );
	
	if (findableTracksHist == NULL)
	{
		cout << "ERROR: Could not find the histogram findableTracksHist in TList '" << histolist->GetName() << "'" << endl;
		return;
	}
	if (foundTracksHistMC == NULL)
	{
		cout << "ERROR: Could not find the histogram foundTracksHistMC in TList '" << histolist->GetName() << "'" << endl;
		return;
	}
	if (fakeTracksHist == NULL)
	{
		cout << "ERROR: Could not find the histogram fakeTracksHist in TList '" << histolist->GetName() << "'" << endl;
		return;
	}
	
	TH1* projeffx = foundTracksHistMC->ProjectionX();
	TH1* projfindx = findableTracksHist->ProjectionX();
	TGraphAsymmErrors* effpt = new TGraphAsymmErrors(projeffx, projfindx);
	effpt->Draw("ap");
	effpt->GetHistogram()->SetTitle("Efficiency of track reconstruction.");
	effpt->GetHistogram()->SetXTitle(projeffx->GetXaxis()->GetTitle());
	effpt->GetHistogram()->SetYTitle("#epsilon");
	effpt->GetYaxis()->SetRangeUser(0, 1.1);
	
	new TCanvas;
	TH1* projfakex = fakeTracksHist->ProjectionX();
	TGraphAsymmErrors* fakept = new TGraphAsymmErrors(projfakex, projfindx);
	fakept->Draw("ap");
	fakept->GetHistogram()->SetTitle("Fake reconstructed tracks ratio.");
	fakept->GetHistogram()->SetXTitle(projfakex->GetXaxis()->GetTitle());
	fakept->GetHistogram()->SetYTitle("fake tracks / findable tracks");
	
	new TCanvas;
	TH1* projeffy = foundTracksHistMC->ProjectionY();
	TH1* projfindy = findableTracksHist->ProjectionY();
	TGraphAsymmErrors* effy = new TGraphAsymmErrors(projeffy, projfindy);
	effy->Draw("ap");
	effy->GetHistogram()->SetTitle("Efficiency of track reconstruction.");
	effy->GetHistogram()->SetXTitle(projeffy->GetXaxis()->GetTitle());
	effy->GetHistogram()->SetYTitle("#epsilon");
	effy->GetYaxis()->SetRangeUser(0, 1.1);
	
	new TCanvas;
	TH1* projfakey = fakeTracksHist->ProjectionY();
	TGraphAsymmErrors* fakey = new TGraphAsymmErrors(projfakey, projfindy);
	fakey->Draw("ap");
	fakey->GetHistogram()->SetTitle("Fake reconstructed tracks ratio.");
	fakey->GetHistogram()->SetXTitle(projfakey->GetXaxis()->GetTitle());
	fakey->GetHistogram()->SetYTitle("fake tracks / findable tracks");
	
	if (includeOverflow)
	{
		cout << "findable tracks = " << projfindx->Integral(0, projfindx->GetNbinsX()+1) << endl;
		cout << "found tracks    = " << projeffx->Integral(0, projeffx->GetNbinsX()+1) << endl;
		cout << "fake tracks     = " << projfakex->Integral(0, projfakex->GetNbinsX()+1) << endl;
	}
	else
	{
		cout << "findable tracks = " << projfindx->Integral(0, projfindx->GetNbinsX()+1) << endl;
		cout << "found tracks    = " << projeffx->Integral(0, projeffx->GetNbinsX()+1) << endl;
		cout << "fake tracks     = " << projfakex->Integral(0, projfakex->GetNbinsX()+1) << endl;
	}
	double eff, fake, deff, dfake;
	EfficiencyIntegral("Total efficiency = ", projeffx, projfindx, eff, deff, includeOverflow);
	EfficiencyIntegral("Total fake ratio = ", projfakex, projfindx, fake, dfake, includeOverflow);
	cout << "Sum = " << eff + fake << " +/- " << sqrt(deff*deff + dfake*dfake) << endl;
}

 PlotEfficiency.C:1
 PlotEfficiency.C:2
 PlotEfficiency.C:3
 PlotEfficiency.C:4
 PlotEfficiency.C:5
 PlotEfficiency.C:6
 PlotEfficiency.C:7
 PlotEfficiency.C:8
 PlotEfficiency.C:9
 PlotEfficiency.C:10
 PlotEfficiency.C:11
 PlotEfficiency.C:12
 PlotEfficiency.C:13
 PlotEfficiency.C:14
 PlotEfficiency.C:15
 PlotEfficiency.C:16
 PlotEfficiency.C:17
 PlotEfficiency.C:18
 PlotEfficiency.C:19
 PlotEfficiency.C:20
 PlotEfficiency.C:21
 PlotEfficiency.C:22
 PlotEfficiency.C:23
 PlotEfficiency.C:24
 PlotEfficiency.C:25
 PlotEfficiency.C:26
 PlotEfficiency.C:27
 PlotEfficiency.C:28
 PlotEfficiency.C:29
 PlotEfficiency.C:30
 PlotEfficiency.C:31
 PlotEfficiency.C:32
 PlotEfficiency.C:33
 PlotEfficiency.C:34
 PlotEfficiency.C:35
 PlotEfficiency.C:36
 PlotEfficiency.C:37
 PlotEfficiency.C:38
 PlotEfficiency.C:39
 PlotEfficiency.C:40
 PlotEfficiency.C:41
 PlotEfficiency.C:42
 PlotEfficiency.C:43
 PlotEfficiency.C:44
 PlotEfficiency.C:45
 PlotEfficiency.C:46
 PlotEfficiency.C:47
 PlotEfficiency.C:48
 PlotEfficiency.C:49
 PlotEfficiency.C:50
 PlotEfficiency.C:51
 PlotEfficiency.C:52
 PlotEfficiency.C:53
 PlotEfficiency.C:54
 PlotEfficiency.C:55
 PlotEfficiency.C:56
 PlotEfficiency.C:57
 PlotEfficiency.C:58
 PlotEfficiency.C:59
 PlotEfficiency.C:60
 PlotEfficiency.C:61
 PlotEfficiency.C:62
 PlotEfficiency.C:63
 PlotEfficiency.C:64
 PlotEfficiency.C:65
 PlotEfficiency.C:66
 PlotEfficiency.C:67
 PlotEfficiency.C:68
 PlotEfficiency.C:69
 PlotEfficiency.C:70
 PlotEfficiency.C:71
 PlotEfficiency.C:72
 PlotEfficiency.C:73
 PlotEfficiency.C:74
 PlotEfficiency.C:75
 PlotEfficiency.C:76
 PlotEfficiency.C:77
 PlotEfficiency.C:78
 PlotEfficiency.C:79
 PlotEfficiency.C:80
 PlotEfficiency.C:81
 PlotEfficiency.C:82
 PlotEfficiency.C:83
 PlotEfficiency.C:84
 PlotEfficiency.C:85
 PlotEfficiency.C:86
 PlotEfficiency.C:87
 PlotEfficiency.C:88
 PlotEfficiency.C:89
 PlotEfficiency.C:90
 PlotEfficiency.C:91
 PlotEfficiency.C:92
 PlotEfficiency.C:93
 PlotEfficiency.C:94
 PlotEfficiency.C:95
 PlotEfficiency.C:96
 PlotEfficiency.C:97
 PlotEfficiency.C:98
 PlotEfficiency.C:99
 PlotEfficiency.C:100
 PlotEfficiency.C:101
 PlotEfficiency.C:102
 PlotEfficiency.C:103
 PlotEfficiency.C:104
 PlotEfficiency.C:105
 PlotEfficiency.C:106
 PlotEfficiency.C:107
 PlotEfficiency.C:108
 PlotEfficiency.C:109
 PlotEfficiency.C:110
 PlotEfficiency.C:111
 PlotEfficiency.C:112
 PlotEfficiency.C:113
 PlotEfficiency.C:114
 PlotEfficiency.C:115
 PlotEfficiency.C:116
 PlotEfficiency.C:117
 PlotEfficiency.C:118
 PlotEfficiency.C:119
 PlotEfficiency.C:120
 PlotEfficiency.C:121
 PlotEfficiency.C:122
 PlotEfficiency.C:123
 PlotEfficiency.C:124
 PlotEfficiency.C:125
 PlotEfficiency.C:126
 PlotEfficiency.C:127
 PlotEfficiency.C:128
 PlotEfficiency.C:129
 PlotEfficiency.C:130
 PlotEfficiency.C:131
 PlotEfficiency.C:132
 PlotEfficiency.C:133
 PlotEfficiency.C:134
 PlotEfficiency.C:135
 PlotEfficiency.C:136
 PlotEfficiency.C:137
 PlotEfficiency.C:138
 PlotEfficiency.C:139
 PlotEfficiency.C:140
 PlotEfficiency.C:141
 PlotEfficiency.C:142
 PlotEfficiency.C:143
 PlotEfficiency.C:144
 PlotEfficiency.C:145
 PlotEfficiency.C:146
 PlotEfficiency.C:147
 PlotEfficiency.C:148
 PlotEfficiency.C:149
 PlotEfficiency.C:150
 PlotEfficiency.C:151
 PlotEfficiency.C:152
 PlotEfficiency.C:153
 PlotEfficiency.C:154
 PlotEfficiency.C:155
 PlotEfficiency.C:156
 PlotEfficiency.C:157
 PlotEfficiency.C:158
 PlotEfficiency.C:159
 PlotEfficiency.C:160
 PlotEfficiency.C:161
 PlotEfficiency.C:162
 PlotEfficiency.C:163
 PlotEfficiency.C:164
 PlotEfficiency.C:165
 PlotEfficiency.C:166
 PlotEfficiency.C:167
 PlotEfficiency.C:168
 PlotEfficiency.C:169
 PlotEfficiency.C:170
 PlotEfficiency.C:171
 PlotEfficiency.C:172
 PlotEfficiency.C:173
 PlotEfficiency.C:174
 PlotEfficiency.C:175
 PlotEfficiency.C:176
 PlotEfficiency.C:177
 PlotEfficiency.C:178
 PlotEfficiency.C:179
 PlotEfficiency.C:180
 PlotEfficiency.C:181
 PlotEfficiency.C:182
 PlotEfficiency.C:183
 PlotEfficiency.C:184
 PlotEfficiency.C:185
 PlotEfficiency.C:186
 PlotEfficiency.C:187
 PlotEfficiency.C:188
 PlotEfficiency.C:189
 PlotEfficiency.C:190
 PlotEfficiency.C:191