ATLAS Offline Software
PlotUtils.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 #!/usr/bin/env python
4 import ROOT, math, os
5 from array import array
6 
8  Out = In
9  NotWantedChars = ["{", "}", "[", "]", "#", "^", ")", "(", "'", " ", "-"]
10  ReplaceChars = [".", ","]
11  for C in NotWantedChars:
12  Out = Out.replace(C, "")
13  for C in ReplaceChars:
14  Out = Out.replace(C, "_")
15  return Out
16 
17 
19  def __init__(self, name = "",
20  axis_title = "",
21  bins = -1,
22  bmin = 0.,
23  bmax = -1.e9,
24  bin_width = -1,
25  bdir = None,
26  log_binning = False):
27  self.__name = name
28  self.__xTitle = axis_title
29  self.__min = bmin
30  self.__width = bin_width
31  self.__entries = 0
32  self.__content = {}
33  self.__error = {}
34  self.__TH1 = None
35  self.__TDir = bdir
36 
37  self.__log_binning = log_binning
38  if bins > 0 and not log_binning:
39  self.__width = (bmax-bmin)/ bins
40  self.__TH1 = ROOT.TH1D(name, "Diagnostic histogram", bins, bmin, bmax)
41  self.__TH1.SetDirectory(bdir)
42  elif bins > 0:
43  log_start = math.log(bmin)
44  log_end = math.log(bmax)
45  log_step = (log_end -log_start) / bins
46  binning = array("f", [math.exp(log_start +n*log_step) for n in range(bins+1)])
47  self.__TH1 = ROOT.TH1D(name, "Diagnostic histogram", bins, binning)
48  self.__TH1.SetDirectory(bdir)
49 
50  def has_log_binnnig(self): return self.__log_binning
51  def name(self): return self.__name
52  def TH1(self): return self.__TH1
53  def fill(self, value, weight=1.):
54  self.__entries +=1
55  if self.__TH1: self.__TH1.Fill(value, weight)
56  else:
57  rng = self.__getInterval(value)
58  try: self.__content[rng] += weight
59  except: self.__content[rng] = weight
60  try: self.__error[rng] += weight**2
61  except: self.__error[rng] = weight**2
62  def __getInterval(self,value):
63  i = math.ceil( (value - self.__min) / self.__width)
64  return (self.__min +self.__width*(i-1), self.__min+ self.__width*i)
65  def write(self):
66  self.fixHisto()
67  if not self.__TH1: return
68  self.__TH1.GetXaxis().SetTitle(self.__xTitle)
69 
70  self.TH1().SetBinContent(self.TH1().GetNbinsX(),self.TH1().GetBinContent(self.TH1().GetNbinsX()+1) + self.TH1().GetBinContent(self.TH1().GetNbinsX()))
71  self.TH1().SetBinError(self.TH1().GetNbinsX(), math.sqrt( (self.TH1().GetBinError(self.TH1().GetNbinsX()+1) + self.TH1().GetBinError(self.TH1().GetNbinsX()))**2))
72 
73  self.TH1().SetBinContent(1,self.TH1().GetBinContent(0) + self.TH1().GetBinContent(1))
74  self.TH1().SetBinError(1, math.sqrt( (self.TH1().GetBinError(0) + self.TH1().GetBinError(1))**2))
75 
76  self.__TH1.SetEntries(self.__entries)
77  if self.__TDir: self.__TDir.WriteObject(self.__TH1, self.__name)
78  def max(self):
79  try: return sorted(self.__content.iterkeys(), key=lambda Rng: Rng[1])[-1][1]
80  except: return float('nan')
81  def min(self):
82  try: return sorted(self.__content.iterkeys(), key=lambda Rng: Rng[0])[0][1]
83  except: return float('nan')
84  def setMinimum(self, minimum): self.__min = minimum
85  def setMaximum(self, maximum): self.__max = maximum
86  def fixHisto(self):
87  if self.__TH1: return
88  bins = min (int((self.__max - self.__min) / self.__width), 10000)
89  self.__TH1 = ROOT.TH1D(self.name(), "Diagnostic histogram", bins, self.__min, self.__max)
90  self.__TH1.SetDirectory(self.__TDir)
91 
92  for rng in self.__content.iterkeys():
93  bin = self.__TH1.FindBin((rng[1] + rng[0])/2.)
94  self.__TH1.SetBinContent(bin, self.__content[rng])
95  self.__TH1.SetBinError(bin, math.sqrt(self.__error[rng]))
96 
98  def __init__(self, size=18, status="Internal", lumi=1., sqrts="13", normalizedToUnity=False):
99  self.__Status = status
100  self.__Size = size
101  self.__Lumi = lumi # in fb^-1
102  self.__SqrtS = sqrts
104  self.__Canvas = None
105  self.__Pad1 = None
106  self.__Pad2 = None
107  self.__Styling = None
108  self.__RatStyling = None
109  self.__Legend = None
110  self.__NLegEnt = 0
111  self.__normalizedToUnity = normalizedToUnity
112  self.__Objects = []
113 
114  def DrawTLatex(self, x, y, text, size=18, font=43, align=11, ndc=True, color=-1):
115  tex = ROOT.TLatex()
116  tex.SetTextAlign(align)
117  tex.SetTextSize(size)
118  tex.SetTextFont(font)
119  if ndc: tex.SetNDC()
120  if color > -1: tex.SetTextColor(color)
121  self.__Objects.append(tex)
122  tex.DrawLatex(x, y, text)
123 
124  def GetStatus(self):
125  return self.__Status
126 
127  def GetLumi(self):
128  return self.__Lumi
129 
130  def DrawAtlas(self, x, y, align=11):
131  # print "Size is %.2f"%self.__Size
132  self.DrawTLatex(x, y, "#font[72]{ATLAS} %s" % self.__Status, self.__Size, 43, align)
133 
134  def DrawLumiSqrtS(self, x, y, align=11, lumi=1.):
135  if self.__normalizedToUnity: self.DrawTLatex(x, y, "#sqrt{s} = %s TeV" % (self.__SqrtS), self.__Size, 43, align)
136  elif self.__Lumi >= 999999999: self.DrawTLatex(x, y, "#sqrt{s} = %s TeV, ?? pb^{-1}" % (self.__SqrtS), self.__Size, 43, align)
137  elif self.__Lumi < 1.e-6:
138  lumiToPrint = "%.0f" % (self.__Lumi * 1e6)
139  self.DrawTLatex(x, y, "#sqrt{s} = %s TeV, %s nb^{-1}" % (self.__SqrtS, lumiToPrint), self.__Size, 43, align)
140  elif self.__Lumi < 1.e-3:
141  lumiToPrint = "%.0f" % (self.__Lumi * 1e3)
142  self.DrawTLatex(x, y, "#sqrt{s} = %s TeV, %s pb^{-1}" % (self.__SqrtS, lumiToPrint), self.__Size, 43, align)
143  else:
144  lumiToPrint = "%.1f" % (self.__Lumi)
145  self.DrawTLatex(x, y, "#sqrt{s} = %s TeV, %s fb^{-1}" % (self.__SqrtS, lumiToPrint), self.__Size, 43, align)
146 
147  def DrawSqrtS(self, x, y, align=11):
148  self.DrawTLatex(x, y, "#sqrt{s} = %s TeV" % (self.__SqrtS), self.__Size, 43, align)
149 
150 
151  def CreateLegend(self, x1, y1, x2, y2, textsize=22):
152  if self.__Legend:
153  print "WARNING: There already exists a legend. Will delete the old one"
154  del self.__Legend
155  self.__Legend = ROOT.TLegend(x1, y1, x2, y2)
156  self.__Legend.SetFillStyle(0)
157  self.__Legend.SetBorderSize(0)
158  self.__Legend.SetTextFont(43)
159  self.__Legend.SetTextSize(textsize)
160  return self.__Legend
161 
162  def GetLegend(self, x1=0, y1=1., x2=1., y2=1.):
163  if not self.__Legend: return CreateLegend(x1, y1, x2, y2)
164  return self.__Legend
165 
166  def AddToLegend(self, Items, Style="FL"):
167  if isinstance(Items, list):
168  for I in Items:
169  self.__AddItemToLegend(I, Style)
170  else:
171  self.__AddItemToLegend(Items, Style)
172 
173  def __AddItemToLegend(self, Item, Style):
174  try:
175  self.__Legend.AddEntry(Item, Item.GetTitle(), Style)
176  except:
177  self.__Legend.AddEntry(Item.get(), Item.GetTitle(), Style)
178 
179  self.__NLegEnt += 1
180 
181  def DrawLegend(self, NperCol=3):
182  if not self.__Legend:
183  print "No legend has been defined yet"
184  return
185  N = self.__NLegEnt
186  Col = int((N - N % NperCol) / NperCol + (N % NperCol > 0))
187  if Col < 1: Col = 1
188  self.__Legend.SetNColumns(Col)
189  self.__Legend.Draw()
190 
191  def DrawSource(self, probe, x, y, align=11):
192  self.DrawTLatex(x, y, self.ProbeName(probe), self.__Size, 43, align)
193 
194  def Prepare1PadCanvas(self, cname, width=800, height=600, isQuad=False):
195  if isQuad: height = width
196  if self.__Canvas:
197  if self.__Canvas.GetName() != cname: self.__Canvas = None
198  else:
199  print "INFO Already found a canvas named: " + cname
200  return self.__Canvas
201  self.__Canvas = ROOT.TCanvas(cname, cname, width, height)
202  self.__Canvas.cd()
203 
204  def GetCanvas(self):
205  if not self.__Canvas: print "WARNING: No Canvas has been created yet. Please call CreateXPadCanvas() before"
206  return self.__Canvas
207 
208  def Prepare2PadCanvas(self, cname, width=800, height=600, isQuad=False, DoLogX=False):
209  self.Prepare1PadCanvas(cname, width, height, isQuad)
210 
211  self.__Pad1 = ROOT.TPad(cname+"Pad1", cname, 0.0, self.__VerticalCanvasSplit - 0.03, 1.0, 1.0)
212  self.__Pad2 = ROOT.TPad(cname+"Pad2", cname, 0.0, 0.0, 1.0, self.__VerticalCanvasSplit - 0.03)
213  if DoLogX:
214  self.__Pad1.SetLogx()
215  self.__Pad2.SetLogx()
216  self.__Pad1.SetBottomMargin(0.03) # set to 0 for space between top and bottom pad
217  self.__Pad1.SetTopMargin(0.09)
218  self.__Pad1.Draw()
219  self.__Pad2.SetTopMargin(0.01) # set to 0 for space between top and bottom pad
220  self.__Pad2.SetBottomMargin(0.35)
221  self.__Pad2.SetGridy()
222  self.__Pad2.Draw()
223 
224  def GetTopPad(self):
225  return self.__Pad1
226  def GetBottomPad(self):
227  return self.__Pad2
228  def AdaptLabelsTopPad(self, histos):
229  labelscalefact = 1. / (1. - self.__VerticalCanvasSplit)
230  for hist in histos:
231  hist.GetXaxis().SetTitleSize(labelscalefact * hist.GetXaxis().GetTitleSize())
232  hist.GetYaxis().SetTitleSize(labelscalefact * hist.GetYaxis().GetTitleSize())
233  hist.GetXaxis().SetLabelSize(labelscalefact * hist.GetXaxis().GetLabelSize())
234  hist.GetYaxis().SetLabelSize(labelscalefact * hist.GetYaxis().GetLabelSize())
235  hist.GetXaxis().SetTitleOffset(1. / labelscalefact * hist.GetXaxis().GetTitleOffset())
236  hist.GetYaxis().SetTitleOffset(1. / labelscalefact * hist.GetYaxis().GetTitleOffset())
237 
238  def AdaptLabelsBottomPad(self, histos, scale=1.):
239  if self.__VerticalCanvasSplit == 0:
240  labelscalefact = 1.
241  else:
242  labelscalefact = 1. / (scale * self.__VerticalCanvasSplit)
243  for hist in histos:
244  hist.GetXaxis().SetTitleSize(labelscalefact * hist.GetXaxis().GetTitleSize())
245  hist.GetYaxis().SetTitleSize(labelscalefact * hist.GetYaxis().GetTitleSize())
246  hist.GetXaxis().SetLabelSize(labelscalefact * hist.GetXaxis().GetLabelSize())
247  hist.GetYaxis().SetLabelSize(labelscalefact * hist.GetYaxis().GetLabelSize())
248  hist.GetXaxis().SetTitleOffset(2.2 / labelscalefact * hist.GetXaxis().GetTitleOffset())
249  hist.GetYaxis().SetTitleOffset(1.05 / labelscalefact * hist.GetYaxis().GetTitleOffset())
250 
251  def drawStyling(self, Template, ymin, ymax, TopPad=True, RemoveLabel=False):
252  self.__Styling = Template.Clone("Style" + Template.GetName())
253  self.__Styling.SetMinimum(ymin)
254  self.__Styling.SetMaximum(ymax)
255 
256  if RemoveLabel == True: self.__Styling.GetXaxis().SetLabelOffset(10.)
257  if TopPad: self.AdaptLabelsTopPad([self.__Styling])
258  self.__Styling.Draw("AXIS")
259 
260  def addValuesInText(self, histo, on_top=True, off_set_y=0.005):
261  plot_range_x = (histo.GetXaxis().GetBinUpEdge(histo.GetNbinsX()) - histo.GetXaxis().GetBinLowEdge(1)) / (
262  (1 - self.GetCanvas().GetRightMargin()) - self.GetCanvas().GetLeftMargin())
263  plot_range_y = (histo.GetMaximum() - histo.GetMinimum())
264 
265  left_margin = self.GetCanvas().GetLeftMargin()
266  bottom_margin = 0
267  if on_top and self.__Pad1:
268  plot_range_y /= (1 - self.__Pad1.GetTopMargin() - self.__Pad1.GetBottomMargin())
269  bottom_margin = self.__Pad1.GetBottomMargin()
270 
271  elif on_top and self.GetCanvas():
272  plot_range_y /= (1 - self.GetCanvas().GetTopMargin() - self.GetCanvas().GetBottomMargin())
273  bottom_margin = self.GetCanvas().GetBottomMargin()
274  elif not on_top and self.__Pad2:
275  plot_range_y /= (1 - self.__Pad2.GetTopMargin() - self.__Pad2.GetBottomMargin())
276  bottom_margin = self.__Pad2.GetBottomMargin()
277 
278  for i in range(1, histo.GetNbinsX() + 1):
279  tex = self.DrawTLatex(
280  left_margin + ((histo.GetBinCenter(i) - histo.GetXaxis().GetBinLowEdge(1)) / plot_range_x),
281  bottom_margin + (histo.GetBinContent(i) + off_set_y - histo.GetMinimum()) / plot_range_y,
282  "%.3f" % (histo.GetBinContent(i)),
283  size=10,
284  align=21,
285  color=histo.GetLineColor(),
286  )
287  def saveHisto(self, name, outputfiletypes):
288  Path = RemoveSpecialChars(name)
289  if Path.find("/") != -1:
290  dir_name = Path[ : Path.rfind("/") ]
291  os.system("mkdir -p %s"%(dir_name))
292  if "png" in outputfiletypes:
293  # need a 'pdf' file for using 'convert' to create a 'png'
294  if not "pdf" in outputfiletypes:
295  outputfiletypes.append("pdf")
296  a, b = outputfiletypes.index('pdf'), outputfiletypes.index('png')
297  outputfiletypes[b], outputfiletypes[a] = outputfiletypes[a], outputfiletypes[b]
298  if self.GetBottomPad(): self.GetBottomPad().RedrawAxis()
299  if self.GetTopPad(): self.GetTopPad().RedrawAxis()
300 
301  for otype in outputfiletypes:
302  if otype != "png":
303  self.__Canvas.SaveAs("%s.%s" % (Path, otype))
304  else:
305  # due to problems in png creation, convert pdfs to pngs manually
306  os.system("convert -density 300 %s.pdf %s.png" % (Path, Path))
PlotUtils.PlotUtils.DrawSource
def DrawSource(self, probe, x, y, align=11)
Definition: PlotUtils.py:191
PlotUtils.PlotUtils
Definition: PlotUtils.py:97
PlotUtils.PlotUtils.Prepare1PadCanvas
def Prepare1PadCanvas(self, cname, width=800, height=600, isQuad=False)
Definition: PlotUtils.py:194
PlotUtils.PlotUtils.__Legend
__Legend
Definition: PlotUtils.py:109
PlotUtils.PlotUtils.__Pad2
__Pad2
Definition: PlotUtils.py:106
PlotUtils.DiagnosticHisto
Definition: PlotUtils.py:18
PlotUtils.DiagnosticHisto.__log_binning
__log_binning
Definition: PlotUtils.py:30
PlotUtils.PlotUtils.Prepare2PadCanvas
def Prepare2PadCanvas(self, cname, width=800, height=600, isQuad=False, DoLogX=False)
Definition: PlotUtils.py:208
PlotUtils.PlotUtils.__init__
def __init__(self, size=18, status="Internal", lumi=1., sqrts="13", normalizedToUnity=False)
Definition: PlotUtils.py:98
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
PlotUtils.PlotUtils.__Styling
__Styling
Definition: PlotUtils.py:107
PlotUtils.DiagnosticHisto.__content
__content
Definition: PlotUtils.py:25
PlotUtils.PlotUtils.CreateLegend
def CreateLegend(self, x1, y1, x2, y2, textsize=22)
Definition: PlotUtils.py:151
PlotUtils.PlotUtils.__NLegEnt
__NLegEnt
Definition: PlotUtils.py:110
PlotUtils.PlotUtils.GetTopPad
def GetTopPad(self)
Definition: PlotUtils.py:224
RootHelpers::FindBin
Int_t FindBin(const TAxis *axis, const double x)
Definition: RootHelpers.cxx:14
PlotUtils.PlotUtils.drawStyling
def drawStyling(self, Template, ymin, ymax, TopPad=True, RemoveLabel=False)
Definition: PlotUtils.py:251
PlotUtils.DiagnosticHisto.__entries
__entries
Definition: PlotUtils.py:24
PlotUtils.PlotUtils.__RatStyling
__RatStyling
Definition: PlotUtils.py:108
PlotUtils.DiagnosticHisto.__init__
def __init__(self, name="", axis_title="", bins=-1, bmin=0., bmax=-1.e9, bin_width=-1, bdir=None, log_binning=False)
Definition: PlotUtils.py:19
PlotUtils.PlotUtils.AddToLegend
def AddToLegend(self, Items, Style="FL")
Definition: PlotUtils.py:166
PlotUtils.DiagnosticHisto.fixHisto
def fixHisto(self)
Definition: PlotUtils.py:86
PlotUtils.PlotUtils.__Status
__Status
Definition: PlotUtils.py:99
PlotUtils.PlotUtils.__SqrtS
__SqrtS
Definition: PlotUtils.py:102
PlotUtils.PlotUtils.AdaptLabelsTopPad
def AdaptLabelsTopPad(self, histos)
Definition: PlotUtils.py:228
PlotUtils.PlotUtils.GetCanvas
def GetCanvas(self)
Definition: PlotUtils.py:204
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
PlotUtils.DiagnosticHisto.setMinimum
def setMinimum(self, minimum)
Definition: PlotUtils.py:84
PlotUtils.PlotUtils.DrawLumiSqrtS
def DrawLumiSqrtS(self, x, y, align=11, lumi=1.)
Definition: PlotUtils.py:134
PlotUtils.DiagnosticHisto.__TH1
__TH1
Definition: PlotUtils.py:27
PlotUtils.PlotUtils.DrawSqrtS
def DrawSqrtS(self, x, y, align=11)
Definition: PlotUtils.py:147
PlotUtils.PlotUtils.__Pad1
__Pad1
Definition: PlotUtils.py:105
PlotUtils.PlotUtils.GetLumi
def GetLumi(self)
Definition: PlotUtils.py:127
PlotUtils.DiagnosticHisto.__width
__width
Definition: PlotUtils.py:23
PlotUtils.DiagnosticHisto.__xTitle
__xTitle
Definition: PlotUtils.py:21
PlotUtils.DiagnosticHisto.has_log_binnnig
def has_log_binnnig(self)
Definition: PlotUtils.py:50
PlotUtils.PlotUtils.DrawTLatex
def DrawTLatex(self, x, y, text, size=18, font=43, align=11, ndc=True, color=-1)
Definition: PlotUtils.py:114
python.Bindings.iterkeys
iterkeys
Definition: Control/AthenaPython/python/Bindings.py:810
PlotUtils.PlotUtils.addValuesInText
def addValuesInText(self, histo, on_top=True, off_set_y=0.005)
Definition: PlotUtils.py:260
PlotUtils.DiagnosticHisto.max
def max(self)
Definition: PlotUtils.py:78
PlotUtils.PlotUtils.AdaptLabelsBottomPad
def AdaptLabelsBottomPad(self, histos, scale=1.)
Definition: PlotUtils.py:238
PlotUtils.DiagnosticHisto.__max
__max
Definition: PlotUtils.py:85
PlotUtils.DiagnosticHisto.__TDir
__TDir
Definition: PlotUtils.py:28
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
PlotUtils.DiagnosticHisto.__error
__error
Definition: PlotUtils.py:26
PlotUtils.PlotUtils.GetLegend
def GetLegend(self, x1=0, y1=1., x2=1., y2=1.)
Definition: PlotUtils.py:162
PlotUtils.PlotUtils.DrawAtlas
def DrawAtlas(self, x, y, align=11)
Definition: PlotUtils.py:130
PlotUtils.DiagnosticHisto.__min
__min
Definition: PlotUtils.py:22
PlotUtils.DiagnosticHisto.TH1
def TH1(self)
Definition: PlotUtils.py:52
PlotUtils.DiagnosticHisto.write
def write(self)
Definition: PlotUtils.py:65
PlotUtils.RemoveSpecialChars
def RemoveSpecialChars(In)
Definition: PlotUtils.py:7
PlotUtils.DiagnosticHisto.__getInterval
def __getInterval(self, value)
Definition: PlotUtils.py:62
PlotUtils.DiagnosticHisto.__name
__name
Definition: PlotUtils.py:20
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
array
PlotUtils.PlotUtils.GetStatus
def GetStatus(self)
Definition: PlotUtils.py:124
PlotUtils.PlotUtils.__Size
__Size
Definition: PlotUtils.py:100
RCU::SetDirectory
bool SetDirectory(TObject *object, TDirectory *directory)
effects: set the directory this object is associated with returns: whether the object type actively k...
Definition: RootUtils.cxx:28
PlotUtils.PlotUtils.__Lumi
__Lumi
Definition: PlotUtils.py:101
PlotUtils.DiagnosticHisto.fill
def fill(self, value, weight=1.)
Definition: PlotUtils.py:53
PlotUtils.PlotUtils.__VerticalCanvasSplit
__VerticalCanvasSplit
Definition: PlotUtils.py:103
PlotUtils.PlotUtils.__Canvas
__Canvas
Definition: PlotUtils.py:104
PlotUtils.PlotUtils.__normalizedToUnity
__normalizedToUnity
Definition: PlotUtils.py:111
calibdata.cd
cd
Definition: calibdata.py:51
PlotUtils.DiagnosticHisto.name
def name(self)
Definition: PlotUtils.py:51
pickleTool.object
object
Definition: pickleTool.py:30
PlotUtils.PlotUtils.saveHisto
def saveHisto(self, name, outputfiletypes)
Definition: PlotUtils.py:287
PlotUtils.PlotUtils.__AddItemToLegend
def __AddItemToLegend(self, Item, Style)
Definition: PlotUtils.py:173
PlotUtils.DiagnosticHisto.setMaximum
def setMaximum(self, maximum)
Definition: PlotUtils.py:85
PlotUtils.PlotUtils.__Objects
__Objects
Definition: PlotUtils.py:112
PlotUtils.PlotUtils.DrawLegend
def DrawLegend(self, NperCol=3)
Definition: PlotUtils.py:181
readCCLHist.float
float
Definition: readCCLHist.py:83
PlotUtils.DiagnosticHisto.min
def min(self)
Definition: PlotUtils.py:81
PlotUtils.PlotUtils.GetBottomPad
def GetBottomPad(self)
Definition: PlotUtils.py:226