def Print(self, path, **kwargs): r"""Print the histogram to a file. Creates a PDF/PNG/... file with the absolute path defined by **path**. If a file with the same name already exists it will be overwritten (can be changed with the **overwrite** keyword argument). If **mkdir** is set to ``True`` (default: ``False``) directories in **path** with do not yet exist will be created automatically. The styling of the histogram, pad and canvas can be configured via their respective properties passed as keyword arguments. :param path: path of the output file (must end with '.pdf', '.png', ...) :type path: ``str`` :param \**kwargs: :class:`.Histo2D`, :class:`.Plot`, :class:`.Canvas` and :class:`.Pad` properties + additional properties (see below) Keyword Arguments: * **inject** (``list``, ``tuple``, ``ROOT.TObject``) -- inject a (list of) *drawable* :class:`ROOT` object(s) to the main pad, object properties can be specified by passing instead a ``tuple`` of the format :code:`(obj, props)` where :code:`props` is a ``dict`` holding the object properties (default: \[\]) * **overwrite** (``bool``) -- overwrite an existing file located at **path** (default: ``True``) * **mkdir** (``bool``) -- create non-existing directories in **path** (default: ``False``) """ injections = {"inject0": kwargs.pop("inject", [])} kwargs.setdefault("logy", False) # overwriting Pad template's default value! properties = DissectProperties(kwargs, [Histo2D, Plot, Canvas, Pad]) if any( map( lambda s: "Z" in s.upper(), [self.GetDrawOption(), properties["Pad"].get("drawoption", "")], ) ): properties["Pad"].setdefault("rightmargin", 0.18) plot = Plot(npads=1) plot.Register(self, **MergeDicts(properties["Histo2D"], properties["Pad"])) plot.Print( path, **MergeDicts(properties["Plot"], properties["Canvas"], injections) )
return self._drawbenchmarklines if __name__ == "__main__": from Plot import Plot from IOManager import IOManager filename = "../data/ds_data18.root" RatioPlot.PrintAvailableProperties() h1 = Histo1D("test1", "test1", 20, 0.0, 400.0) h2 = Histo1D("test2", "test2", 20, 0.0, 400.0) h3 = Histo1D("test3", "test3", 20, 0.0, 400.0) h1.Fill(filename, tree="DirectStau", varexp="MET", cuts="tau1Pt>650") h2.Fill(filename, tree="DirectStau", varexp="MET", cuts="tau1Pt>620") h3.Fill(filename, tree="DirectStau", varexp="MET", cuts="tau1Pt>700") h1.DeclareProperty("template", "background") h2.DeclareProperties(template="data", markercolor="#a7126b", linecolor="#a7126b") h3.DeclareProperties(template="signal", linecolor="#17a242") rp = RatioPlot([h2, h3], h1) p1 = Plot(npads=2) p1.Register(h1, 0) p1.Register(h2, 0, xunits="GeV") p1.Register(h3, 0) p1.Register(rp, 1, logy=False, ymin=0.5, ymax=2.0, ytitle="Data / Bkg.") p1.Print("ratioplot_test.pdf")
p1 = Plot() p2 = Plot(npads=2) p3 = Plot(npads=3) x_0 = 0.2 y_0 = 0.5 logy = False # print("PLOT 1 (npads = 1)") t1 = Text(x_0, y_0, "TEST 12345") t2 = Text(x_0, t1.GetY() - t1.GetYsize(), "TEST 123TT") t3 = Text(x_0, t2.GetY() - t2.GetYsize(), "TEST 12345") t4 = Text(x_0 + t1.GetXsize(), t1.GetY() - t2.GetYsize(), "TEST 12345") p1.Register(t1, logy=logy) p1.Register(t2) p1.Register(t3) p1.Register(t4) p1.Print("text_test-1.pdf", luminosity=139) # print("PLOT 2 (npads = 2)") t2 = Text(x_0, t1.GetY() - t1.GetYsize(), "TEST 123TT") t3 = Text(x_0, t2.GetY() - t2.GetYsize(), "TEST 12345") t4 = Text(x_0 + t1.GetXsize(), t1.GetY() - t2.GetYsize(), "TEST 12345") p2.Register(t1, pad=0, logy=logy) p2.Register(t2, pad=0) p2.Register(t3, pad=0) p2.Register(t4, pad=0) p2.Print("text_test-2.pdf", luminosity=139)
def Print(self, path, **kwargs): r"""Print the histogram to a file. Creates a PDF/PNG/... file with the absolute path defined by **path**. If a file with the same name already exists it will be overwritten (can be changed with the **overwrite** keyword argument). If **mkdir** is set to ``True`` (default: ``False``) directories in **path** with do not yet exist will be created automatically. The styling of the stack, pad and canvas can be configured via their respective properties passed as keyword arguments. Additional plots can be added to :class:`.Pad` s below the main one where the :class:`.Stack` object is drawn using the **ratio**, **contribution** and/or **sensitivity** flag (see below). :param path: path of the output file (must end with '.pdf', '.png', ...) :type path: ``str`` :param \**kwargs: :class:`.Stack`, :class:`.Plot`, :class:`.Canvas` and :class:`.Pad` properties + additional properties (see below) Keyword Arguments: * **sort** (``bool``) -- define whether the stack is sorted before it is drawn (see :func:`Stack.SetStackSorting`, default: ``True``) * **contribution** (``bool``) -- draw the relative per-bin contribution of each stacked histogram in an additional :class:`.Pad` (default: ``False``) * **ratio** (``bool``) -- draw a :class:`RatioPlot` of (assumed) data versus the (assumed) total background in an additional :class:`.Pad` (default: ``False``) * **sensitivity** (``bool``) -- draw a sensitivity scan for all (assumed) signal histograms and using the (asumed) total background as reference in an additional :class:`.Pad` (default: ``False``) * **inject<N>** (``list``, ``tuple``, ``ROOT.TObject``) -- inject a (list of) *drawable* :class:`ROOT` object(s) to pad **<N>** (default: 0), object properties can be specified by passing instead a ``tuple`` of the format :code:`(obj, props)` where :code:`props` is a ``dict`` holding the object properties (default: \[\]) * **overwrite** (``bool``) -- overwrite an existing file located at **path** (default: ``True``) * **mkdir** (``bool``) -- create non-existing directories in **path** (default: ``False``) """ from RatioPlot import RatioPlot from SensitivityScan import SensitivityScan from ContributionPlot import ContributionPlot sort = kwargs.pop("sort", True) contribution = kwargs.pop("contribution", False) ratio = kwargs.pop("ratio", False) sensitivity = kwargs.pop("sensitivity", False) if kwargs.get("drawstacksum"): self.SetDrawStackSum(kwargs.pop("drawstacksum")) injections = { k: kwargs.pop(k) for k in dict(kwargs).keys() if k.startswith("inject") } npads = sum([contribution, bool(ratio), bool(sensitivity)]) + 1 addcls = [RatioPlot] if ratio else [] addcls += [ContributionPlot] if contribution else [] addcls += [SensitivityScan] if sensitivity else [] properties = DissectProperties(kwargs, [Stack, Plot, Canvas, Pad] + addcls) self.BuildStack(sort=sort) if self.GetNhists() == 0: injections = {"inject0": injections.get("inject0", [])} if contribution: logger.warning("Cannot create ContributionPlot: Missing stack!") contribution = False if ratio: logger.warning("Cannot create RatioPlot: Missing stack!") ratio = False if sensitivity: logger.warning("Cannot create SensitivityScan: Missing stack!") sensitivity = False if ratio is True: try: # it's just a guess... datahisto = filter( lambda h: not h.GetDrawOption().upper().startswith("HIST"), self._store["nostack"], )[0] ratio = [datahisto, self._stacksumhisto] # overwrite boolean except IndexError: if self._store["nostack"]: ratio = [self._store["nostack"][0], self._stacksumhisto] else: logger.error( "Failed to identify appropriate numerator histogram for " "RatioPlot pad!" ) ratio = False if sensitivity: try: # again just making assumptions here... sensitivity = filter( lambda h: "HIST" in h.GetDrawOption().upper(), self._store["nostack"], # overwrite boolean with list of sig histos ) except IndexError: logger.error( "Failed to identify appropriate numerator histogram for " "SensitivityScan pad!" ) sensitivity = False plot = Plot(npads=npads, **properties["Plot"]) # Register the Stack to the upper Pad (pad=0): plot.Register(self, **MergeDicts(properties["Stack"], properties["Pad"])) if self._drawstacksum and self.GetNhists() > 1: # Dummy histo with the correct legend entry styling: htmp = Histo1D( "{}_legendentry".format(self._stacksumhisto.GetName()), self._stacksumhisto.GetTitle(), [ self._stacksumhisto._lowbinedges[0], self._stacksumhisto._lowbinedges[self._stacksumhisto._nbins], ], **{ k[8:]: v for k, v in DissectProperties( properties["Stack"], [ { "Stacksum": [ "stacksum{}".format(p) for p in Histo1D.GetListOfProperties() ] } ], )["Stacksum"].items() } ) plot.Register( htmp, fillcolor=self._stacksumhisto._errorband.GetFillColor(), fillstyle=self._stacksumhisto._errorband.GetFillStyle(), legenddrawoption=self._stacksumhisto.GetLegendDrawOption(), **properties["Pad"] ) idx = 1 xaxisprops = { k: v for k, v in properties["Pad"].items() if k in ["xtitle", "xunits"] } if contribution: contribplot = ContributionPlot(self) properties["ContributionPlot"].update( xaxisprops, **properties["ContributionPlot"] ) plot.Register( contribplot, pad=idx, ytitle="Contrib.", logy=False, ymin=0, ymax=1, **{k: v for k, v in properties["Pad"].items() if k.startswith("x")} ) idx += 1 if ratio: ratioplot = RatioPlot(*ratio, **properties["RatioPlot"]) properties["RatioPlot"].update(xaxisprops) plot.Register( ratioplot, pad=idx, ytitle="Data / SM", logy=False, ymin=0.2, ymax=1.8, **{k: v for k, v in properties["Pad"].items() if k.startswith("x")} ) idx += 1 if sensitivity: sensitivityscan = SensitivityScan( sensitivity, self._stacksumhisto, **properties["SensitivityScan"] ) properties["SensitivityScan"].update(xaxisprops) plot.Register( sensitivityscan, pad=idx, ytitle="Z_{A}-value", logy=False, **{k: v for k, v in properties["Pad"].items() if k.startswith("x")} ) plot.Print(path, **MergeDicts(properties["Canvas"], injections))
"bboxy2", ] def __init__(self, *args, **kwargs): MethodProxy.__init__(self) ROOT.TLine.__init__(self, *args) self._ndc = False if len(args) >= 4: kwargs["x1"], kwargs["y1"], kwargs["x2"], kwargs["y2"] = args[0:4] kwargs.setdefault("template", "common") self.DeclareProperties(**kwargs) def SetNDC(self, boolean): self._ndc = boolean super(Line, self).SetNDC(boolean) def GetUseNDC(self): return self._ndc if __name__ == "__main__": from Plot import Plot p = Plot() a = Line(0.25, 0.25, 0.75, 0.75) p.Register(a, logy=False) p.Print("test_line.pdf")
for line in self._benchmarklines: line.Draw() if __name__ == "__main__": from Plot import Plot filename = "../data/ds_data18.root" h_bkg = Histo1D("h_bkg", "Background", 20, 0.0, 400.0) h_sig1 = Histo1D("h_sig1", "Signal 1", 20, 0.0, 400.0) h_sig2 = Histo1D("h_sig2", "Signal 2", 20, 0.0, 400.0) h_bkg.Fill(filename, tree="DirectStau", varexp="MET", weight="100.0/MET") h_sig1.Fill(filename, tree="DirectStau", varexp="MET", cuts="tau1Pt>600") h_sig2.Fill(filename, tree="DirectStau", varexp="MET", cuts="tau1Pt>800") h_sig1_props = dict(template="signal", linecolor=ROOT.kRed) h_sig2_props = dict(template="signal", linecolor=ROOT.kBlue) scan = SensitivityScan([(h_sig1, h_sig1_props), (h_sig2, h_sig2_props)], h_bkg) p = Plot(npads=2) p.Register(h_bkg, template="background", fillcolor=ROOT.kGray) p.Register(h_sig1, **h_sig1_props) p.Register(h_sig2, **h_sig2_props) p.Register(scan, 1, logy=False, ytitle="Z_{N}-value") p.Print("test_sensitivityscan.pdf")