1 from __future__
import absolute_import
2 from __future__
import print_function
5 from array
import array
11 from six.moves
import range
23 """Sets the PubComm recommended style
25 Just a copy of <http://ghm.web.cern.ch/ghm/plots/MacroExample/tdrstyle.C>
26 @sa ModTDRStyle() to use this style with some additional customisation.
29 R.gStyle.SetCanvasBorderMode(0)
30 R.gStyle.SetCanvasColor(R.kWhite)
31 R.gStyle.SetCanvasDefH(600)
32 R.gStyle.SetCanvasDefW(600)
33 R.gStyle.SetCanvasDefX(0)
34 R.gStyle.SetCanvasDefY(0)
37 R.gStyle.SetPadBorderMode(0)
39 R.gStyle.SetPadColor(R.kWhite)
40 R.gStyle.SetPadGridX(
False)
41 R.gStyle.SetPadGridY(
False)
42 R.gStyle.SetGridColor(0)
43 R.gStyle.SetGridStyle(3)
44 R.gStyle.SetGridWidth(1)
47 R.gStyle.SetFrameBorderMode(0)
48 R.gStyle.SetFrameBorderSize(1)
49 R.gStyle.SetFrameFillColor(0)
50 R.gStyle.SetFrameFillStyle(0)
51 R.gStyle.SetFrameLineColor(1)
52 R.gStyle.SetFrameLineStyle(1)
53 R.gStyle.SetFrameLineWidth(1)
58 R.gStyle.SetHistLineColor(1)
59 R.gStyle.SetHistLineStyle(0)
60 R.gStyle.SetHistLineWidth(1)
64 R.gStyle.SetEndErrorSize(2)
68 R.gStyle.SetMarkerStyle(20)
72 R.gStyle.SetFitFormat(
'5.4g')
73 R.gStyle.SetFuncColor(2)
74 R.gStyle.SetFuncStyle(1)
75 R.gStyle.SetFuncWidth(1)
78 R.gStyle.SetOptDate(0)
83 R.gStyle.SetOptFile(0)
84 R.gStyle.SetOptStat(0)
86 R.gStyle.SetStatColor(R.kWhite)
87 R.gStyle.SetStatFont(42)
88 R.gStyle.SetStatFontSize(0.025)
89 R.gStyle.SetStatTextColor(1)
90 R.gStyle.SetStatFormat(
'6.4g')
91 R.gStyle.SetStatBorderSize(1)
92 R.gStyle.SetStatH(0.1)
93 R.gStyle.SetStatW(0.15)
99 R.gStyle.SetPadTopMargin(0.05)
100 R.gStyle.SetPadBottomMargin(0.13)
101 R.gStyle.SetPadLeftMargin(0.16)
102 R.gStyle.SetPadRightMargin(0.02)
105 R.gStyle.SetOptTitle(0)
106 R.gStyle.SetTitleFont(42)
107 R.gStyle.SetTitleColor(1)
108 R.gStyle.SetTitleTextColor(1)
109 R.gStyle.SetTitleFillColor(10)
110 R.gStyle.SetTitleFontSize(0.05)
119 R.gStyle.SetTitleColor(1,
'XYZ')
120 R.gStyle.SetTitleFont(42,
'XYZ')
121 R.gStyle.SetTitleSize(0.06,
'XYZ')
125 R.gStyle.SetTitleXOffset(0.9)
126 R.gStyle.SetTitleYOffset(1.25)
131 R.gStyle.SetLabelColor(1,
'XYZ')
132 R.gStyle.SetLabelFont(42,
'XYZ')
133 R.gStyle.SetLabelOffset(0.007,
'XYZ')
134 R.gStyle.SetLabelSize(0.05,
'XYZ')
138 R.gStyle.SetAxisColor(1,
'XYZ')
139 R.gStyle.SetStripDecimals(
True)
140 R.gStyle.SetTickLength(0.03,
'XYZ')
141 R.gStyle.SetNdivisions(510,
'XYZ')
142 R.gStyle.SetPadTickX(1)
143 R.gStyle.SetPadTickY(1)
146 R.gStyle.SetOptLogx(0)
147 R.gStyle.SetOptLogy(0)
148 R.gStyle.SetOptLogz(0)
151 R.gStyle.SetPaperSize(20., 20.)
164 R.gStyle.SetHatchesLineWidth(5)
165 R.gStyle.SetHatchesSpacing(0.05)
168 def ModTDRStyle(width=600, height=600, t=0.06, b=0.12, l=0.16, r=0.04):
169 """Modified version of the tdrStyle
172 width (int): Canvas width in pixels
173 height (int): Canvas height in pixels
174 t (float): Pad top margin [0-1]
175 b (float): Pad bottom margin [0-1]
176 l (float): Pad left margin [0-1]
177 r (float): Pad right margin [0-1]
182 R.gStyle.SetCanvasDefW(width)
183 R.gStyle.SetCanvasDefH(height)
188 def_w = float(R.gStyle.GetCanvasDefW())
189 def_h = float(R.gStyle.GetCanvasDefH())
191 scale_h = (def_w / def_h)
if (def_h > def_w)
else 1.
192 scale_w = (def_h / def_w)
if (def_w > def_h)
else 1.
194 def_min = def_h
if (def_h < def_w)
else def_w
196 R.gStyle.SetPadTopMargin(t * scale_h)
198 R.gStyle.SetPadBottomMargin(b * scale_h)
200 R.gStyle.SetPadLeftMargin(l * scale_w)
202 R.gStyle.SetPadRightMargin(r * scale_w)
208 R.gStyle.SetNdivisions(506,
'XYZ')
211 R.gStyle.SetMarkerColor(R.kBlack)
212 R.gStyle.SetMarkerSize(1.0)
214 R.gStyle.SetLabelOffset(0.007,
'YZ')
218 R.gStyle.SetLabelOffset(0.005 * (3. - 2. / scale_h),
'X')
227 title_px = title_size * def_min
229 R.gStyle.SetTitleSize(title_size,
'XYZ')
230 R.gStyle.SetLabelSize(label_size,
'XYZ')
232 R.gStyle.SetTitleXOffset(0.5 * scale_h *
233 (1.2 * (def_h * b * scale_h - 0.6 * title_px)) /
235 R.gStyle.SetTitleYOffset(0.5 * scale_w *
236 (1.2 * (def_w * l * scale_w - 0.6 * title_px)) /
240 R.gStyle.SetPadTickX(0)
241 R.gStyle.SetPadTickY(0)
242 R.gStyle.SetTickLength(0.02,
'XYZ')
244 R.gStyle.SetLegendBorderSize(0)
245 R.gStyle.SetLegendFont(42)
246 R.gStyle.SetLegendFillColor(0)
247 R.gStyle.SetFillColor(0)
252 def SetBirdPalette():
255 'd', [0.0000, 0.1250, 0.2500, 0.3750, 0.5000, 0.6250, 0.7500, 0.8750, 1.0000])
257 'd', [0.2082, 0.0592, 0.0780, 0.0232, 0.1802, 0.5301, 0.8186, 0.9956, 0.9764])
259 'd', [0.1664, 0.3599, 0.5041, 0.6419, 0.7178, 0.7492, 0.7328, 0.7862, 0.9832])
261 'd', [0.5293, 0.8684, 0.8385, 0.7914, 0.6425, 0.4662, 0.3499, 0.1968, 0.0539])
262 R.TColor.CreateGradientColorTable(nRGBs, stops, red, green, blue, 255, 1)
265 def SetDeepSeaPalette():
268 'd', [0.0000, 0.1250, 0.2500, 0.3750, 0.5000, 0.6250, 0.7500, 0.8750, 1.0000])
270 'd', reversed([0./255., 9./255., 13./255., 17./255., 24./255., 32./255., 27./255., 25./255., 29./255.]))
272 'd', reversed([0./255., 0./255., 0./255., 2./255., 37./255., 74./255., 113./255., 160./255., 221./255.]))
274 'd', reversed([28./255., 42./255., 59./255., 78./255., 98./255., 129./255., 154./255., 184./255., 221./255.]))
275 R.TColor.CreateGradientColorTable(nRGBs, stops, red, green, blue, 255, 1)
278 def SetCorrMatrixPalette():
279 R.TColor.CreateGradientColorTable(3,
280 array (
"d", [0.00, 0.50, 1.00]),
281 array (
"d", [1.00, 1.00, 0.00]),
282 array (
"d", [0.70, 1.00, 0.34]),
283 array (
"d", [0.00, 1.00, 0.82]),
288 adapt = R.gROOT.GetColor(color)
289 new_idx = R.gROOT.GetListOfColors().GetLast() + 1
291 new_idx, adapt.GetRed(), adapt.GetGreen(), adapt.GetBlue(),
'', alpha)
292 COL_STORE.append(trans)
293 trans.SetName(
'userColor%i' % new_idx)
297 def Set(obj, **kwargs):
298 for key, value
in six.iteritems(kwargs):
300 getattr(obj,
'Set' + key)()
301 elif isinstance(value, (list, tuple)):
302 getattr(obj,
'Set' + key)(*value)
304 getattr(obj,
'Set' + key)(value)
316 pad = R.TPad(
'pad',
'pad', 0., 0., 1., 1.)
324 upper = R.TPad(
'upper',
'upper', 0., 0., 1., 1.)
325 upper.SetBottomMargin(split_point + gap_high)
326 upper.SetFillStyle(4000)
328 lower = R.TPad(
'lower',
'lower', 0., 0., 1., 1.)
329 lower.SetTopMargin(1 - split_point + gap_low)
330 lower.SetFillStyle(4000)
333 result = [upper, lower]
336 def ThreePadSplit(upper_split_point, split_point, gap_low, gap_high):
337 upper2 = R.TPad(
'upper2',
'upper2', 0., 0., 1., 1.)
338 upper2.SetTopMargin(1 - upper_split_point)
339 upper2.SetBottomMargin(split_point + gap_high)
340 upper2.SetFillStyle(4000)
342 upper1 = R.TPad(
'upper1',
'upper1', 0., 0., 1., 1.)
343 upper1.SetBottomMargin(upper_split_point)
344 upper1.SetFillStyle(4000)
346 lower = R.TPad(
'lower',
'lower', 0., 0., 1., 1.)
347 lower.SetTopMargin(1 - split_point + gap_low)
348 lower.SetFillStyle(4000)
351 result = [upper1, lower, upper2]
354 def MultiRatioSplit(split_points, gaps_low, gaps_high):
355 """Create a set of TPads split vertically on the TCanvas
357 This is a generalisation of the two pad main/ratio split but for the case
358 of multiple ratio pads.
362 split_points (list[float]): Height of each ratio pad as a fraction of the
363 canvas height. Pads will be created from the bottom of the frame
364 upwards. The final, main pad will occupy however much space remains,
365 therefore the size of this list should be [number of pads] - 1.
366 gaps_low (list[float]): Gaps between ratio pad frames created on the
367 lower pad side at each boundary. Give a list of zeroes for no gap
368 between pad frames. Should be the same length as `split_points`.1
369 gaps_high (list[float]): Gaps between ratio pad frames created on the
370 upper pad side at each boundary. Give a list of zeroes for no gap
374 list[TPad]: List of TPads, indexed from top to bottom on the canvas.
377 for i
in range(len(split_points)+1):
378 pad = R.TPad(
'pad%i'%i,
'', 0., 0., 1., 1.)
380 pad.SetBottomMargin(sum(split_points[0:i])+gaps_high[i-1])
381 if i < len(split_points):
382 pad.SetTopMargin(1.-sum(split_points[0:i+1])+gaps_low[i])
383 pad.SetFillStyle(4000)
390 def TwoPadSplitColumns(split_point, gap_left, gap_right):
391 left = R.TPad(
'left',
'left', 0., 0., 1., 1.)
392 left.SetRightMargin(1 - split_point + gap_right)
393 left.SetFillStyle(4000)
395 right = R.TPad(
'right',
'right', 0., 0., 1., 1.)
396 right.SetLeftMargin(split_point + gap_left)
397 right.SetFillStyle(4000)
400 result = [left, right]
404 def MultiRatioSplitColumns(split_points, gaps_left, gaps_right):
406 for i
in range(len(split_points)+1):
407 pad = R.TPad(
'pad%i'%i,
'', 0., 0., 1., 1.)
409 pad.SetLeftMargin(sum(split_points[0:i])+gaps_left[i-1])
410 if i < len(split_points):
411 pad.SetRightMargin(1.-sum(split_points[0:i+1])+gaps_right[i])
412 pad.SetFillStyle(4000)
422 if lower.GetXaxis().GetTitle() ==
'':
423 lower.GetXaxis().SetTitle(upper.GetXaxis().GetTitle())
424 upper.GetXaxis().SetTitle(
"")
425 upper.GetXaxis().SetLabelSize(0)
426 upper_h = 1. - pads[0].GetTopMargin() - pads[0].GetBottomMargin()
427 lower_h = 1. - pads[1].GetTopMargin() - pads[1].GetBottomMargin()
428 lower.GetYaxis().SetTickLength(R.gStyle.GetTickLength() * upper_h / lower_h)
431 lower.GetYaxis().SetTitle(y_title)
432 lower.GetYaxis().CenterTitle(y_centered)
434 lower.SetMinimum(y_min)
435 lower.SetMaximum(y_max)
439 width = xaxis.GetBinWidth(1)
440 w_label = (
"%"+fmt) % width
443 yaxis.SetTitle(
"Events / " + w_label)
445 xaxis.SetTitle(var +
" (" + units +
")")
446 yaxis.SetTitle(
"Events / " + w_label +
" " + units)
466 result = src.GetHistogram().Clone(
'tmp')
470 x = ctypes.c_double(0.)
471 y = ctypes.c_double(0.)
472 src.GetPoint(0, x, y)
475 for i
in range(1, src.GetN()):
476 src.GetPoint(i, x, y)
481 result.GetXaxis().SetLimits(min, max)
490 res.append(h.Clone(
'tmp%i'%i))
495 pad_obs = pad.GetListOfPrimitives()
500 if obj.InheritsFrom(R.TH1.Class()):
502 if obj.InheritsFrom(R.TMultiGraph.Class()):
503 return obj.GetHistogram()
504 if obj.InheritsFrom(R.TGraph.Class()):
505 return obj.GetHistogram()
506 if obj.InheritsFrom(R.THStack.Class()):
507 return obj.GetHistogram()
518 def TFileIsGood(filename):
519 """Performs a series of tests on a TFile to ensure that it can be opened
523 filename: `str` The name of the TFile to check
526 `bool` True if the file can opened, is not a zombie, and if ROOT did
527 not need to try and recover the contents
529 fin = R.TFile(filename)
532 if fin
and not fin.IsOpen():
534 elif fin
and fin.IsOpen()
and fin.IsZombie():
537 elif fin
and fin.IsOpen()
and fin.TestBit(R.TFile.kRecovered):
546 def MakeTChain(files, tree):
547 chain = R.TChain(tree)
554 R.TH1.AddDirectory(
False)
556 res = R.gDirectory.Get(obj)
561 def ParamFromFilename(filename, param):
562 if len(re.findall(param +
'\.\d+\.\d+', filename)):
564 param +
'\.\d+\.\d+', filename)[0].replace(param +
'.',
'')
566 elif len(re.findall(param +
'\.\d+', filename)):
567 num1 = re.findall(param +
'\.\d+', filename)[0].replace(param +
'.',
'')
570 print(
"Error: parameter " + param +
" not found in filename")
583 tree.Draw(xvar +
':' + yvar, selection,
'goff')
584 gr = R.TGraph(tree.GetSelectedRows(), tree.GetV1(), tree.GetV2())
589 tree.Draw(xvar +
':' + yvar +
':' + zvar, selection,
'goff')
591 tree.GetSelectedRows(), tree.GetV1(), tree.GetV2(), tree.GetV3())
595 def RocCurveFrom1DHists(h_x, h_y, cut_is_greater_than):
596 backup = R.TH1.AddDirectoryStatus()
597 R.TH1.AddDirectory(
False)
600 x_err = ctypes.c_double(0.)
601 x_int = h_x.IntegralAndError(0, h_x.GetNbinsX() + 1, x_err)
602 for i
in range(1, h_x.GetNbinsX() + 1):
603 x_part_err = ctypes.c_double(0.)
604 x_part_int = h_x.IntegralAndError(i, h_x.GetNbinsX(
605 ) + 1, x_part_err)
if cut_is_greater_than
else h_x.IntegralAndError(0, i, x_part_err)
606 x_den.SetBinContent(i, x_int)
607 x_den.SetBinError(i, x_err)
608 x_num.SetBinContent(i, x_part_int)
609 x_num.SetBinError(i, x_part_err)
612 y_err = ctypes.c_double(0.)
613 y_int = h_y.IntegralAndError(0, h_y.GetNbinsX() + 1, y_err)
614 for i
in range(1, h_y.GetNbinsX() + 1):
615 y_part_err = ctypes.c_double(0.)
616 y_part_int = h_y.IntegralAndError(i, h_y.GetNbinsX(
617 ) + 1, y_part_err)
if cut_is_greater_than
else h_y.IntegralAndError(0, i, y_part_err)
618 y_den.SetBinContent(i, y_int)
619 y_den.SetBinError(i, y_err)
620 y_num.SetBinContent(i, y_part_int)
621 y_num.SetBinError(i, y_part_err)
626 x_gr = R.TGraphAsymmErrors(x_num, x_den)
627 y_gr = R.TGraphAsymmErrors(y_num, y_den)
630 for i
in range(0, res.GetN()):
631 res.GetX()[i] = x_gr.GetY()[i]
632 res.GetEXlow()[i] = x_gr.GetEYlow()[i]
633 res.GetEXhigh()[i] = x_gr.GetEYhigh()[i]
635 R.TH1.AddDirectory(backup)
639 def TH2FromTGraph2D(graph, method='BinEdgeAligned',
642 """Build an empty TH2 from the set of points in a TGraph2D
644 There is no unique way to define a TH2 binning given an arbitrary
645 TGraph2D, therefore this function supports multiple named methods:
647 - `BinEdgeAligned` simply takes the sets of x- and y- values in the
648 TGraph2D and uses these as the bin edge arrays in the TH2. The
649 implication of this is that when filling the bin contents interpolation
650 will be required when evaluating the TGraph2D at the bin centres.
651 - `BinCenterAligned` will try to have the TGraph2D points at the bin
652 centers, but this will only work completely correctly when the input
653 point spacing is regular. The algorithm first identifies the bin width
654 as the smallest interval between points on each axis. The start
655 position of the TH2 axis is then defined as the lowest value in the
656 TGraph2D minus half this width, and the axis continues with regular
657 bins until the graph maximum is passed.
660 graph (TGraph2D): Should have at least two unique x and y values,
661 otherwise we can't define any bins
662 method (str): The binning algorithm to use
663 force_x_width (bool): Override the derived x-axis bin width in the
665 force_y_width (bool): Override the derived y-axis bin width in the
669 RuntimeError: If the method name is not recognised
672 TH2F: The exact binning of the TH2F depends on the chosen method
677 for i
in range(graph.GetN()):
678 x_vals.add(graph.GetX()[i])
679 y_vals.add(graph.GetY()[i])
681 x_vals = sorted(x_vals)
682 y_vals = sorted(y_vals)
683 if method ==
'BinEdgeAligned':
684 h_proto = R.TH2F(
'prototype',
'',
685 len(x_vals) - 1, array(
'd', x_vals),
686 len(y_vals) - 1, array(
'd', y_vals))
687 elif method ==
'BinCenterAligned':
690 for i
in range(1, len(x_vals)):
691 x_widths.append(x_vals[i] - x_vals[i - 1])
692 for i
in range(1, len(y_vals)):
693 y_widths.append(y_vals[i] - y_vals[i - 1])
694 x_min = min(x_widths)
if force_x_width
is None else force_x_width
695 y_min = min(y_widths)
if force_y_width
is None else force_y_width
696 x_bins = int(((x_vals[-1] - (x_vals[0] - 0.5 * x_min)) / x_min) + 0.5)
697 y_bins = int(((y_vals[-1] - (y_vals[0] - 0.5 * y_min)) / y_min) + 0.5)
698 print(
'[TH2FromTGraph2D] x-axis binning: (%i, %g, %g)' % (x_bins, x_vals[0] - 0.5 * x_min, x_vals[0] - 0.5 * x_min + x_bins * x_min))
699 print(
'[TH2FromTGraph2D] y-axis binning: (%i, %g, %g)' % (y_bins, y_vals[0] - 0.5 * y_min, y_vals[0] - 0.5 * y_min + y_bins * y_min))
702 h_proto = R.TH2F(
'prototype',
'',
704 0] - 0.49999 * x_min, x_vals[0] - 0.50001 * x_min + x_bins * x_min,
705 y_bins, y_vals[0] - 0.49999 * y_min, y_vals[0] - 0.50001 * y_min + y_bins * y_min)
708 '[TH2FromTGraph2D] Method %s not supported' % method)
709 h_proto.SetDirectory(0)
713 def MakeErrorBand(LowerGraph, UpperGraph):
714 errorBand = R.TGraphAsymmErrors()
717 for i
in range(LowerGraph.GetN()):
719 (float(LowerGraph.GetX()[i]), float(LowerGraph.GetY()[i])))
721 (float(UpperGraph.GetX()[i]), float(UpperGraph.GetY()[i])))
722 lower_list = sorted(set(lower_list))
723 upper_list = sorted(set(upper_list))
724 for i
in range(LowerGraph.GetN()):
725 errorBand.SetPoint(i, lower_list[i][0], lower_list[i][1])
726 errorBand.SetPointEYlow(i, lower_list[i][1] - lower_list[i][1])
727 errorBand.SetPointEYhigh(i, upper_list[i][1] - lower_list[i][1])
731 def LimitTGraphFromJSON(js, label):
735 xvals.append(float(key))
736 yvals.append(js[key][label])
737 graph = R.TGraph(len(xvals), array(
'd', xvals), array(
'd', yvals))
742 def LimitTGraphFromJSONFile(jsfile, label):
743 with open(jsfile)
as jsonfile:
744 js = json.load(jsonfile)
745 return LimitTGraphFromJSON(js, label)
747 def ToyTGraphFromJSON(js, label):
750 if isinstance(label,(str,)):
751 for entry
in js[label]:
752 xvals.append(float(entry))
756 return ToyTGraphFromJSON(js,label[0])
758 return ToyTGraphFromJSON(js[label[0]],label[1:])
759 graph = R.TGraph(len(xvals), array(
'd', xvals), array(
'd', yvals))
769 def ToyTGraphFromJSONFile(jsfile, label):
770 with open(jsfile)
as jsonfile:
771 js = json.load(jsonfile)
772 return ToyTGraphFromJSON(js, label)
774 def LimitBandTGraphFromJSON(js, central, lo, hi):
780 xvals.append(float(key))
781 yvals.append(js[key][central])
782 yvals_lo.append(js[key][central] - js[key][lo])
783 yvals_hi.append(js[key][hi] - js[key][central])
784 graph = R.TGraphAsymmErrors(len(xvals), array(
'd', xvals), array(
'd', yvals), array(
785 'd', [0]), array(
'd', [0]), array(
'd', yvals_lo), array(
'd', yvals_hi))
790 def StandardLimitsFromJSONFile(json_file, draw=['obs', 'exp0', 'exp1', 'exp2']):
793 with open(json_file)
as jsonfile:
794 data = json.load(jsonfile)
796 graphs[
'obs'] = LimitTGraphFromJSON(data,
'obs')
797 if 'exp0' in draw
or 'exp' in draw:
798 graphs[
'exp0'] = LimitTGraphFromJSON(data,
'exp0')
799 if 'exp1' in draw
or 'exp' in draw:
800 graphs[
'exp1'] = LimitBandTGraphFromJSON(data,
'exp0',
'exp-1',
'exp+1')
801 if 'exp2' in draw
or 'exp' in draw:
802 graphs[
'exp2'] = LimitBandTGraphFromJSON(data,
'exp0',
'exp-2',
'exp+2')
807 nfind = tree.Draw(y +
":" + x, cut +
"deltaNLL == 0")
810 gr0.SetPoint(0, -999, -999)
812 grc = R.gROOT.FindObject(
"Graph").Clone()
815 gr0.SetPoint(0, grc.GetXmax(), grc.GetYmax())
816 gr0.SetMarkerStyle(34)
817 gr0.SetMarkerSize(2.0)
821 def treeToHist2D(t, x, y, name, cut, xmin, xmax, ymin, ymax, xbins, ybins):
822 t.Draw(
"2*deltaNLL:%s:%s>>%s_prof(%d,%10g,%10g,%d,%10g,%10g)" %
823 (y, x, name, xbins, xmin, xmax, ybins, ymin, ymax), cut +
"deltaNLL != 0",
"PROF")
824 prof = R.gROOT.FindObject(name +
"_prof")
825 h2d = R.TH2D(name, name, xbins, xmin, xmax, ybins, ymin, ymax)
826 for ix
in range(1, xbins + 1):
827 for iy
in range(1, ybins + 1):
828 z = prof.GetBinContent(ix, iy)
829 if (z != z)
or (z > 4294967295):
831 h2d.SetBinContent(ix, iy, z)
832 h2d.GetXaxis().SetTitle(x)
833 h2d.GetYaxis().SetTitle(y)
835 h2d = NewInterpolate(h2d)
839 def makeHist1D(name, xbins, graph, scaleXrange=1.0, absoluteXrange=None):
840 len_x = graph.GetX()[graph.GetN() - 1] - graph.GetX()[0]
841 binw_x = (len_x * 0.5 / (float(xbins) - 1.)) - 1E-5
843 hist = R.TH1F(name,
'', xbins, absoluteXrange[0], absoluteXrange[1])
846 name,
'', xbins, graph.GetX()[0], scaleXrange * (graph.GetX()[graph.GetN() - 1] + binw_x))
850 def makeHist2D(name, xbins, ybins, graph2d):
851 len_x = graph2d.GetXmax() - graph2d.GetXmin()
852 binw_x = (len_x * 0.5 / (float(xbins) - 1.)) - 1E-5
853 len_y = graph2d.GetYmax() - graph2d.GetYmin()
854 binw_y = (len_y * 0.5 / (float(ybins) - 1.)) - 1E-5
855 hist = R.TH2F(name,
'', xbins, graph2d.GetXmin() - binw_x, graph2d.GetXmax() +
856 binw_x, ybins, graph2d.GetYmin() - binw_y, graph2d.GetYmax() + binw_y)
860 def makeVarBinHist2D(name, xbins, ybins):
863 xbins_new = [
None] * (len(xbins) + 1)
864 for i
in range(len(xbins) - 1):
866 xbins_new[i] = xbins[i] - ((xbins[i + 1] - xbins[i]) / 2) + 1E-5
868 xbins_new[i] = xbins[i] - ((xbins[i + 1] - xbins[i]) / 2)
869 xbins_new[len(xbins) - 1] = xbins[len(xbins) - 2] + \
870 ((xbins[len(xbins) - 2] - xbins[len(xbins) - 3]) / 2)
871 xbins_new[len(xbins)] = xbins[len(xbins) - 1] + \
872 ((xbins[len(xbins) - 1] - xbins[len(xbins) - 2]) / 2) - 1E-5
874 ybins_new = [
None] * (len(ybins) + 1)
875 for i
in range(len(ybins) - 1):
877 ybins_new[i] = ybins[i] - ((ybins[i + 1] - ybins[i]) / 2) + 1E-5
879 ybins_new[i] = ybins[i] - ((ybins[i + 1] - ybins[i]) / 2)
880 ybins_new[len(ybins) - 1] = ybins[len(ybins) - 2] + \
881 ((ybins[len(ybins) - 2] - ybins[len(ybins) - 3]) / 2)
882 ybins_new[len(ybins)] = ybins[len(ybins) - 1] + \
883 ((ybins[len(ybins) - 1] - ybins[len(ybins) - 2]) / 2) - 1E-5
884 hist = R.TH2F(name,
'', len(
885 xbins_new) - 1, array(
'd', xbins_new), len(ybins_new) - 1, array(
'd', ybins_new))
889 def GraphDifference(graph1,graph2,relative):
892 if graph1.GetN() != graph2.GetN():
894 for i
in range(graph1.GetN()):
895 xvals.append(graph1.GetX()[i])
897 yvals.append(2*abs(graph1.GetY()[i]-graph2.GetY()[i])/(graph1.GetY()[i]+graph2.GetY()[i]))
899 yvals.append(2*(graph1.GetY()[i]-graph2.GetY()[i])/(graph1.GetY()[i]+graph2.GetY()[i]))
900 diff_graph = R.TGraph(len(xvals),array(
'd',xvals),array(
'd',yvals))
905 def GraphDivide(num, den):
907 for i
in range(num.GetN()):
908 res.GetY()[i] = res.GetY()[i]/den.Eval(res.GetX()[i])
909 if type(res)
is R.TGraphAsymmErrors:
910 for i
in range(num.GetN()):
911 res.GetEYhigh()[i] = res.GetEYhigh()[i]/den.Eval(res.GetX()[i])
912 res.GetEYlow()[i] = res.GetEYlow()[i]/den.Eval(res.GetX()[i])
918 """Make a new ratio TH1 from numerator and denominator TH1s with optional
922 num (TH1): Numerator histogram
923 den (TH1): Denominator histogram
924 num_err (bool): Propagate the error in the numerator TH1
925 den_err (bool): Propagate the error in the denominator TH1
928 TH1: A new TH1 containing the ratio
932 for i
in range(1, result.GetNbinsX()+1):
933 result.SetBinError(i, 0.)
934 den_fix = den.Clone()
936 for i
in range(1, den_fix.GetNbinsX()+1):
937 den_fix.SetBinError(i, 0.)
938 result.Divide(den_fix)
948 def RemoveGraphXDuplicates(graph):
950 while i < graph.GetN() - 1:
951 if graph.GetX()[i + 1] == graph.GetX()[i]:
953 graph.RemovePoint(i + 1)
958 def ApplyGraphYOffset(graph, y_off):
959 for i
in range(graph.GetN() - 1):
960 graph.GetY()[i] = graph.GetY()[i] + y_off
963 def RemoveGraphYAll(graph, val):
964 for i
in range(graph.GetN()):
965 if graph.GetY()[i] == val:
966 print(
'[RemoveGraphYAll] Removing point (%f, %f)' % (graph.GetX()[i], graph.GetY()[i]))
968 RemoveGraphYAll(graph, val)
972 def RemoveSmallDelta(graph, val):
973 for i
in range(graph.GetN()):
974 diff = abs(graph.GetY()[i])
976 print(
'[RemoveSmallDelta] Removing point (%f, %f)' % (graph.GetX()[i], graph.GetY()[i]))
978 RemoveSmallDelta(graph, val)
982 def RemoveGraphYAbove(graph, val):
983 for i
in range(graph.GetN()):
984 if graph.GetY()[i] > val:
988 RemoveGraphYAbove(graph, val)
992 def SetMinToZero(graph):
995 for i
in range(graph.GetN()):
996 if graph.GetY()[i] < min :
997 min = graph.GetY()[i]
999 for i
in range(graph.GetN()):
1000 graph.SetPoint(i, graph.GetX()[i], graph.GetY()[i]-min)
1004 def ImproveMinimum(graph, func, doIt=False):
1008 for i
in range(graph.GetN()):
1009 if graph.GetY()[i] < fit_y:
1011 fit_x = graph.GetX()[i]
1012 fit_y = graph.GetY()[i]
1013 if fit_i == 0
or fit_i == (graph.GetN() - 1):
1015 min_x = graph.GetX()[fit_i]
1016 min_y = graph.GetY()[fit_i]
1017 for i
in range(graph.GetN()):
1018 before = graph.GetY()[i]
1019 graph.GetY()[i] -= min_y
1020 after = graph.GetY()[i]
1021 print(
'Point %i, before=%f, after=%f' % (i, before, after))
1022 return (fit_x, fit_y)
1023 search_min = fit_i - 2
if fit_i >= 2
else fit_i - 1
1024 search_max = fit_i + 2
if fit_i + 2 < graph.GetN()
else fit_i + 1
1025 min_x = func.GetMinimumX(graph.GetX()[search_min], graph.GetX()[search_max])
1026 min_y = func.Eval(min_x)
1027 print(
'[ImproveMinimum] Fit minimum was (%f, %f)' % (fit_x, fit_y))
1028 print(
'[ImproveMinimum] Better minimum was (%f, %f)' % (min_x, min_y))
1030 for i
in range(graph.GetN()):
1031 before = graph.GetY()[i]
1032 graph.GetY()[i] -= min_y
1033 after = graph.GetY()[i]
1034 print(
'Point %i, before=%f, after=%f' % (i, before, after))
1035 graph.Set(graph.GetN() + 1)
1036 graph.SetPoint(graph.GetN() - 1, min_x, 0)
1038 return (min_x, min_y)
1041 def FindCrossingsWithSpline(graph, func, yval):
1045 for i
in range(graph.GetN() - 1):
1046 if (graph.GetY()[i] - yval) * (graph.GetY()[i + 1] - yval) < 0.:
1047 cross = func.GetX(yval, graph.GetX()[i], graph.GetX()[i + 1])
1048 if (graph.GetY()[i] - yval) > 0.
and current
is None:
1051 'hi': graph.GetX()[graph.GetN() - 1],
1055 if (graph.GetY()[i] - yval) < 0.
and current
is None:
1057 'lo': graph.GetX()[0],
1062 intervals.append(current)
1064 if (graph.GetY()[i] - yval) < 0.
and current
is not None:
1065 current[
'hi'] = cross
1066 current[
'valid_hi'] =
True
1067 intervals.append(current)
1072 crossings.append(cross)
1073 if current
is not None:
1074 intervals.append(current)
1075 if len(intervals) == 0:
1077 'lo': graph.GetX()[0],
1078 'hi': graph.GetX()[graph.GetN() - 1],
1082 intervals.append(current)
1091 for i
in range(gr.GetN()):
1092 if gr.GetY()[i] == 0.:
1093 fit_x = gr.GetX()[i]
1094 fit_y = gr.GetY()[i]
1098 for i
in range(gr.GetN()):
1099 if gr.GetY()[i] < min_y:
1100 min_y = gr.GetY()[i]
1101 min_x = gr.GetX()[i]
1103 print(
'[ReZeroTGraph] Fit minimum was (%f, %f)' % (fit_x, fit_y))
1104 print(
'[ReZeroTGraph] Better minimum was (%f, %f)' % (min_x, min_y))
1106 for i
in range(gr.GetN()):
1107 before = gr.GetY()[i]
1108 gr.GetY()[i] -= min_y
1109 after = gr.GetY()[i]
1113 def FilterGraph(gr, n=3):
1116 for i
in range(gr.GetN()):
1117 if gr.GetY()[i] == 0.:
1119 if counter % n < (n - 1):
1120 remove_list.append(i)
1123 for i
in reversed(remove_list):
1127 def RemoveInXRange(gr, xmin=0, xmax=1):
1129 for i
in range(gr.GetN()):
1130 if gr.GetY()[i] == 0.:
1132 if gr.GetX()[i] > xmin
and gr.GetX()[i] < xmax:
1133 remove_list.append(i)
1135 for i
in reversed(remove_list):
1139 def RemoveNearMin(graph, val, spacing=None):
1145 spacing = (graph.GetX()[n - 1] - graph.GetX()[0]) / float(n - 2)
1148 for i
in range(graph.GetN()):
1149 if graph.GetY()[i] == 0.:
1150 bf = graph.GetX()[i]
1155 print(
'[RemoveNearMin] No minimum found!')
1157 for i
in range(graph.GetN()):
1160 if abs(graph.GetX()[i] - bf) < (val * spacing):
1161 print(
'[RemoveNearMin] Removing point (%f, %f) close to minimum at %f' % (graph.GetX()[i], graph.GetY()[i], bf))
1162 graph.RemovePoint(i)
1163 RemoveNearMin(graph, val, spacing)
1167 def SortGraph(Graph):
1168 sortedGraph = R.TGraph()
1170 for i
in range(Graph.GetN()):
1171 graph_list.append((float(Graph.GetX()[i]), float(Graph.GetY()[i])))
1172 graph_list = sorted(set(graph_list))
1173 for i
in range(Graph.GetN()):
1174 sortedGraph.SetPoint(i, graph_list[i][0], graph_list[i][1])
1189 ymin = hobj.GetMinimum()
1190 hobj.SetMaximum((fix_y - fraction * ymin) / (1. - fraction))
1191 if R.gPad.GetLogy():
1193 print(
'Cannot adjust log-scale y-axis range if the minimum is zero!')
1195 maxval = (math.log10(fix_y) - fraction * math.log10(ymin)) / \
1197 maxval = math.pow(10, maxval)
1198 hobj.SetMaximum(maxval)
1201 def FixBothRanges(pad, fix_y_lo, frac_lo, fix_y_hi, frac_hi):
1202 """Adjusts y-axis range such that a lower and a higher value are located a
1203 fixed fraction of the frame height away from a new minimum and maximum
1206 This function is useful in conjunction with GetPadYMax which returns the
1207 maximum or minimum y value of all histograms and graphs drawn on the pad.
1209 In the example below, the minimum and maximum values found via this function
1210 are used as the `fix_y_lo` and `fix_y_hi` arguments, and the spacing fractions
1211 as 0.15 and 0.30 respectively.
1214 FixBothRanges(pad, GetPadYMin(pad), 0.15, GetPadYMax(pad), 0.30)
1217 
1220 pad (TPad): A TPad on which histograms and graphs have already been drawn
1221 fix_y_lo (float): The y value which will end up a fraction `frac_lo` above
1222 the new axis minimum.
1223 frac_lo (float): A fraction of the y-axis height
1224 fix_y_hi (float): The y value which will end up a fraction `frac_hi` below
1225 from the new axis maximum.
1226 frac_hi (float): A fraction of the y-axis height
1231 if R.gPad.GetLogy():
1233 print(
'Cannot adjust log-scale y-axis range if the minimum is zero!')
1235 ymin = math.log10(ymin)
1236 ymax = math.log10(ymax)
1241 (1. / (1. - (fh*fl/((1.-fl)*(1.-fh))))) *
1245 yminn = (ymin - fl*ymaxn) / (1. - fl)
1246 if R.gPad.GetLogy():
1247 yminn = math.pow(10, yminn)
1248 ymaxn = math.pow(10, ymaxn)
1249 hobj.SetMinimum(yminn)
1250 hobj.SetMaximum(ymaxn)
1253 def GetPadYMaxInRange(pad, x_min, x_max, do_min=False):
1254 pad_obs = pad.GetListOfPrimitives()
1260 if obj.InheritsFrom(R.TH1.Class()):
1262 for j
in range(1, hobj.GetNbinsX()+1):
1263 if (hobj.GetBinLowEdge(j) + hobj.GetBinWidth(j) < x_min
or
1264 hobj.GetBinLowEdge(j) > x_max):
1266 if (hobj.GetBinContent(j) + hobj.GetBinError(j) > h_max):
1267 h_max = hobj.GetBinContent(j) + hobj.GetBinError(j)
1268 if (hobj.GetBinContent(j) - hobj.GetBinError(j) < h_min)
and not do_min:
1271 h_min = hobj.GetBinContent(j) - hobj.GetBinError(j)
1272 elif obj.InheritsFrom(R.TGraphAsymmErrors.Class()):
1275 for k
in range(0, n):
1278 if x < x_min
or x > x_max:
1280 if (y + gobj.GetEYhigh()[k]) > h_max:
1281 h_max = y + gobj.GetEYhigh()[k]
1282 if (y - gobj.GetEYlow()[k]) < h_min:
1283 h_min = y - gobj.GetEYlow()[k]
1284 elif obj.InheritsFrom(R.TGraphErrors.Class()):
1287 for k
in range(0, n):
1290 if x < x_min
or x > x_max:
1292 if (y + gobj.GetEY()[k]) > h_max:
1293 h_max = y + gobj.GetEY()[k]
1294 if (y - gobj.GetEY()[k]) < h_min:
1295 h_min = y - gobj.GetEY()[k]
1296 elif obj.InheritsFrom(R.TGraph.Class()):
1299 for k
in range(0, n):
1302 if x < x_min
or x > x_max:
1308 return h_max
if do_min
is False else h_min
1312 pad_obs = pad.GetListOfPrimitives()
1317 return GetPadYMaxInRange(pad, xmin, xmax, do_min)
1320 def GetPadYMin(pad):
1325 R.gPad.GetFrame().Draw()
1337 f_x1 = (p_x1 - pad.GetLeftMargin()) / (1. - pad.GetLeftMargin() - pad.GetRightMargin())
1338 f_x2 = (p_x2 - pad.GetLeftMargin()) / (1. - pad.GetLeftMargin() - pad.GetRightMargin())
1339 f_y1 = (p_y1 - pad.GetBottomMargin()) / (1. - pad.GetTopMargin() - pad.GetBottomMargin())
1344 xmin = hobj.GetBinLowEdge(hobj.GetXaxis().GetFirst())
1345 xmax = hobj.GetBinLowEdge(hobj.GetXaxis().GetLast()+1)
1346 ymin = hobj.GetMinimum()
1347 ymax = hobj.GetMaximum()
1350 a_x1 = xmin + (xmax - xmin) * f_x1
1351 a_x2 = xmin + (xmax - xmin) * f_x2
1354 a_max_h = GetPadYMaxInRange(pad, a_x1, a_x2)
1357 f_max_h = (a_max_h - ymin) / (ymax - ymin);
1358 if R.gPad.GetLogy()
and f_max_h > 0.:
1359 f_max_h = (math.log10(a_max_h) - math.log10(ymin)) / (math.log10(ymax) - math.log10(ymin))
1361 if f_y1 - f_max_h < frac:
1362 f_target = 1. - (f_y1 - frac)
1374 width = xaxis.GetBinWidth(1)
1375 w_label =
"%.1f" % width
1378 yaxis.SetTitle(
"Events / " + w_label)
1380 xaxis.SetTitle(var +
" (" + units +
")")
1381 yaxis.SetTitle(
"Events / " + w_label +
" " + units)
1384 def DrawCMSLogo(pad, cmsText, extraText, iPosX, relPosX, relPosY, relExtraDY, extraText2='', cmsTextSize=0.8):
1388 pad (TYPE): Description
1389 cmsText (TYPE): Description
1390 extraText (TYPE): Description
1391 iPosX (TYPE): Description
1392 relPosX (TYPE): Description
1393 relPosY (TYPE): Description
1394 relExtraDY (TYPE): Description
1395 extraText2 (str): Description
1396 cmsTextSize (float): Description
1404 writeExtraText = len(extraText) > 0
1405 writeExtraText2 = len(extraText2) > 0
1410 lumiTextOffset = 0.2
1415 extraOverCmsTextSize = 0.76
1423 if (iPosX / 10 == 0):
1429 if (iPosX / 10 == 1):
1431 if (iPosX / 10 == 2):
1433 if (iPosX / 10 == 3):
1436 align_ = 10 * alignX_ + alignY_
1438 l = pad.GetLeftMargin()
1439 t = pad.GetTopMargin()
1440 r = pad.GetRightMargin()
1441 b = pad.GetBottomMargin()
1445 latex.SetTextAngle(0)
1446 latex.SetTextColor(R.kBlack)
1448 extraTextSize = extraOverCmsTextSize * cmsTextSize
1449 pad_ratio = (float(pad.GetWh()) * pad.GetAbsHNDC()) / \
1450 (float(pad.GetWw()) * pad.GetAbsWNDC())
1451 if (pad_ratio < 1.):
1455 latex.SetTextFont(cmsTextFont)
1456 latex.SetTextAlign(11)
1457 latex.SetTextSize(cmsTextSize * t * (1./pad_ratio))
1458 latex.DrawLatex(l, 1 - t + lumiTextOffset * t, cmsText)
1462 posX_ = l + relPosX * (1 - l - r)
1463 elif (iPosX % 10 == 2):
1464 posX_ = l + 0.5 * (1 - l - r)
1465 elif (iPosX % 10 == 3):
1466 posX_ = 1 - r - relPosX * (1 - l - r)
1468 posY_ = 1 - t - relPosY * (1 - t - b)
1470 latex.SetTextFont(cmsTextFont)
1471 latex.SetTextSize(cmsTextSize * t * pad_ratio)
1472 latex.SetTextAlign(align_)
1473 latex.DrawLatex(posX_, posY_, cmsText)
1475 latex.SetTextFont(extraTextFont)
1476 latex.SetTextAlign(align_)
1477 latex.SetTextSize(extraTextSize * t * pad_ratio)
1479 posX_, posY_ - relExtraDY * cmsTextSize * t, extraText)
1482 posX_, posY_ - 1.8 * relExtraDY * cmsTextSize * t, extraText2)
1483 elif writeExtraText:
1485 posX_ = l + relPosX * (1 - l - r)
1486 posY_ = 1 - t + lumiTextOffset * t
1487 latex.SetTextFont(extraTextFont)
1488 latex.SetTextSize(extraTextSize * t * (1./pad_ratio))
1489 latex.SetTextAlign(align_)
1490 latex.DrawLatex(posX_, posY_, extraText)
1495 ho = horizontaloffset
1500 l = R.gPad.GetLeftMargin()
1501 t = R.gPad.GetTopMargin()
1502 b = R.gPad.GetBottomMargin()
1503 r = R.gPad.GetRightMargin()
1505 return R.TLegend(l + ho, 1 - t - o - h, l + ho + w, 1 - t - o,
'',
'NBNDC')
1507 c = l + 0.5 * (1 - l - r)
1508 return R.TLegend(c - 0.5 * w, 1 - t - o - h, c + 0.5 * w, 1 - t - o,
'',
'NBNDC')
1510 return R.TLegend(1 - r - ho - w, 1 - t - o - h, 1 - r - ho, 1 - t - o,
'',
'NBNDC')
1512 return R.TLegend(l + ho, b + o, l + ho + w, b + o + h,
'',
'NBNDC')
1514 c = l + 0.5 * (1 - l - r)
1515 return R.TLegend(c - 0.5 * w, b + o, c + 0.5 * w, b + o + h,
'',
'NBNDC')
1517 return R.TLegend(1 - r - ho - w, b + o, 1 - r - ho, b + o + h,
'',
'NBNDC')
1522 xmin = axis.GetXaxis().GetXmin()
1523 xmax = axis.GetXaxis().GetXmax()
1524 line.DrawLine(xmin, yval, xmax, yval)
1527 def DrawVerticalLine(pad, line, xval):
1529 ymin = axis.GetYaxis().GetXmin()
1530 ymax = axis.GetYaxis().GetXmax()
1531 line.DrawLine(xval, ymin, xval, ymax)
1533 def DrawVerticalBand(pad, box, x1, x2):
1535 ymin = axis.GetYaxis().GetXmin()
1536 ymax = axis.GetYaxis().GetXmax()
1537 box.DrawBox(x1, ymin, x2, ymax)
1540 def DrawTitle(pad, text, align, textOffset=0.2,textSize=0.6):
1543 t = pad.GetTopMargin()
1544 l = pad.GetLeftMargin()
1545 r = pad.GetRightMargin()
1547 pad_ratio = (float(pad.GetWh()) * pad.GetAbsHNDC()) / \
1548 (float(pad.GetWw()) * pad.GetAbsWNDC())
1554 latex.SetTextAngle(0)
1555 latex.SetTextColor(R.kBlack)
1556 latex.SetTextFont(42)
1557 latex.SetTextSize(textSize * t * pad_ratio)
1559 y_off = 1 - t + textOffset * t
1561 latex.SetTextAlign(11)
1563 latex.DrawLatex(l, y_off, text)
1565 latex.SetTextAlign(21)
1567 latex.DrawLatex(l + (1 - l - r) * 0.5, y_off, text)
1569 latex.SetTextAlign(31)
1571 latex.DrawLatex(1 - r, y_off, text)
1584 def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
1585 return abs(a-b) <= max(abs_tol, rel_tol * max(abs(a),abs(b)))
1587 def StyleLimitBand(graph_dict, overwrite_style_dict=None):
1589 'obs' : {
'LineWidth' : 2},
1590 'exp0' : {
'LineWidth' : 2,
'LineColor' : R.kRed},
1591 'exp1' : {
'FillColor' : R.kGreen},
1592 'exp2' : {
'FillColor' : R.kYellow}
1594 if overwrite_style_dict
is not None:
1595 for key
in overwrite_style_dict:
1596 if key
in style_dict:
1597 style_dict[key].update(overwrite_style_dict[key])
1599 style_dict[key] = overwrite_style_dict[key]
1600 for key
in graph_dict:
1601 Set(graph_dict[key],**style_dict[key])
1603 def DrawLimitBand(pad, graph_dict, draw=['exp2', 'exp1', 'exp0', 'obs'], draw_legend=None,
1604 legend=None, legend_overwrite=None):
1606 'obs' : {
'Label' :
'Observed',
'LegendStyle' :
'LP',
'DrawStyle' :
'PLSAME'},
1607 'exp0' : {
'Label' :
'Expected',
'LegendStyle' :
'L',
'DrawStyle' :
'LSAME'},
1608 'exp1' : {
'Label' :
'#pm1#sigma Expected',
'LegendStyle' :
'F',
'DrawStyle' :
'3SAME'},
1609 'exp2' : {
'Label' :
'#pm2#sigma Expected',
'LegendStyle' :
'F',
'DrawStyle' :
'3SAME'}
1611 if legend_overwrite
is not None:
1612 for key
in legend_overwrite:
1613 if key
in legend_dict:
1614 legend_dict[key].update(legend_overwrite[key])
1616 legend_dict[key] = legend_overwrite[key]
1619 if key
in graph_dict:
1620 graph_dict[key].Draw(legend_dict[key][
'DrawStyle'])
1621 if legend
is not None:
1622 if draw_legend
is None:
1623 draw_legend = reversed(draw)
1624 for key
in draw_legend:
1625 if key
in graph_dict:
1626 legend.AddEntry(graph_dict[key],legend_dict[key][
'Label'],legend_dict[key][
'LegendStyle'])
1637 def contourFromTH2(h2in, threshold, minPoints=10, frameValue=1000.):
1639 contoursList = [threshold]
1640 contours = array(
'd', contoursList)
1644 h2 =
frameTH2D(h2in, threshold, frameValue)
1646 h2.SetContour(1, contours)
1650 canv = R.TCanvas(
'tmp',
'tmp')
1652 h2.Draw(
'CONT Z LIST')
1655 conts = R.gROOT.GetListOfSpecials().FindObject(
'contours')
1658 if conts
is None or conts.GetSize() == 0:
1659 print(
'*** No Contours Were Extracted!')
1662 for i
in range(conts.GetSize()):
1663 contLevel = conts.At(i)
1664 print(
'>> Contour %d has %d Graphs' % (i, contLevel.GetSize()))
1665 for j
in range(contLevel.GetSize()):
1666 gr1 = contLevel.At(j)
1667 print(
'\t Graph %d has %d points' % (j, gr1.GetN()))
1668 if gr1.GetN() > minPoints:
1669 ret.Add(gr1.Clone())
1676 def frameTH2D(hist, threshold, frameValue=1000):
1683 x_bins = [hist.GetXaxis().GetBinLowEdge(x)
1684 for x
in range(1, hist.GetNbinsX() + 2)]
1685 y_bins = [hist.GetYaxis().GetBinLowEdge(y)
1686 for y
in range(1, hist.GetNbinsY() + 2)]
1689 x_new = [0.] * (len(x_bins) + 4)
1690 y_new = [0.] * (len(y_bins) + 4)
1693 xw1 = x_bins[1] - x_bins[0]
1694 xw2 = x_bins[-1] - x_bins[-2]
1695 yw1 = y_bins[1] - y_bins[0]
1696 yw2 = y_bins[-1] - y_bins[-2]
1700 x_new[0] = x_bins[0] - 2 * xw1 * 0.02
1701 x_new[1] = x_bins[0] - 1 * xw1 * 0.02
1702 x_new[-1] = x_bins[-1] + 2 * xw2 * 0.02
1703 x_new[-2] = x_bins[-1] + 1 * xw2 * 0.02
1704 y_new[0] = y_bins[0] - 2 * yw1 * 0.02
1705 y_new[1] = y_bins[0] - 1 * yw1 * 0.02
1706 y_new[-1] = y_bins[-1] + 2 * yw2 * 0.02
1707 y_new[-2] = y_bins[-1] + 1 * yw2 * 0.02
1710 for i
in range(0, len(x_bins)):
1711 x_new[i + 2] = x_bins[i]
1712 for i
in range(0, len(y_bins)):
1713 y_new[i + 2] = y_bins[i]
1718 framed = R.TH2D(
'%s framed' % hist.GetName(),
'%s framed' % hist.GetTitle(), len(
1719 x_new) - 1, array(
'd', x_new), len(y_new) - 1, array(
'd', y_new))
1720 framed.SetDirectory(0)
1722 for x
in range(1, framed.GetNbinsX() + 1):
1723 for y
in range(1, framed.GetNbinsY() + 1):
1724 if x == 1
or x == framed.GetNbinsX()
or y == 1
or y == framed.GetNbinsY():
1726 framed.SetBinContent(x, y, frameValue)
1734 elif x == (len(x_new) - 2):
1738 elif y == (len(y_new) - 2):
1740 framed.SetBinContent(x, y, hist.GetBinContent(ux - 2, uy - 2))
1743 def fastFillTH2(hist2d, graph, initalValue=99999, interpolateMissing=False):
1744 for x
in range(1,hist2d.GetNbinsX()+1):
1745 for y
in range(1,hist2d.GetNbinsY()+1):
1746 hist2d.SetBinContent(x,y,initalValue)
1749 for i
in range(graph.GetN()):
1750 xbin = hist2d.GetXaxis().FindBin(graph.GetX()[i])
1751 ybin = hist2d.GetYaxis().FindBin(graph.GetY()[i])
1752 if isclose(hist2d.GetXaxis().GetBinCenter(xbin), graph.GetX()[i], rel_tol=1e-2)
and isclose(hist2d.GetYaxis().GetBinCenter(ybin), graph.GetY()[i], rel_tol=1e-2):
1753 hist2d.SetBinContent(xbin, ybin, graph.GetZ()[i])
1755 if interpolateMissing:
1756 for x
in range(1,hist2d.GetNbinsX()+1):
1757 for y
in range(1,hist2d.GetNbinsY()+1):
1758 if hist2d.GetBinContent(x,y) == initalValue:
1760 hist2d.SetBinContent(x, y, graph.Interpolate(hist2d.GetXaxis().GetBinCenter(x),hist2d.GetYaxis().GetBinCenter(y)))
1762 def fillTH2(hist2d, graph):
1763 for x
in range(1, hist2d.GetNbinsX() + 1):
1764 for y
in range(1, hist2d.GetNbinsY() + 1):
1765 xc = hist2d.GetXaxis().GetBinCenter(x)
1766 yc = hist2d.GetYaxis().GetBinCenter(y)
1767 val = graph.Interpolate(xc, yc)
1768 hist2d.SetBinContent(x, y, val)
1770 def fillInvertedTH2(hist2d, graph):
1771 for x
in range(1, hist2d.GetNbinsX() + 1):
1772 for y
in range(1, hist2d.GetNbinsY() + 1):
1773 xc = hist2d.GetXaxis().GetBinCenter(x)
1774 yc = hist2d.GetYaxis().GetBinCenter(y)
1775 val = graph.Interpolate(xc, yc)
1776 hist2d.SetBinContent(x, y, 1-val)
1783 def NewInterpolate(hist):
1784 histCopy = hist.Clone()
1787 hist_step1 = histCopy.Clone()
1789 hist_step2 = histCopy.Clone()
1792 nBinsX = histCopy.GetNbinsX()
1793 nBinsY = histCopy.GetNbinsY()
1797 xMax = histCopy.GetNbinsX() + 1
1798 yMax = histCopy.GetNbinsY() + 1
1800 for i
in range(1, nBinsX + 1):
1801 for j
in range(1, nBinsY + 1):
1803 if (i < xMin)
or (i > xMax)
or (j < yMin)
or (j > yMax):
1805 binContent = histCopy.GetBinContent(i, j)
1806 binContentNW = histCopy.GetBinContent(i + 1, j + 1)
1807 binContentSE = histCopy.GetBinContent(i - 1, j - 1)
1808 binContentNE = histCopy.GetBinContent(i + 1, j - 1)
1809 binContentSW = histCopy.GetBinContent(i - 1, j + 1)
1810 binContentUp = histCopy.GetBinContent(i, j + 1)
1811 binContentDown = histCopy.GetBinContent(i, j - 1)
1812 binContentLeft = histCopy.GetBinContent(i - 1, j)
1813 binContentRight = histCopy.GetBinContent(i + 1, j)
1815 if(binContentNW > 0):
1817 if(binContentSE > 0):
1819 if(binContentNE > 0):
1821 if(binContentSW > 0):
1823 if(binContentUp > 0):
1825 if(binContentDown > 0):
1827 if(binContentRight > 0):
1829 if(binContentLeft > 0):
1833 if(binContent == 0)
and (nFilled > 1):
1835 binContent = (binContentNW + binContentSE + binContentNE + binContentSW +
1836 binContentUp + binContentDown + binContentRight + binContentLeft) / nFilled
1837 hist_step1.SetBinContent(i, j, binContent)
1840 histCopy.Add(hist_step1)
1842 for i
in range(1, nBinsX):
1843 for j
in range(1, nBinsY):
1844 if(i < xMin)
or (i > xMax)
or (j < yMin)
or (j > yMax):
1846 binContent = histCopy.GetBinContent(i, j)
1848 binContentUp = histCopy.GetBinContent(i, j + 1)
1849 binContentDown = histCopy.GetBinContent(i, j - 1)
1850 binContentLeft = histCopy.GetBinContent(i - 1, j)
1851 binContentRight = histCopy.GetBinContent(i + 1, j)
1853 if(binContentUp > 0):
1855 if(binContentDown > 0):
1857 if(binContentRight > 0):
1859 if(binContentLeft > 0):
1861 if(binContent == 0)
and (nFilled > 0):
1864 binContentUp + binContentDown + binContentRight + binContentLeft) / nFilled
1865 hist_step2.SetBinContent(i, j, binContent)
1867 histCopy.Add(hist_step2)
1873 histName = hist.GetName()
1874 histName +=
"_rebin"
1882 histRebinned = R.TH2F(histName, histName, 2 * hist.GetNbinsX() - 1, hist.GetXaxis().GetXmin(),
1883 hist.GetXaxis().GetXmax(), 2 * hist.GetNbinsY() - 1, hist.GetYaxis().GetXmin(), hist.GetYaxis().GetXmax())
1886 for iX
in range(1, hist.GetNbinsX() + 1):
1887 for iY
in range(1, hist.GetNbinsY() + 1):
1888 binContent = hist.GetBinContent(iX, iY)
1889 histRebinned.SetBinContent(2 * iX - 1, 2 * iY - 1, binContent)
1890 histRebinned.SetMaximum(hist.GetMaximum())
1891 histRebinned.SetMinimum(hist.GetMinimum())
1894 histRebinnedInterpolated = NewInterpolate(histRebinned)
1896 return histRebinnedInterpolated
1899 def higgsConstraint(model, higgstype):
1900 higgsBand = R.TGraph2D()
1905 for mass
in range(masslow, masshigh, massstep):
1906 myfile = open(
"../../HiggsAnalysis/HiggsToTauTau/data/Higgs125/" +
1907 model +
"/higgs_" + str(mass) +
".dat",
'r')
1909 tanb = (line.split())[0]
1910 mh = float((line.split())[1])
1911 mH = float((line.split())[3])
1912 if higgstype ==
"h":
1913 higgsBand.SetPoint(n, mass, float(tanb), mh)
1914 elif higgstype ==
"H":
1915 higgsBand.SetPoint(n, mass, float(tanb), mH)
1921 def getOverlayMarkerAndLegend(legend, entries, options, borderSize=2.0/3, markerStyle="P"):
1922 borderLegend = legend.Clone()
1923 borderLegend.Clear()
1925 for i
in range(legend.GetNRows()):
1927 graph = entries[i].Clone()
1928 options[i][
"MarkerSize"] = graph.GetMarkerSize()*borderSize
1929 Set(graph,**options[i])
1930 borderLegend.AddEntry(graph,
" ", markerStyle)
1931 graphs.append(graph)
1933 borderLegend.AddEntry(
"",
" ",
"")
1934 borderLegend.SetFillStyle(0)
1935 borderLegend.SetFillColor(0)
1936 return (borderLegend,graphs)
void FixBoxPadding(TPad *pad, TBox *box, double frac)
Modify the pad y-axis range to ensure there is at least a given gap between a particular TBox and the...
void DrawTitle(TPad *pad, TString text, int align)
Draw text in the top-margin region of a TPad.
void FixOverlay()
Just re-draws the axes on the current TPad.
TH1 * MakeRatioHist(TH1 *num, TH1 *den, bool num_err, bool den_err)
Create a new histogram by dividing one by the other.
void FixTopRange(TPad *pad, double fix_y, double fraction)
Adjusts the y-axis maximum on the pad such that the specified y-value is positioned a fixed fraction ...
TLegend * PositionedLegend(double width, double height, int pos, double offset)
Create a legend with fixed height, width and positioning.
TGraph TGraphFromTree(TTree *tree, TString const &xvar, TString const &yvar, TString const &selection="")
Create a TGraph from entries in a TTree.
double GetPadYMax(TPad *pad, double x_min, double x_max)
Find the maximum value of all drawn objects in a given x-axis range.
void StandardAxes(TAxis *xaxis, TAxis *yaxis, TString var, TString units)
Sets standard x- and y-axis titles with given units.
std::vector< TPad * > OnePad()
Just creates a single pad filling the entire canvas.
TLine * DrawHorizontalLine(TPad *pad, TLine *line, double yval)
Use an existing TLine to draw a new horizontal line across the current frame.
std::vector< TH1 * > CreateAxisHists(unsigned n, TH1 *src, double xmin=0, double xmax=-1)
Create multiple axis TH1s from another TH1.
TH1 * GetAxisHist(TPad *pad)
Finds the TH1 used to draw the axes on a given TPad.
void SetupTwoPadSplitAsRatio(std::vector< TPad * > const &pads, TH1 *upper, TH1 *lower, TString y_title, bool y_centered, float y_min, float y_max)
Set a few style options for a two-pad setup used to show a data-MC comparison and ratio plot.
void DrawCMSLogo(TPad *pad, TString cmsText, TString extraText, int iPosX, float relPosX, float relPosY, float relExtraDY)
Draw the CMS logo and subtitle in the new style.
TH1 * CreateAxisHist(TH1 *src, double xmin=0, double xmax=-1)
Create an empty TH1 from another TH1 for drawing the axes.
int CreateTransparentColor(int color, float alpha)
Create a transparent version of a colour.
std::vector< TPad * > TwoPadSplit(double split_point, double gap_low, double gap_high)
Create two pads, split horizontally, on the current canvas split.
void ReZeroTGraph(TGraph *gr)
Shift all the graph y-values upwards such that there are no negative values and the minimum point is ...
TGraph2D TGraph2DFromTree(TTree *tree, TString const &xvar, TString const &yvar, TString const &zvar, TString const &selection="")
Create a TGraph2D from entries in a TTree.
TH2D * frameTH2D(TH2D *in, double threshold)
TGraph * bestFit(TTree *t, TString x, TString y, TCut cut)
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 SetTDRStyle()
Sets the semi-official CMS plotting global style.
void ModTDRStyle(int width, int height, double t, double b, double l, double r)
Sets an improved plotting style, using the CMS default as a base.