BCMTFChannel.cxx
1 /*
2  * Copyright (C) 2007-2018, the BAT core developer team
3  * All rights reserved.
4  *
5  * For the licensing terms see doc/COPYING.
6  * For documentation see http://mpp.mpg.de/bat
7  */
8 
9 // ---------------------------------------------------------
10 
11 #include <iostream>
12 
13 #include <TCanvas.h>
14 #include <TH1D.h>
15 #include <TH2D.h>
16 #include <TLatex.h>
17 #include <TMath.h>
18 
19 #include "BCMTFTemplate.h"
20 #include "BCMTFSystematicVariation.h"
21 
22 #include "BCMTFChannel.h"
23 
24 // ---------------------------------------------------------
25 BCMTFChannel::BCMTFChannel(const std::string& name)
26  : fData(0)
27  , fFlagChannelActive(true)
28  , fHistUncertaintyBandExpectation(0)
29  , fHistUncertaintyBandPoisson(0)
30 {
31  SetName(name);
32 }
33 
34 // ---------------------------------------------------------
36 {
37  delete fData;
38 
39  for (unsigned int i = 0; i < fTemplateContainer.size(); ++i)
40  delete (fTemplateContainer.at(i));
41 
42  for (unsigned int i = 0; i < fSystematicVariationContainer.size(); ++i)
43  delete (fSystematicVariationContainer.at(i));
44 
45  delete fHistUncertaintyBandExpectation;
46  delete fHistUncertaintyBandPoisson;
47 }
48 
49 // ---------------------------------------------------------
51 {
52  if (fHistUncertaintyBandExpectation) {
53  delete fHistUncertaintyBandExpectation;
54  }
55  fHistUncertaintyBandExpectation = hist;
56 }
57 
58 // ---------------------------------------------------------
59 void BCMTFChannel::PrintTemplates(const std::string& filename)
60 {
61  std::string newFilename(filename);
62  // check if file extension is pdf
63  if ( (newFilename.find_last_of(".") != std::string::npos) &&
64  (newFilename.substr(newFilename.find_last_of(".") + 1) == "pdf") ) {
65  ; // it's a PDF file
66 
67  } else if ( (newFilename.find_last_of(".") != std::string::npos) &&
68  (newFilename.substr(newFilename.find_last_of(".") + 1) == "ps") ) {
69  ; // it's a PS file
70  } else {
71  ; // make it a PDF file
72  newFilename += ".pdf";
73  }
74 
75  // create new canvas
76  TCanvas* c1 = new TCanvas();
77  c1->cd();
78 
79  // get number of templates
80  int ntemplates = int(fTemplateContainer.size());
81 
82  int first_hist = -1;
83  int last_hist = 0;
84 
85  // calculate first and last existing histogram
86  for (int i = 0; i < ntemplates; ++i) {
87  // get histogram
88  TH1D* temphist = GetTemplate(i)->GetHistogram();
89 
90  if (first_hist < 0 && temphist)
91  first_hist = i;
92 
93  if (temphist)
94  last_hist = i;
95  }
96 
97  // Don't print if there are no histograms
98  if ( first_hist < 0 ) {
99  // free memory
100  delete c1;
101 
102  return;
103  }
104 
105  // loop over templates
106  for (int i = 0; i < ntemplates; ++i) {
107 
108  // get histogram
109  TH1D* temphist = GetTemplate(i)->GetHistogram();
110 
111  TLatex* l = new TLatex();
112 
113  // draw
114  if (temphist) {
115  temphist->Draw();
116  l->DrawTextNDC(0.2, 0.9, (fName + "-" + GetTemplate(i)->GetProcessName()).data());
117  }
118 
119  // print
120  if (i == first_hist && (first_hist != last_hist))
121  c1->Print((newFilename + "(").data());
122  else if (i == last_hist && (first_hist != last_hist))
123  c1->Print((newFilename + ")").data());
124  else {
125  if (temphist)
126  c1->Print(newFilename.data());
127  }
128 
129  // free memory
130  delete l;
131  }
132 
133  // free memory
134  delete c1;
135 }
136 
137 // ---------------------------------------------------------
138 void BCMTFChannel::PrintTemplate(int index, const std::string& filename)
139 {
140  // create new canvas
141  TCanvas* c1 = new TCanvas();
142  c1->cd();
143 
144  // get number of systematics
145  unsigned int nsystematics = fSystematicVariationContainer.size();
146 
147  // draw template
148  GetTemplate(index)->GetHistogram()->Draw();
149 
150  // print to file
151  if (nsystematics == 0)
152  c1->Print(filename.data());
153  else
154  c1->Print( (filename + "(").data() );
155 
156  // loop over systematics
157  for (unsigned int isystematic = 0; isystematic < nsystematics; ++isystematic) {
158  c1->cd();
159 
160  // check that histogram exists
161  if (!GetSystematicVariation(isystematic)->GetHistogramUp(index) ||
162  !GetSystematicVariation(isystematic)->GetHistogramDown(index))
163  continue;
164 
165  // get histogram
166  TH1D hist = TH1D(*GetTemplate(index)->GetHistogram());
167  TH1D hist_up(hist);
168  TH1D hist_down(hist);
169 
170  // set style
171  hist.SetFillStyle(0);
172  hist_up.SetFillStyle(0);
173  hist_up.SetLineStyle(2);
174  hist_down.SetFillStyle(0);
175  hist_down.SetLineStyle(3);
176 
177  // get efficiency
178  double efficiency = GetTemplate(index)->GetEfficiency();
179 
180  // scale histogram
181  hist.Scale(efficiency / hist.Integral());
182 
183  // loop over all bins
184  for (int i = 1; i <= hist.GetNbinsX(); ++i) {
185  hist.SetBinContent(i, GetTemplate(index)->GetHistogram()->GetBinContent(i));
186  hist_up.SetBinContent(i, hist.GetBinContent(i) * (1.0 + GetSystematicVariation(isystematic)->GetHistogramUp(index)->GetBinContent(i)));
187  hist_down.SetBinContent(i, hist.GetBinContent(i) * (1.0 - GetSystematicVariation(isystematic)->GetHistogramDown(index)->GetBinContent(i)));
188  }
189 
190  // draw histogram
191  hist_up.Draw("HIST");
192  hist.Draw("HISTSAME");
193  hist_down.Draw("HISTSAME");
194 
195  if (isystematic < nsystematics - 1)
196  c1->Print(filename.data());
197  else
198  c1->Print( (filename + ")").data() );
199  }
200 
201  // free memory
202  delete c1;
203 }
204 
205 // ---------------------------------------------------------
206 void BCMTFChannel::PrintHistUncertaintyBandExpectation(const std::string& filename)
207 {
208  // create new canvas
209  TCanvas* c1 = new TCanvas();
210  c1->cd();
211 
212  // draw histogram
213  fHistUncertaintyBandExpectation->Draw("COLZ");
214  c1->Draw();
215 
216  // print
217  c1->Print(filename.data());
218 
219  // free memory
220  delete c1;
221 }
222 
223 // ---------------------------------------------------------
225 {
226  // calculate histogram
227  int nbinsy_exp = fHistUncertaintyBandExpectation->GetNbinsY();
228  int nbinsx_poisson = fHistUncertaintyBandPoisson->GetNbinsX();
229  int nbinsy_poisson = fHistUncertaintyBandPoisson->GetNbinsY();
230 
231  // loop over x-axis of observation
232  for (int ix = 1; ix <= nbinsx_poisson; ++ix) {
233  double sum_w = 0;
234  // loop over y-axis of expectation and calculate sum of weights
235  for (int iy = 1; iy <= nbinsy_exp; ++iy) {
236  double w = fHistUncertaintyBandExpectation->GetBinContent(ix, iy);
237  sum_w += w;
238  }
239  // loop over y-axis of expectation
240  for (int iy = 1; iy <= nbinsy_exp; ++iy) {
241  double w = fHistUncertaintyBandExpectation->GetBinContent(ix, iy) / sum_w;
242  double expectation = fHistUncertaintyBandExpectation->GetYaxis()->GetBinCenter(iy);
243  // loop over y-axis of observation
244  for (int jbin = 1; jbin <= nbinsy_poisson; ++jbin) {
245  double p = TMath::Poisson(double(jbin - 1), expectation);
246  double bincontent = 0;
247  if (iy > 1)
248  bincontent = fHistUncertaintyBandPoisson->GetBinContent(ix, jbin);
249  fHistUncertaintyBandPoisson->SetBinContent(ix, jbin, bincontent + p * w);
250  }
251  }
252  }
253 
254 }
255 
256 // ---------------------------------------------------------
257 TH1D* BCMTFChannel::CalculateUncertaintyBandPoisson(double minimum, double maximum, int color)
258 {
259  TH1D* hist;
260  {
262  hist = new TH1D(*(fData->GetHistogram()));
263  }
264  hist->SetMarkerSize(0);
265  hist->SetFillColor(color);
266  hist->SetFillStyle(1001);
267 
268  int nbinsx_poisson = fHistUncertaintyBandPoisson->GetNbinsX();
269  int nbinsy_poisson = fHistUncertaintyBandPoisson->GetNbinsY();
270 
271  // loop over x-axis of observation
272  for (int ix = 1; ix <= nbinsx_poisson; ++ix) {
273  double sum_p = 0; // sum of all probabilities inside the interval
274  int limit_min = 0;
275  int limit_max = nbinsx_poisson - 1;
276 
277  // loop over y-axis of observation
278  for (int jbin = 1; jbin <= nbinsy_poisson; ++jbin) {
279  double p = fHistUncertaintyBandPoisson->GetBinContent(ix, jbin);
280  sum_p += p;
281  if (sum_p < minimum)
282  limit_min = jbin;
283  if (sum_p > maximum && (sum_p - p) < maximum )
284  limit_max = jbin - 1;
285  }
286  // hist->SetBinContent(ix, 0.5*double(limit_min+limit_max));
287  // hist->SetBinError(ix, 0.5*double(limit_max-limit_min));
288  double ylimit_min = fHistUncertaintyBandPoisson->GetYaxis()->GetBinCenter(limit_min);
289  double ylimit_max = fHistUncertaintyBandPoisson->GetYaxis()->GetBinCenter(limit_max);
290  hist->SetBinContent(ix, 0.5 * double(ylimit_min + ylimit_max));
291  hist->SetBinError(ix, 0.5 * double(ylimit_max - ylimit_min));
292  }
293 
294  return hist;
295 }
296 
297 // ---------------------------------------------------------
299 {
300  // create new canvas
301  TCanvas* c1 = new TCanvas();
302  c1->cd();
303 
304  // calculate error band
306 
307  TH2D hist(*fHistUncertaintyBandPoisson);
308 
309  int nbinsx_poisson = hist.GetNbinsX();
310  int nbinsy_poisson = hist.GetNbinsY();
311 
312  // loop over x-axis of observation
313  for (int ix = 1; ix <= nbinsx_poisson; ++ix) {
314  double sum_p = 0; // sum of all probabilities inside the interval
315 
316  // loop over y-axis of observation
317  for (int jbin = 1; jbin <= nbinsy_poisson; ++jbin) {
318  double p = hist.GetBinContent(ix, jbin);
319  sum_p += p;
320  hist.SetBinContent(ix, jbin, sum_p);
321  }
322  }
323 
324  // draw histogram
325  hist.Draw("COLZ");
326  c1->Draw();
327 
328  // print
329  c1->Print(filename.data());
330 
331  // free memory
332  delete c1;
333 }
334 
335 // ---------------------------------------------------------
336 void BCMTFChannel::PrintHistUncertaintyBandPoisson(const std::string& filename, const std::string& options)
337 {
338  // create new canvas
339  TCanvas* c1 = new TCanvas();
340  c1->cd();
341 
342  // calculate error band
344 
345  // draw histogram
346  fHistUncertaintyBandPoisson->Draw(options.c_str());
347  c1->Draw();
348 
349  // print
350  c1->Print(filename.data());
351 
352  // free memory
353  delete c1;
354 }
355 
356 // ---------------------------------------------------------
357 void BCMTFChannel::PrintUncertaintyBandPoisson(const std::string& filename, double minimum, double maximum, int color)
358 {
359  // create new canvas
360  TCanvas* c1 = new TCanvas();
361  c1->cd();
362 
363  // calculate error band
364  TH1D* hist = CalculateUncertaintyBandPoisson(minimum, maximum, color);
365 
366  // draw histogram
367  hist->Draw("E2");
368  c1->Draw();
369 
370  // print
371  c1->Print(filename.data());
372 
373  // free memory
374  delete c1;
375 }
376 
377 // ---------------------------------------------------------
void PrintHistUncertaintyBandExpectation(const std::string &filename)
Print histogram for uncertainty band calculation.
void SetHistUncertaintyBandExpectation(TH2D *hist)
Set a histogram ued for the calculation of the error band of the expectation.
void PrintTemplate(int index, const std::string &filename)
Print a particular template with systematics.
A guard object to prevent ROOT from taking over ownership of TNamed objects.
Definition: BCAux.h:171
void PrintHistCumulativeUncertaintyBandPoisson(const std::string &filename)
Print cumulative histogram for uncertainty band calculation.
double GetEfficiency()
Definition: BCMTFTemplate.h:66
BCMTFTemplate * GetTemplate(int index)
Return a template.
Definition: BCMTFChannel.h:76
void PrintHistUncertaintyBandPoisson(const std::string &filename, const std::string &options="COLZ")
Print histogram for uncertainty band calculation.
BCMTFSystematicVariation * GetSystematicVariation(int index)
Return a systematic variation.
Definition: BCMTFChannel.h:83
void PrintUncertaintyBandPoisson(const std::string &filename, double minimum, double maximum, int color)
Print uncertainty band.
void SetName(const std::string &name)
Set the name of the channel.
Definition: BCMTFChannel.h:121
TH1D * GetHistogram()
Definition: BCMTFTemplate.h:71
TH1D * GetHistogramUp(int index)
Returns the histogram correponding to the up-scale variation of the systematic.
BCMTFChannel(const std::string &name)
The default constructor.
void CalculateHistUncertaintyBandPoisson()
Calculate histogram for uncertainty band calculation.
TH1D * GetHistogramDown(int index)
Returns the histogram correponding to the down-scale variation of the systematic. ...
~BCMTFChannel()
The default destructor.
TH1D * CalculateUncertaintyBandPoisson(double minimum, double maximum, int color)
Calculate histogram for uncertainty band calculation and return a TH1D.
void PrintTemplates(const std::string &filename)
Print the templates in this channel.