CombineHarvester
Plotting_Contours.h
Go to the documentation of this file.
1 #ifndef ICHiggsTauTau_Core_Plotting_Countours_h
2 #define ICHiggsTauTau_Core_Plotting_Countours_h
3 
4 // Mostly copied from here:
5 // https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/blob/master/test/plotting/contours2D.cxx
6 // with minor modifications
7 #include "Plotting.h"
8 
9 #include <iostream>
10 #include <math.h>
11 #include "TGraph.h"
12 #include "TTree.h"
13 #include "TCut.h"
14 #include "TROOT.h"
15 #include "TH2F.h"
16 #include "TMath.h"
17 #include "TPad.h"
18 #include "TStyle.h"
19 #include "TMarker.h"
20 #include "TFile.h"
21 #include "TCanvas.h"
22 #include "TLegend.h"
23 #include "TLatex.h"
24 
25 // ---------------------------------------------------------------------------
26 // Function declarations
27 // ---------------------------------------------------------------------------
28 TGraph *bestFit(TTree *t, TString x, TString y, TCut cut);
29 
30 TH2 *treeToHist2D(TTree *t, TString x, TString y, TString name, TCut cut,
31  double xmin, double xmax, double ymin, double ymax, int xbins,
32  int ybins);
33 
34 TList *contourFromTH2(TH2 *h2in, double threshold, int minPoints = 20);
35 
36 TH2D *frameTH2D(TH2D *in, double threshold);
37 
38 void styleMultiGraph(TList *tmg, int lineColor, int lineWidth, int lineStyle);
39 
40 void styleMultiGraphMarker(TList *tmg, int markerColor, int markerSize,
41  int markerStyle);
42 
43 void drawContours(TPad *pad, TString file, TString x_title, TString y_title,
44  TLegend *leg);
45 // ---------------------------------------------------------------------------
46 // Function implementations
47 // ---------------------------------------------------------------------------
69 void contour2D(TString filein, TString fileout, TString xvar, int xbins, float xmin, float xmax, TString yvar,
70  int ybins, float ymin, float ymax, TString name = "contour2D") {
71  TFile fin(filein);
72  fin.cd();
73  TTree *tree = (TTree *)gFile->Get("limit");
74  TH2 *hist2d = treeToHist2D(tree, xvar, yvar, "h2d", "", xmin, xmax, ymin,
75  ymax, xbins, ybins);
76  hist2d->SetContour(200);
77  hist2d->GetZaxis()->SetRangeUser(0, 21);
78  TGraph *fit = bestFit(tree, xvar, yvar, "");
79  TList *c68 = contourFromTH2(hist2d, 2.30);
80  TList *c95 = contourFromTH2(hist2d, 5.99);
81  TList *c997 = contourFromTH2(hist2d, 11.83);
82  TFile fout(fileout, "RECREATE");
83  fout.cd();
84  hist2d->SetName(name + "_h2d");
85  fout.WriteTObject(hist2d, 0);
86  fit->SetName(name + "_best");
87  fout.WriteTObject(fit, 0);
88  c68->SetName(name + "_c68");
89  fout.WriteTObject(c68, 0, "SingleKey");
90  c95->SetName(name + "_c95");
91  fout.WriteTObject(c95, 0, "SingleKey");
92  c997->SetName(name + "_c997");
93  fout.WriteTObject(c997, 0, "SingleKey");
94  c68->At(1)->Write("second");
95  fout.Close();
96 }
97 
98 
99 
100 TGraph *bestFit(TTree *t, TString x, TString y, TCut cut) {
101  int nfind = t->Draw(y + ":" + x, cut + "deltaNLL == 0");
102  if (nfind == 0) {
103  TGraph *gr0 = new TGraph(1);
104  gr0->SetPoint(0, -999, -999);
105  gr0->SetMarkerStyle(34);
106  gr0->SetMarkerSize(2.0);
107  return gr0;
108  } else {
109  TGraph *gr0 = (TGraph *)gROOT->FindObject("Graph")->Clone();
110  gr0->SetMarkerStyle(34);
111  gr0->SetMarkerSize(2.0);
112  if (gr0->GetN() > 1) gr0->Set(1);
113  return gr0;
114  }
115 }
116 
117 TH2 *treeToHist2D(TTree *t, TString x, TString y, TString name, TCut cut,
118  double xmin, double xmax, double ymin, double ymax, int xbins,
119  int ybins) {
120  t->Draw(Form("2*deltaNLL:%s:%s>>%s_prof(%d,%10g,%10g,%d,%10g,%10g)", y.Data(),
121  x.Data(), name.Data(), xbins, xmin, xmax, ybins, ymin, ymax),
122  cut + "deltaNLL != 0", "PROF");
123  TH2 *prof = (TH2 *)gROOT->FindObject(name + "_prof");
124  TH2D *h2d = new TH2D(name, name, xbins, xmin, xmax, ybins, ymin, ymax);
125  for (int ix = 1; ix <= xbins; ++ix) {
126  for (int iy = 1; iy <= ybins; ++iy) {
127  double z = prof->GetBinContent(ix, iy);
128  if (z == TMath::Infinity()) z = 999;
129  if (z != z)
130  z = (name.Contains("bayes") ? 0 : 999); // protect agains NANs
131  h2d->SetBinContent(ix, iy, z);
132  }
133  }
134  h2d->GetXaxis()->SetTitle(x);
135  h2d->GetYaxis()->SetTitle(y);
136  h2d->SetDirectory(0);
137  return h2d;
138 }
139 
140 TList *contourFromTH2(TH2 *h2in, double threshold, int minPoints) {
141  std::cout << "Getting contour at threshold " << threshold << " from "
142  << h2in->GetName() << std::endl;
143  // http://root.cern.ch/root/html/tutorials/hist/ContourList.C.html
144  Double_t contours[1];
145  contours[0] = threshold;
146  if (h2in->GetNbinsX() * h2in->GetNbinsY() > 10000) minPoints = 50;
147  if (h2in->GetNbinsX() * h2in->GetNbinsY() <= 100) minPoints = 10;
148 
149  TH2D *h2 = frameTH2D((TH2D *)h2in, threshold);
150 
151  h2->SetContour(1, contours);
152 
153  // Draw contours as filled regions, and Save points
154  h2->Draw("CONT Z LIST");
155  gPad->Update(); // Needed to force the plotting and retrieve the contours in
156  // TGraphs
157 
158  // Get Contours
159  TObjArray *conts =
160  (TObjArray *)gROOT->GetListOfSpecials()->FindObject("contours");
161  TList *contLevel = NULL;
162 
163  if (conts == NULL || conts->GetSize() == 0) {
164  printf("*** No Contours Were Extracted!\n");
165  return 0;
166  }
167 
168  TList *ret = new TList();
169  for (int i = 0; i < conts->GetSize(); i++) {
170  contLevel = (TList *)conts->At(i);
171  // printf("Contour %d has %d Graphs\n", i, contLevel->GetSize());
172  for (int j = 0, n = contLevel->GetSize(); j < n; ++j) {
173  TGraph *gr1 = (TGraph *)contLevel->At(j);
174  // printf("\t Graph %d has %d points\n", j, gr1->GetN());
175  if (gr1->GetN() > minPoints) ret->Add(gr1->Clone());
176  // break;
177  }
178  }
179  return ret;
180 }
181 
182 TH2D *frameTH2D(TH2D *in, double threshold) {
183  // NEW LOGIC:
184  // - pretend that the center of the last bin is on the border if the frame
185  // - add one tiny frame with huge values
186  double frameValue = 1000;
187  if (TString(in->GetName()).Contains("bayes")) frameValue = -1000;
188 
189  Double_t xw = in->GetXaxis()->GetBinWidth(1);
190  Double_t yw = in->GetYaxis()->GetBinWidth(1);
191 
192  Int_t nx = in->GetNbinsX();
193  Int_t ny = in->GetNbinsY();
194 
195  Double_t x0 = in->GetXaxis()->GetXmin();
196  Double_t x1 = in->GetXaxis()->GetXmax();
197 
198  Double_t y0 = in->GetYaxis()->GetXmin();
199  Double_t y1 = in->GetYaxis()->GetXmax();
200  Double_t xbins[999], ybins[999];
201  double eps = 0.1;
202  double mult = 5.;
203 
204  xbins[0] = x0 - eps * xw - xw * mult;
205  xbins[1] = x0 + eps * xw - xw * mult;
206  for (int ix = 2; ix <= nx; ++ix) xbins[ix] = x0 + (ix - 1) * xw;
207  xbins[nx + 1] = x1 - eps * xw + 0.5 * xw * mult;
208  xbins[nx + 2] = x1 + eps * xw + xw * mult;
209 
210  ybins[0] = y0 - eps * yw - yw * mult;
211  ybins[1] = y0 + eps * yw - yw * mult;
212  for (int iy = 2; iy <= ny; ++iy) ybins[iy] = y0 + (iy - 1) * yw;
213  ybins[ny + 1] = y1 - eps * yw + yw * mult;
214  ybins[ny + 2] = y1 + eps * yw + yw * mult;
215 
216  TH2D *framed =
217  new TH2D(Form("%s framed", in->GetName()),
218  Form("%s framed", in->GetTitle()), nx + 2, xbins, ny + 2, ybins);
219 
220  // Copy over the contents
221  for (int ix = 1; ix <= nx; ix++) {
222  for (int iy = 1; iy <= ny; iy++) {
223  framed->SetBinContent(1 + ix, 1 + iy, in->GetBinContent(ix, iy));
224  }
225  }
226  // Frame with huge values
227  nx = framed->GetNbinsX();
228  ny = framed->GetNbinsY();
229  for (int ix = 1; ix <= nx; ix++) {
230  framed->SetBinContent(ix, 1, frameValue);
231  framed->SetBinContent(ix, ny, frameValue);
232  }
233  for (int iy = 2; iy <= ny - 1; iy++) {
234  framed->SetBinContent(1, iy, frameValue);
235  framed->SetBinContent(nx, iy, frameValue);
236  }
237 
238  return framed;
239 }
240 
241 // void styleMultiGraph(TList *tmg, int lineColor, int lineWidth, int lineStyle) {
242 // for (int i = 0; i < tmg->GetSize(); ++i) {
243 // TGraph *g = (TGraph *)tmg->At(i);
244 // g->SetLineColor(lineColor);
245 // g->SetLineWidth(lineWidth);
246 // g->SetLineStyle(lineStyle);
247 // }
248 // }
249 
250 // void styleMultiGraphMarker(TList *tmg, int markerColor, int markerSize,
251 // int markerStyle) {
252 // for (int i = 0; i < tmg->GetSize(); ++i) {
253 // TGraph *g = (TGraph *)tmg->At(i);
254 // g->SetMarkerColor(markerColor);
255 // g->SetMarkerSize(markerSize);
256 // g->SetMarkerStyle(markerStyle);
257 // }
258 // }
259 
260 void drawContours(TPad *pad, TString file, TString x_title, TString y_title,
261  TLegend *leg) {
262  TFile infile(file);
263  TH2D *h2d = (TH2D *)gDirectory->Get("contour2D_h2d");
264 
265  h2d->GetXaxis()->SetTitle(x_title);
266  h2d->GetYaxis()->SetTitle(y_title);
267 
268  pad->cd();
269  h2d->Draw("AXIS");
270 
271  TGraph *bestfit = (TGraph *)gDirectory->Get("contour2D_best");
272  std::vector<TGraph *> c68;
273  std::vector<TGraph *> c95;
274 
275  TList * l68 = (TList *)gDirectory->Get("contour2D_c68");
276  for (int i = 0; i < l68->GetSize(); ++i) {
277  c68.push_back((TGraph *)l68->At(i));
278  }
279 
280  TList * l95 = (TList *)gDirectory->Get("contour2D_c95");
281  for (int i = 0; i < l95->GetSize(); ++i) {
282  c95.push_back((TGraph *)l95->At(i));
283  }
284 
285 
286  // TGraph *c68 = (TGraph *)((TList *)gDirectory->Get("contour2D_c68"))->At(0);
287  // TGraph *c95 = (TGraph *)((TList *)gDirectory->Get("contour2D_c95"))->At(0);
288 
289  for (unsigned i = 0; i < c95.size(); ++i) {
290  c95[i]->SetLineStyle(1);
291  c95[i]->SetLineColor(kBlack);
292  // c95[i]->SetLineWidth(3);
293  c95[i]->SetFillColor(kBlue - 10);
294  c95[i]->Draw("F SAME");
295  }
296 
297  for (unsigned i = 0; i < c68.size(); ++i) {
298  c68[i]->SetLineStyle(1);
299  c68[i]->SetLineColor(kBlack);
300  // c68[i]->SetLineWidth(3);
301  c68[i]->SetFillColor(kBlue - 8);
302  c68[i]->Draw("F SAME");
303  }
304 
305  for (unsigned i = 0; i < c95.size(); ++i) c95[i]->Draw("L SAME");
306  for (unsigned i = 0; i < c68.size(); ++i) c68[i]->Draw("L SAME");
307 
308  bestfit->SetMarkerStyle(34);
309  bestfit->SetMarkerSize(3.0);
310  bestfit->SetMarkerColor(kBlack);
311  // bestfit->Draw("P SAME");
312  if (leg) {
313  leg->AddEntry(c95[0], "95% CL", "F");
314  leg->AddEntry(c68[0], "68% CL", "F");
315  }
316  // leg->AddEntry(bestfit, "Best fit", "P");
317 
318  // leg->Draw("SAME");
319 
320  // TLatex *title_latex = new TLatex();
321  // title_latex->SetNDC();
322  // title_latex->SetTextSize(0.035);
323  // title_latex->SetTextFont(62);
324  // title_latex->SetTextAlign(31);
325  // double height = 0.94;
326  // title_latex->DrawLatex(0.95, height,
327  // "19.7 fb^{-1} (8 TeV) + 4.9 fb^{-1} (7 TeV)");
328  // title_latex->SetTextAlign(11);
329  // title_latex->DrawLatex(0.17, height, "H#rightarrow#tau#tau");
330  // title_latex->SetTextSize(0.08);
331  // title_latex->DrawLatex(0.22, 0.84, "#mu#tau_{h}");
332  // canv.SaveAs(output);
333 }
334 
335 #endif
void styleMultiGraphMarker(TList *tmg, int markerColor, int markerSize, int markerStyle)
TH2D * frameTH2D(TH2D *in, double threshold)
TGraph * bestFit(TTree *t, TString x, TString y, TCut cut)
void contour2D(TString filein, TString fileout, TString xvar, int xbins, float xmin, float xmax, TString yvar, int ybins, float ymin, float ymax, TString name="contour2D")
Make a 2D contour plot from the output of MultiDimFit.
void styleMultiGraph(TList *tmg, int lineColor, int lineWidth, int lineStyle)
TList * contourFromTH2(TH2 *h2in, double threshold, int minPoints=20)
TH2 * treeToHist2D(TTree *t, TString x, TString y, TString name, TCut cut, double xmin, double xmax, double ymin, double ymax, int xbins, int ybins)
void drawContours(TPad *pad, TString file, TString x_title, TString y_title, TLegend *leg)