5 Miscellaneous utilities for PyROOT.
7 __author__ =
'Juerg Beringer'
8 __version__ =
'$Id: ROOTUtils.py 759047 2016-07-01 00:45:13Z beringer $'
12 from array
import array
15 protectedObjectList = []
18 """Utility function to prevent ROOT objects from being garbage-collected,
19 (thus disappearing from plots) when they go out of scope."""
20 protectedObjectList.append(obj)
25 myCanvasSizes = {
'default': (700, 500),
26 'default2d': (545, 500),
29 'slide2text': (400,500),
33 'landscape': (1600,1000),
35 'extrawide': (1500,500),
41 """Class MyCanvas is a ROOT TCanvas that allows choosing one of
42 several typically used canvas sizes. It can automatically save
43 the canvas in different formats upon destruction provided the
44 user makes sure that all histograms still exist."""
47 saveAsList = [
'.gif' ]
48 autoSaveOnExit =
False
49 autoName =
'%s.autosave%s'
51 def __init__(self,name='MyCanvas', size='default', xdivs=1, ydivs=1, saveAsList=None, autoSaveOnExit=None):
52 super(MyCanvas,self).
__init__(name,name,myCanvasSizes[size][0],myCanvasSizes[size][1])
58 if autoSaveOnExit!=
None:
63 self.Divide(xdivs,ydivs)
78 """PlotLibrary is a base class that can be used to manage a set of
79 plots. Each individual plot should be created as a method of a
80 derived class. Other methods of the derived class that do not
81 generate plots should either have names starting with
82 underscore, or should be declared when calling __init__ of the
85 def __init__(self, name = 'MyPlots', otherMethods=[]):
86 """Constructor. otherMethods specifies a list of methods of the derived
87 class that are not creating plots and should not be called by plot()."""
102 """Protect ROOT object from garbage collection."""
106 def plot(self, plotName='',*args):
107 """Make one or all (if plotName=='') plots."""
109 self.__class__.__dict__[plotName](self,*args)
111 for i
in self.__class__.__dict__:
112 if i[0]==
'_':
continue
114 self.__class__.__dict__[i](self,*args)
116 def genPlot(self,what='ALL',code='plot',labels=[],*args):
117 """Make plots using a general code. genPlot makes either a single plot defined
118 by argument what, or all plots (if what=''). The plots made in the latter
119 case are specified by whatList. A canvas that is subdivided if necessary
120 is created before the plotting code is called."""
121 if what==
'' or what.upper()==
'ALL':
129 self.__class__.__dict__[code](self,w,*args)
131 self.__class__.__bases__[0].__dict__[code](self,w,*args)
136 ROOT.gPad.SaveAs(
'%s-%s-%s%s' % (self.
name,code,w,o))
150 print "ERROR: can't add labels unless we have an empty pad to use. Ignoring labels."
154 c.SaveAs(
'%s-%s-%s%s' % (self.
name,code,what,o))
161 self.__class__.__dict__[code](self,what,*args)
163 self.__class__.__bases__[0].__dict__[code](self,what,*args)
167 c.SaveAs(
'%s-%s-%s%s' % (self.
name,code,what,o))
172 """StyleFactory is a helper class for assigning marker styles, line styles,
173 and colors in ROOT plots."""
175 markerSequence = [ 8, 21, 22, 23, 29, 4, 25, 26, 27, 28, 30, 2, 3, 6]
176 lineSequence = [ 1, 2, 3, 4]
177 colorSequence = [ 1, 2, 4, 6, 8]
179 def __init__(self,incMarker=True,incLine=True,incColor=True):
188 """Get next style cycling through markers, lines and colors as specified by
189 the flags in the constructor. Returns a triplet of (marker,line,color) styles."""
193 return (StyleFactory.markerSequence[self.
idMarker % len(StyleFactory.markerSequence)],
194 StyleFactory.lineSequence[self.
idLine % len(StyleFactory.lineSequence)],
195 StyleFactory.colorSequence[self.
idColor % len(StyleFactory.colorSequence)])
198 """Get next marker style."""
200 return StyleFactory.markerSequence[self.
idMarker % len(StyleFactory.markerSequence)]
203 """Get next line style."""
205 return StyleFactory.lineSequence[self.
idLine % len(StyleFactory.lineSequence)]
208 """Get next color."""
210 return StyleFactory.colorSequence[self.
idColor % len(StyleFactory.colorSequence)]
213 def drawAxisFrame(xmin,xmax,ymin,ymax,title='',xTitleOffset=None,yTitleOffset=None,doPlot=True,protectFrame=True):
214 frame = ROOT.TH2F(
'axisFrame',title,100,xmin,xmax,100,ymin,ymax)
215 frame.SetStats(
False)
216 if xTitleOffset!=
None:
217 frame.GetXaxis().SetTitleOffset(xTitleOffset)
218 if yTitleOffset!=
None:
219 frame.GetYaxis().SetTitleOffset(yTitleOffset)
228 """Draw a horizontal band of width +-ywidth. Nice colors are 19 and 33."""
229 b = ROOT.TH1F(
'band',
'band',1,xmin,xmax)
231 b.SetBinError(1,ywidth)
232 b.SetFillColor(color)
233 b.SetMarkerColor(color)
234 b.SetMarkerSize(0.01)
243 def drawText(x=0.74,y=0.87,dy=0.06,text='',font=62,color=1,align=11,linesep=';'):
244 """Draw a variable number of lines of text."""
248 t.SetTextColor(color)
249 t.SetTextAlign(align)
250 t.SetTextSize(dy/1.2)
251 for line
in text.split(linesep):
252 t.DrawLatex(x,y,line)
259 def drawLegend(x1,y1,x2,y2,legendList=[],fillColor=0,lineColor=0,textSize=None,protectLegend=True):
260 """Draw a legend with one or more entries. legendList is a list of lists,
261 where each inner list defines the object, text and option of a legend entry.
262 NOTE: Must store returned TLegend, otherwise legend will disappear!"""
263 nlines = len(legendList)
265 print "ERROR: drawLegend called w/o any legend entries"
270 l = ROOT.TLegend(x1,y1,x2,y2)
271 l.SetFillColor(fillColor)
272 l.SetLineColor(lineColor)
273 l.SetShadowColor(lineColor)
275 l.SetTextSize(textSize)
277 l.AddEntry(e[0],e[1],e[2])
288 st = h.GetListOfFunctions().FindObject(
'stats')
290 print 'ERROR: No stats found - cannot move it'
292 st.SetTextColor(h.GetLineColor())
293 st.SetX1NDC(st.GetX1NDC()+dx)
294 st.SetY1NDC(st.GetY1NDC()+dy)
295 st.SetX2NDC(st.GetX2NDC()+xw
if xw!=0
else st.GetX2NDC()+dx)
296 st.SetY2NDC(st.GetY2NDC()+yw
if yw!=0
else st.GetY2NDC()+dy)
303 def atlasLabel(x,y,isPreliminary=False,color=1,offset=0.115,isForApproval=False,energy=8,customstring="",size=0.05):
304 if x==
None or y==
None:
305 print "Must set (x,y) position using --atlasx and --atlasy to add labels. No ATLAS labels created."
307 offset = offset/0.05*size
312 l.SetTextColor(color)
313 l.DrawLatex(x,y,
"ATLAS")
319 p.SetTextColor(color)
321 if customstring !=
"":
322 p.DrawLatex(x+offset,y,customstring)
325 p.DrawLatex(x+offset,y,
"Preliminary")
328 p.DrawLatex(x+offset,y,
"Internal")
332 p.DrawLatex(x, y-(0.07/0.05*size),
"#sqrt{s} = %s TeV" % energy)
334 p.DrawLatex(x, y-(0.07/0.05*size),
"#sqrt{s} = %s GeV" % energy)
339 s = ROOT.TStyle(
'ATLAS',
'ATLAS Style V2.02')
343 s.SetFrameBorderMode(icol);
344 s.SetFrameFillColor(icol);
345 s.SetCanvasBorderMode(icol);
346 s.SetCanvasColor(icol);
347 s.SetPadBorderMode(icol);
349 s.SetStatColor(icol);
353 s.SetPaperSize(20,26);
354 s.SetPadTopMargin(0.05);
355 s.SetPadRightMargin(0.05);
356 s.SetPadBottomMargin(0.16);
357 s.SetPadLeftMargin(0.16);
360 s.SetTitleXOffset(1.4)
361 s.SetTitleYOffset(1.4)
369 s.SetTextSize(tsize);
370 s.SetLabelFont(font,
"x");
371 s.SetTitleFont(font,
"x");
372 s.SetLabelFont(font,
"y");
373 s.SetTitleFont(font,
"y");
374 s.SetLabelFont(font,
"z");
375 s.SetTitleFont(font,
"z");
377 s.SetLabelSize(tsize,
"x");
378 s.SetTitleSize(tsize,
"x");
379 s.SetLabelSize(tsize,
"y");
380 s.SetTitleSize(tsize,
"y");
381 s.SetLabelSize(tsize,
"z");
382 s.SetTitleSize(tsize,
"z");
385 s.SetMarkerStyle(20);
386 s.SetMarkerSize(1.2);
387 s.SetHistLineWidth(2);
388 s.SetLineStyleString(2,
"[12 12]");
394 s.SetEndErrorSize(0.);
416 print '\nApplying style %s (%s) ...\n' % (style.GetName(),style.GetTitle())
417 ROOT.gROOT.SetStyle(style.GetName())
418 ROOT.gROOT.ForceStyle()