5 ROOT.gROOT.SetBatch(
True)
6 ROOT.PyConfig.IgnoreCommandLineOptions =
True
13 """Class to allow algorithm-specific values for e.g. plot bound values"""
18 default -- default value
20 Keyword arguments are treated as a dictionary where the key is a name of an algorithm, and the value is a value for that algorithm
24 self._values.update(kwargs)
27 """Get a value for an algorithm."""
33 obj = tdirectory.Get(name)
35 print "Did not find {obj} from {dir}".
format(obj=name, dir=tdirectory.GetPath())
44 return max([th1.GetBinContent(i)+th1.GetBinError(i)
for i
in xrange(1, th1.GetNbinsX()+1)])
46 def _findBounds(th1s, xmin=None, xmax=None, ymin=None, ymax=None):
47 """Find x-y axis boundaries encompassing a list of TH1s if the bounds are not given in arguments.
53 xmin -- Minimum x value; if None, take the minimum of TH1s
54 xmax -- Maximum x value; if None, take the maximum of TH1s
55 xmin -- Minimum y value; if None, take the minimum of TH1s
56 xmax -- Maximum y value; if None, take the maximum of TH1s
58 if xmin
is None or xmax
is None or ymin
is None or ymax
is None or isinstance(ymax, list):
64 xaxis = th1.GetXaxis()
65 xmins.append(xaxis.GetBinLowEdge(xaxis.GetFirst()))
66 xmaxs.append(xaxis.GetBinUpEdge(xaxis.GetLast()))
67 ymins.append(th1.GetMinimum())
68 ymaxs.append(th1.GetMaximum())
78 ymax = 1.05*
max(ymaxs)
79 elif isinstance(ymax, list):
81 ymaxs_above =
filter(
lambda y: y>ym, ymax)
82 if len(ymaxs_above) == 0:
83 raise Exception(
"Histogram maximum y %f is above all given ymax values %s" % (ym, str(ymax)))
84 ymax =
min(ymaxs_above)
87 th1.GetXaxis().SetRangeUser(xmin, xmax)
88 th1.GetYaxis().SetRangeUser(ymin, ymax)
90 return (xmin, ymin, xmax, ymax)
94 """Class to calculate the fake+duplicate rate"""
95 def __init__(self, name, assoc, dup, reco, title=""):
99 name -- String for the name of the resulting efficiency histogram
100 assoc -- String for the name of the "associated" histogram
101 dup -- String for the name of the "duplicates" histogram
102 reco -- String for the name of the "reco" (denominator) histogram
105 title -- String for a title of the resulting histogram (default "")
107 The result is calculated as 1 - (assoc - dup) / reco
116 """String representation, returns the name"""
120 """Create and return the efficiency histogram from a TDirectory"""
127 if not hassoc
or not hdup
or not hreco:
130 hfakedup = hreco.Clone(self.
_name)
131 hfakedup.SetTitle(self.
_title)
133 for i
in xrange(1, hassoc.GetNbinsX()+1):
134 numerVal = hassoc.GetBinContent(i) - hdup.GetBinContent(i)
135 denomVal = hreco.GetBinContent(i)
137 fakedupVal = (1 - numerVal / denomVal)
if denomVal != 0.0
else 0.0
138 errVal = math.sqrt(fakedupVal*(1-fakedupVal)/denomVal)
if (denomVal != 0.0
and fakedupVal <= 1)
else 0.0
140 hfakedup.SetBinContent(i, fakedupVal)
141 hfakedup.SetBinError(i, errVal)
146 def __init__(self, name, histoName, mapping, normalizeTo=None, scale=None):
164 for i, label
in enumerate(self.
_mapping):
165 bin = th1.GetXaxis().FindBin(label)
167 result.SetBinContent(i+1, th1.GetBinContent(bin))
168 result.GetXaxis().SetBinLabel(i+1, label)
170 for i, (key, labels)
in enumerate(self._mapping.iteritems()):
173 bin = th1.GetXaxis().FindBin(l)
175 sumTime += th1.GetBinContent(bin)
176 result.SetBinContent(i+1, sumTime)
177 result.GetXaxis().SetBinLabel(i+1, key)
182 print "Trying to normalize {name} to {binlabel}, which does not exist".
format(name=self.
_name, binlabel=self.
_normalizeTo)
184 value = th1.GetBinContent(bin)
186 result.Scale(1/value)
188 if self.
_scale is not None:
194 def __init__(self, name, mapping, normalizeTo=None):
204 for key, histoName
in self._mapping.iteritems():
208 result.append( (key, th1.Integral(0, th1.GetNbinsX()+1)) )
212 res = ROOT.TH1F(self.
_name, self.
_name, len(result), 0, len(result))
214 for i, (name, count)
in enumerate(result):
215 res.SetBinContent(i+1, count)
216 res.GetXaxis().SetBinLabel(i+1, name)
222 scale = th1.Integral(0, th1.GetNbinsX()+1)
228 _plotStylesColor = [4, 2, ROOT.kBlack, ROOT.kOrange+7, ROOT.kMagenta-3]
229 _plotStylesMarker = [21, 20, 22, 34, 33]
232 """Represents one plot, comparing one or more histograms."""
237 name -- String for name of the plot, or Efficiency object
240 title -- String for a title of the plot (default None)
241 xtitle -- String for x axis title (default None)
242 ytitle -- String for y axis title (default None)
243 ytitlesize -- Float for y axis title size (default None)
244 ytitleoffset -- Float for y axis title offset (default None)
245 xmin -- Float for x axis minimum (default None, i.e. automatic)
246 xmax -- Float for x axis maximum (default None, i.e. automatic)
247 ymin -- Float for y axis minimum (default 0)
248 ymax -- Float for y axis maximum (default None, i.e. automatic)
249 xlog -- Bool for x axis log status (default False)
250 ylog -- Bool for y axis log status (default False)
251 xgrid -- Bool for x axis grid status (default True)
252 ygrid -- Bool for y axis grid status (default True)
253 stat -- Draw stat box? (default False)
254 fit -- Do gaussian fit? (default False)
255 statx -- Stat box x coordinate (default 0.65)
256 staty -- Stat box y coordinate (default 0.8)
257 statyadjust -- List of floats for stat box y coordinate adjustments (default None)
258 normalizeToUnitArea -- Normalize histograms to unit area? (default False)
259 profileX -- Take histograms via ProfileX()? (default False)
260 fitSlicesY -- Take histograms via FitSlicesY() (default False)
261 scale -- Scale histograms by a number (default None)
262 xbinlabels -- List of x axis bin labels (if given, default None)
263 xbinlabelsize -- Size of x axis bin labels (default None)
264 xbinlabeloption -- Option string for x axis bin labels (default None)
265 drawStyle -- If "hist", draw as line instead of points (default None)
266 drawCommand -- Deliver this to Draw() (default: None for same as drawStyle)
267 lineWidth -- If drawStyle=="hist", the width of line (default 2)
268 legendDx -- Float for moving TLegend in x direction for separate=True (default None)
269 legendDy -- Float for moving TLegend in y direction for separate=True (default None)
270 legendDw -- Float for changing TLegend width for separate=True (default None)
271 legendDh -- Float for changing TLegend height for separate=True (default None)
272 histogramModifier -- Function to be called in create() to modify the histograms (default None)
276 def _set(attr, default):
277 setattr(self,
"_"+attr, kwargs.get(attr, default))
282 _set(
"ytitlesize",
None)
283 _set(
"ytitleoffset",
None)
300 _set(
"statyadjust",
None)
302 _set(
"normalizeToUnitArea",
False)
303 _set(
"profileX",
False)
304 _set(
"fitSlicesY",
False)
306 _set(
"xbinlabels",
None)
307 _set(
"xbinlabelsize",
None)
308 _set(
"xbinlabeloption",
None)
310 _set(
"drawStyle",
None)
311 _set(
"drawCommand",
None)
314 _set(
"legendDx",
None)
315 _set(
"legendDy",
None)
316 _set(
"legendDw",
None)
317 _set(
"legendDh",
None)
319 _set(
"histogramModifier",
None)
324 """Return number of existing histograms."""
328 return str(self.
_name)
331 """Create one histogram from a TDirectory."""
336 if hasattr(self.
_name,
"create"):
337 th1 = self._name.create(tdir)
339 th1 = tdir.Get(self.
_name)
343 print "Did not find {histo} from {dir}".
format(histo=self.
_name, dir=tdir.GetPath())
352 """Create histograms from list of TDirectories"""
355 if self._histogramModifier
is not None:
359 raise Exception(
"More histograms (%d) than there are plot styles (%d) defined. Please define more plot styles in this file" % (len(self.
_histograms), len(_plotStylesColor)))
364 def _modifyHisto(th1):
372 ROOT.TH1.AddDirectory(
True)
374 th1 = ROOT.gDirectory.Get(th1.GetName()+
"_2")
375 th1.SetDirectory(
None)
377 ROOT.TH1.AddDirectory(
False)
379 if self._title
is not None:
380 th1.SetTitle(self._title)
382 if self._scale
is not None:
383 th1.Scale(self._scale)
394 if h
is not None and hasattr(h,
"SetStats"):
398 def _doStats(h, col, dy):
405 f = h.GetListOfFunctions().FindObject(
"gaus")
413 st = h.GetListOfFunctions().FindObject(
"stats")
417 st.SetX1NDC(startingX)
418 st.SetX2NDC(startingX+0.3)
419 st.SetY1NDC(startingY+dy)
420 st.SetY2NDC(startingY+dy+0.15)
425 if self._statyadjust
is not None and i < len(self._statyadjust):
426 dy += self._statyadjust[i]
428 _doStats(h, _plotStylesColor[i], dy)
432 """Normalise histograms to unit area"""
443 """Draw the histograms using values for a given algorithm."""
444 if self._normalizeToUnitArea:
447 def _styleMarker(h, msty, col):
448 h.SetMarkerStyle(msty)
449 h.SetMarkerColor(col)
454 def _styleHist(h, msty, col):
455 _styleMarker(h, msty, col)
457 h.SetLineWidth(self._lineWidth)
461 if self._drawStyle
is not None:
462 if "hist" in self._drawStyle.lower():
465 if "l" in self._drawStyle.lower():
473 style(h, _plotStylesMarker[i], _plotStylesColor[i])
476 print "No histograms for plot {name}".
format(name=self.
_name)
480 ROOT.gPad.SetLogx(self._xlog)
481 ROOT.gPad.SetLogy(self._ylog)
482 ROOT.gPad.SetGridx(self._xgrid)
483 ROOT.gPad.SetGridy(self._ygrid)
487 if hasattr(val,
"value"):
488 return val.value(algo)
492 xmin=_getVal(self._xmin), xmax=_getVal(self._xmax),
493 ymin=_getVal(self._ymin), ymax=_getVal(self._ymax))
499 xbinlabels = self._xbinlabels
500 if xbinlabels
is None:
501 if len(histos[0].GetXaxis().GetBinLabel(1)) > 0:
503 for i
in xrange(1, histos[0].GetNbinsX()+1):
504 xbinlabels.append(histos[0].GetXaxis().GetBinLabel(i))
507 if xbinlabels
is None:
508 frame = ROOT.gPad.DrawFrame(*bounds)
511 nbins = len(xbinlabels)
512 frame = ROOT.TH1F(
"hframe",
"hframe", nbins, bounds[0], bounds[2])
513 frame.SetBit(ROOT.TH1.kNoStats)
514 frame.SetBit(ROOT.kCanDelete)
515 frame.SetMinimum(bounds[1])
516 frame.SetMaximum(bounds[3])
517 frame.GetYaxis().SetLimits(bounds[1], bounds[3])
520 xaxis = frame.GetXaxis()
521 for i
in xrange(nbins):
522 xaxis.SetBinLabel(i+1, xbinlabels[i])
523 if self._xbinlabelsize
is not None:
524 xaxis.SetLabelSize(self._xbinlabelsize)
525 if self._xbinlabeloption
is not None:
526 frame.LabelsOption(self._xbinlabeloption)
529 frame.SetTitle(histos[0].GetTitle())
530 if self._xtitle
is not None:
531 frame.GetXaxis().SetTitle(self._xtitle)
532 if self._ytitle
is not None:
533 frame.GetYaxis().SetTitle(self._ytitle)
534 if self._ytitlesize
is not None:
535 frame.GetYaxis().SetTitleSize(self._ytitlesize)
536 if self._ytitleoffset
is not None:
537 frame.GetYaxis().SetTitleOffset(self._ytitleoffset)
542 if self._drawStyle
is not None:
544 if self._drawCommand
is not None:
545 ds = self._drawCommand
551 ROOT.gPad.RedrawAxis()
555 """Add histograms to a legend.
559 legendLabels -- List of strings for the legend labels
561 for h, label
in zip(self.
_histograms, legendLabels):
564 legend.AddEntry(h, label,
"LP")
567 """Group of plots, results a TCanvas"""
572 name -- String for name of the TCanvas, used also as the basename of the picture files
573 plots -- List of Plot objects
576 legendDx -- Float for moving TLegend in x direction (default None)
577 legendDy -- Float for moving TLegend in y direction (default None)
578 legendDw -- Float for changing TLegend width (default None)
579 legendDh -- Float for changing TLegend height (default None)
580 overrideLegendLabels -- List of strings for legend labels, if given, these are used instead of the ones coming from Plotter (default None)
587 elif len(self.
_plots) <= 4:
589 elif len(self.
_plots) <= 6:
591 elif len(self.
_plots) <= 8:
593 elif len(self.
_plots) <= 10:
600 self._canvasSingle.SetTopMargin(0.05)
601 self._canvasSingle.SetBottomMargin(0.13)
602 self._canvasSingle.SetLeftMargin(0.16)
603 self._canvasSingle.SetRightMargin(0.05)
606 def _set(attr, default):
607 setattr(self,
"_"+attr, kwargs.get(attr, default))
609 _set(
"legendDx",
None)
610 _set(
"legendDy",
None)
611 _set(
"legendDw",
None)
612 _set(
"legendDh",
None)
614 _set(
"overrideLegendLabels",
None)
617 """Create histograms from a list of TDirectories."""
619 plot.create(tdirectories)
621 def draw(self, algo, legendLabels, prefix=None, separate=False, saveFormat=".pdf"):
622 """Draw the histograms using values for a given algorithm.
625 algo -- string for algorithm
626 legendLabels -- List of strings for legend labels (corresponding to the tdirectories in create())
627 prefix -- Optional string for file name prefix (default None)
628 separate -- Save the plots of a group to separate files instead of a file per group (default False)
629 saveFormat -- String specifying the plot format (default '.pdf')
632 if self._overrideLegendLabels
is not None:
633 legendLabels = self._overrideLegendLabels
636 return self.
_drawSeparate(algo, legendLabels, prefix, saveFormat)
638 self._canvas.Divide(2, int((len(self.
_plots)+1)/2))
641 for i, plot
in enumerate(self.
_plots):
657 if self._legendDx
is not None:
658 lx1 += self._legendDx
659 lx2 += self._legendDx
660 if self._legendDy
is not None:
661 ly1 += self._legendDy
662 ly2 += self._legendDy
663 if self._legendDw
is not None:
664 lx2 += self._legendDw
665 if self._legendDh
is not None:
666 ly1 -= self._legendDh
667 plot =
max(self.
_plots, key=
lambda p: p.getNumberOfHistograms())
668 legend = self.
_createLegend(plot, legendLabels, lx1, ly1, lx2, ly2)
670 return self.
_save(self.
_canvas, saveFormat, prefix=prefix)
682 self._canvasSingle.cd()
691 if plot._legendDx
is not None:
692 lx1 += plot._legendDx
693 lx2 += plot._legendDx
694 if plot._legendDy
is not None:
695 ly1 += plot._legendDy
696 ly2 += plot._legendDy
697 if plot._legendDw
is not None:
698 lx2 += plot._legendDw
699 if plot._legendDh
is not None:
700 ly1 -= plot._legendDh
702 legend = self.
_createLegend(plot, legendLabels, lx1, ly1, lx2, ly2, textSize=0.03)
704 ret.extend(self.
_save(self.
_canvasSingle, saveFormat, prefix=prefix, postfix=
"_"+plot.getName()))
707 def _createLegend(self, plot, legendLabels, lx1, ly1, lx2, ly2, textSize=0.016):
708 l = ROOT.TLegend(lx1, ly1, lx2, ly2)
709 l.SetTextSize(textSize)
716 plot.addToLegend(l, legendLabels)
720 def _save(self, canvas, saveFormat, prefix=None, postfix=None):
723 if prefix
is not None:
725 if postfix
is not None:
727 canvas.SaveAs(name+saveFormat)
730 return [name+saveFormat]
734 """Represent a collection of PlotGroups."""
735 def __init__(self, possibleDirs, plotGroups, saveFormat=".pdf"):
739 possibleDirs -- List of strings for possible directories of histograms in TFiles
740 plotGroups -- List of PlotGroup objects
741 saveFormat -- String specifying the plot format (default '.pdf')
747 ROOT.gROOT.SetStyle(
"Plain")
748 ROOT.gStyle.SetPadRightMargin(0.07)
749 ROOT.gStyle.SetPadLeftMargin(0.13)
750 ROOT.gStyle.SetTitleFont(42,
"XYZ")
751 ROOT.gStyle.SetTitleSize(0.05,
"XYZ")
752 ROOT.gStyle.SetTitleOffset(1.2,
"Y")
754 ROOT.gStyle.SetLabelFont(42,
"XYZ")
755 ROOT.gStyle.SetLabelSize(0.05,
"XYZ")
756 ROOT.gStyle.SetTextSize(0.05)
758 ROOT.TH1.AddDirectory(
False)
764 """Return the list of possible directory names."""
768 self._plotGroups.append(plotGroup)
770 def set(self, plotGroups):
774 """Get TDirectory from TFile."""
780 if subdir
is not None:
786 msg =
"Did not find subdirectory '%s' from directory '%s' in file %s" % (subdir, pd, tfile.GetName())
794 msg =
"Did not find any of directories '%s' from file %s" % (
",".
join(self.
_possibleDirs), tfile.GetName())
801 def create(self, files, labels, subdir=None):
802 """Create histograms from a list of TFiles.
805 files -- List of TFiles
806 labels -- List of strings for legend labels corresponding the files
807 subdir -- Optional string for subdirectory inside the possibleDirs; if list of strings, then each corresponds to a TFile
811 if isinstance(subdir, list):
812 for f, l, s
in zip(files, labels, subdir):
815 self._labels.append(l)
817 for f, l
in zip(files, labels):
820 self._labels.append(l)
825 def draw(self, algo, prefix=None, separate=False, saveFormat=None):
826 """Draw and save all plots using settings of a given algorithm.
829 algo -- String for the algorithm
830 prefix -- Optional string for file name prefix (default None)
831 separate -- Save the plots of a group to separate files instead of a file per group (default False)
832 saveFormat -- If given, overrides the saveFormat
837 if saveFormat
is not None:
841 ret.extend(pg.draw(algo, self.
_labels, prefix=prefix, separate=separate, saveFormat=sf))
def getPossibleDirectoryNames
def setPossibleDirectoryNames
static std::string join(char **cmd)
def getNumberOfHistograms