CMS 3D CMS Logo

DisplayManager.py
Go to the documentation of this file.
1 import ROOT
2 import copy
3 import math
4 
6  leg.SetBorderSize(0)
7  leg.SetFillColor(10)
8  leg.SetLineColor(0)
9  leg.SetFillStyle(0)
10 # leg.SetTextSize(0.035)
11 # leg.SetTextFont(42)
12 
13 def createRatioCanvas(name, errorBandFillColor=14, errorBandStyle=3354):
14  cv = ROOT.TCanvas(name.replace('.pdf', ''), name.replace('.pdf', ''), 10, 10, 700, 600)
15  ## this is the tricky part...
16  ## Divide with correct margins
17  cv.Divide(1, 2, 0.0, 0.0)
18  ## Set Pad sizes
19  cv.GetPad(1).SetPad(0.0, 0.32, 1., 1.0)
20  cv.GetPad(2).SetPad(0.0, 0.00, 1., 0.34)
21  cv.GetPad(1).SetFillStyle(4000)
22  cv.GetPad(2).SetFillStyle(4000)
23  ## Set pad margins 1
24  cv.cd(1)
25  ROOT.gPad.SetTopMargin(0.08)
26  ROOT.gPad.SetLeftMargin(0.12)
27  ROOT.gPad.SetBottomMargin(0.03)
28  ROOT.gPad.SetRightMargin(0.1)
29  ## Set pad margins 2
30  cv.cd(2)
31  ROOT.gPad.SetBottomMargin(0.35)
32  ROOT.gPad.SetLeftMargin(0.12)
33  ROOT.gPad.SetRightMargin(0.1)
34 
35  bogyHist = ROOT.TH1F("legendPseudoHist", "", 1, 1., 2.)
36  bogyHist.SetFillColor(errorBandFillColor)
37  bogyHist.SetFillStyle(errorBandStyle)
38  bogyHist.SetLineColor(0)
39 
40  cv.cd(1)
41  return cv
42 
43 def checkDifferences(histos):
44  rel_diff = 0
45  if len(histos)>0:
46  for ib in range(0, histos[0].GetNbinsX()):
47  for ih, h in enumerate(histos):
48  if not ih == 0:
49  if not histos[0].GetBinContent(ib+1) == 0:
50  rel_diff+=((h.GetBinContent(ib+1)-histos[0].GetBinContent(ib+1))/histos[0].GetBinContent(ib+1))*((h.GetBinContent(ib+1)-histos[0].GetBinContent(ib+1))/histos[0].GetBinContent(ib+1))
51  return math.sqrt(rel_diff)
52 
54  def __init__(self, name, ratio):
55  if ratio:
56  self.canvas = createRatioCanvas(name.replace('pdf', ''))
57  else:
58  self.canvas = ROOT.TCanvas(name.replace('.pdf', ''))
59  self.name = name
60  self.draw_ratio = ratio
61  self.histos = []
62  self.Legend = ROOT.TLegend(0.15, 0.79, 0.5, 0.89)
64  self.draw_ratioLegend = ROOT.TLegend(0.15, 0.79, 0.5, 0.89)
66  self.pullRange = 0.5
67  self.box = ROOT.TPave(0.93,0.85,0.98,0.90)
68  self.canvas.Print(self.name + '[')
69 
70  def __del__(self):
71  self.canvas.Print(self.name + ']')
72 
73  def Draw(self, histos, titles):
74  self.histos = histos
75  ymax = max(h.GetMaximum() for h in self.histos)
76  self.Legend.Clear()
77  self.draw_ratioLegend.Clear()
78  for i, h in enumerate(self.histos):
79  title = titles[i]
80  h.GetYaxis().SetRangeUser(0., ymax * 1.3)
81  self.Legend.AddEntry(h, title + ': ' + str(h.Integral()))
82  if i == 0:
83  h.Draw('HIST E')
84  else:
85  h.Draw('SAME HIST E')
86  self.Legend.Draw()
87  ## add an assessment on the agreement
88  rel_diff = checkDifferences(self.histos)
89  self.box.SetLineColor(1)
90  self.box.SetLineWidth(1)
91  self.box.SetShadowColor(0)
92  if rel_diff <= 0.01:
93  self.box.SetFillColor(416) ## kGreen
94  elif rel_diff <= 0.10:
95  self.box.SetFillColor(797) ## kOrange
96  else:
97  self.box.SetFillColor(632) ## kRed
98  self.box.ConvertNDCtoPad()
99  self.box.Draw()
100 
101  pull_histos = []
102  if self.draw_ratio:
103  self.canvas.cd(2)
104  for ihist in range(1, len(self.histos)):
105  histPull = copy.deepcopy(self.histos[ihist])
106  pull_histos.append(histPull)
107  histPull.Divide(self.histos[0])
108  histPull.UseCurrentStyle()
109  histPull.SetLineColor(self.histos[ihist].GetLineColor())
110  histPull.SetMarkerColor(self.histos[ihist].GetLineColor())
111  histPull.SetLineStyle(self.histos[ihist].GetLineStyle())
112  histPull.SetLineWidth(self.histos[ihist].GetLineWidth())
113  histPull.GetYaxis().SetRangeUser(-self.pullRange + 1., self.pullRange + 1.)
114  # defaultYtoPixel = 408. # height in pixels of default canvas
115  defaultYtoPixel = self.canvas.GetPad(1).YtoPixel(0.)
116  pad2YtoPixel = float(self.canvas.GetPad(2).YtoPixel(0))
117  pad2XaxisFactor = defaultYtoPixel / pad2YtoPixel
118  histPull.GetXaxis().SetLabelSize(self.histos[0].GetXaxis().GetLabelSize()*pad2XaxisFactor)
119  histPull.GetXaxis().SetLabelOffset(self.histos[0].GetXaxis().GetLabelOffset()*pad2XaxisFactor)
120  histPull.GetXaxis().SetTitleSize(self.histos[0].GetXaxis().GetTitleSize()*pad2XaxisFactor)
121  histPull.GetXaxis().SetTitleOffset(self.histos[0].GetXaxis().GetTitleOffset()/pad2XaxisFactor*2.5)
122  histPull.GetYaxis().SetLabelSize(self.histos[0].GetYaxis().GetLabelSize()*pad2XaxisFactor)
123  histPull.GetYaxis().SetLabelOffset(self.histos[0].GetYaxis().GetLabelOffset()*pad2XaxisFactor)
124  histPull.GetYaxis().SetTitleSize(self.histos[0].GetYaxis().GetTitleSize()*pad2XaxisFactor)
125  histPull.GetYaxis().SetTitleOffset(self.histos[0].GetYaxis().GetTitleOffset()/pad2XaxisFactor)
126  histPull.GetYaxis().CenterTitle()
127  histPull.GetXaxis().SetTickLength(histPull.GetXaxis().GetTickLength()*pad2XaxisFactor)
128  histPull.GetYaxis().SetNdivisions(306)
129  histPull.GetYaxis().SetTitle("Ratio to " + titles[0])
130  histPull.SetTitle('')
131  if ihist == 1:
132  histPull.Draw("ep")
133  else:
134  histPull.Draw("same ep")
135  self.draw_ratioLegend.AddEntry(histPull, titles[ihist])
136  # This is a little bit ugly though ...
137  for i, h in enumerate(self.histos):
138  h.GetXaxis().SetLabelSize(0)
139  self.canvas.cd(1)
140  self.canvas.Update()
141  self.canvas.Print(self.name)
def __init__(self, name, ratio)
def checkDifferences(histos)
def createRatioCanvas(name, errorBandFillColor=14, errorBandStyle=3354)
def applyLegendSettings(leg)
def Draw(self, histos, titles)