def get_total_stat_sys_hists(hists, sys_dict): """ first make total hist for each systematic. then sum deviations in quadrature bin-by-bin to make band. """ ## make total sys hists h_total = histutils.add_hists(hists) h_total_stat = make_stat_hist(h_total) sys_hists_total = {} for sys in sys_dict.values(): hists_up = [] hists_dn = [] for h in hists: ## if hist not found, take nominal if not h.sys_hists.has_key(sys): hists_up.append(h) hists_dn.append(h) else: hists_up.append(h.sys_hists[sys][0] or h) hists_dn.append(h.sys_hists[sys][0] or h) h_up = histutils.add_hists(hists_up) h_dn = histutils.add_hists(hists_dn) sys_hists_total[sys] = (h_up, h_dn) ## sum bin-by-bin deviations in quadrature h_sys_UP = h_total.Clone('%s_sys_UP' % (h_total.GetName())) h_sys_DN = h_total.Clone('%s_sys_DN' % (h_total.GetName())) h_total_UP = h_total.Clone('%s_total_UP' % (h_total.GetName())) h_total_DN = h_total.Clone('%s_total_DN' % (h_total.GetName())) for i in range(1, h_total.GetNbinsX() + 1): n = h_total.GetBinContent(i) tot_sys_UP2 = 0.0 tot_sys_DN2 = 0.0 for sys in sys_dict.values(): (h_UP, h_DN) = sys_hists_total[sys] n_UP = h_UP.GetBinContent(i) n_DN = h_DN.GetBinContent(i) v_UP = (n_UP - n) / n if (n_UP != None and n) else 0.0 v_DN = (n_DN - n) / n if (n_DN != None and n) else 0.0 tot_sys_UP2 += pow(v_UP, 2) tot_sys_DN2 += pow(v_DN, 2) tot_sys_UP = sqrt(tot_sys_UP2) tot_sys_DN = sqrt(tot_sys_DN2) h_sys_UP.SetBinContent(i, tot_sys_UP) h_sys_DN.SetBinContent(i, tot_sys_DN) stat = h_total_stat.GetBinContent(i) tot_UP = sqrt(pow(tot_sys_UP, 2) + pow(stat, 2)) tot_DN = sqrt(pow(tot_sys_DN, 2) + pow(stat, 2)) h_total_UP.SetBinContent(i, tot_UP) h_total_DN.SetBinContent(i, tot_DN) return (h_total_stat, h_sys_UP, h_sys_DN, h_total_UP, h_total_DN)
def get_total_stat_sys_hists(hists,sys_dict): """ first make total hist for each systematic. then sum deviations in quadrature bin-by-bin to make band. """ ## make total sys hists h_total = histutils.add_hists(hists) h_total_stat = make_stat_hist(h_total) sys_hists_total = {} for sys in sys_dict.values(): hists_up = [] hists_dn = [] for h in hists: ## if hist not found, take nominal if not h.sys_hists.has_key(sys): hists_up.append(h) hists_dn.append(h) else: hists_up.append(h.sys_hists[sys][0] or h) hists_dn.append(h.sys_hists[sys][0] or h) h_up = histutils.add_hists(hists_up) h_dn = histutils.add_hists(hists_dn) sys_hists_total[sys] = (h_up,h_dn) ## sum bin-by-bin deviations in quadrature h_sys_UP = h_total.Clone('%s_sys_UP'%(h_total.GetName())) h_sys_DN = h_total.Clone('%s_sys_DN'%(h_total.GetName())) h_total_UP = h_total.Clone('%s_total_UP'%(h_total.GetName())) h_total_DN = h_total.Clone('%s_total_DN'%(h_total.GetName())) for i in range(1,h_total.GetNbinsX()+1): n = h_total.GetBinContent(i) tot_sys_UP2 = 0.0 tot_sys_DN2 = 0.0 for sys in sys_dict.values(): (h_UP,h_DN) = sys_hists_total[sys] n_UP = h_UP.GetBinContent(i) n_DN = h_DN.GetBinContent(i) v_UP = (n_UP-n)/n if (n_UP!=None and n) else 0.0 v_DN = (n_DN-n)/n if (n_DN!=None and n) else 0.0 tot_sys_UP2 += pow(v_UP,2) tot_sys_DN2 += pow(v_DN,2) tot_sys_UP = sqrt(tot_sys_UP2) tot_sys_DN = sqrt(tot_sys_DN2) h_sys_UP.SetBinContent(i,tot_sys_UP) h_sys_DN.SetBinContent(i,tot_sys_DN) stat = h_total_stat.GetBinContent(i) tot_UP = sqrt(pow(tot_sys_UP,2)+pow(stat,2)) tot_DN = sqrt(pow(tot_sys_DN,2)+pow(stat,2)) h_total_UP.SetBinContent(i,tot_UP) h_total_DN.SetBinContent(i,tot_DN) return (h_total_stat,h_sys_UP,h_sys_DN,h_total_UP,h_total_DN)
def hist(self, histname=None, region=None, icut=None, sys=None, mode=None): """ Supports list of regions to be added """ if not self.is_affected_by_systematic(sys): sys = mode = None htag = self.get_hist_tag(histname, region, icut, sys, mode) if not isinstance(region, list): region = [region] if not self.hist_store.has_key(htag): h_dict = {} for r in region: h_dict[r] = self.__hist__( histname=histname, region=r, icut=icut, sys=sys, mode=mode, ) h = None if not all(v is None for v in h_dict.values()): h = histutils.add_hists(h_dict.values()) if h: self.sample.plotopts.configure(h) log.debug('%s: %s' % (self.sample.name, h.Integral())) self.hist_store[htag] = h return self.hist_store[htag]
def __hist__(self,region=None,icut=None,histname=None,sys=None,mode=None): hists = [] for s in self.samples: h = s.hist(region=region,icut=icut,histname=histname,sys=sys,mode=mode) if h: hists.append(h) h = histutils.add_hists(hists) return h
def hist(self,histname=None,region=None,icut=None,sys=None,mode=None): """ Supports list of regions to be added """ if not self.is_affected_by_systematic(sys): sys=mode=None htag = self.get_hist_tag(histname,region,icut,sys,mode) if not isinstance(region,list): region = [region] if not self.hist_store.has_key(htag): h_dict = {} for r in region: h_dict[r] = self.__hist__( histname=histname, region=r, icut=icut, sys=sys, mode=mode, ) h = None if not all(v is None for v in h_dict.values()): h = histutils.add_hists(h_dict.values()) if h: self.sample.plotopts.configure(h) log.debug('%s: %s'%(self.sample.name,h.Integral())) self.hist_store[htag] = h return self.hist_store[htag]
def __hist__(self,region=None,histname=None,icut=None,sys=None,mode=None): # ---------------- # addition regions # ---------------- h_addition = [] for reg in self.addition_regions: if "fakes" in self.sample.name: h_data_minus_mc = self.data_minus_mc.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_data_minus_mc: h_addition.append(h_data_minus_mc.Clone()) elif "data" in self.sample.name: h_data = self.data_sample.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_data: h_addition.append(h_data.Clone()) elif self.sample.type == "mc": for mcs in self.mc_samples: if mcs.name in self.sample.name: h_mcs = mcs.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_mcs: h_addition.append(h_mcs.Clone()) # ------------------- # subtraction regions # ------------------- h_subtraction = [] for reg in self.subtraction_regions: if "fakes" in self.sample.name: h_data_minus_mc = self.data_minus_mc.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_data_minus_mc: h_subtraction.append(h_data_minus_mc.Clone()) elif "data" in self.sample.name: h_data = self.data_sample.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_data: h_subtraction.append(h_data.Clone()) elif self.sample.type == "mc": for mcs in self.mc_samples: if mcs.name in self.sample.name: h_mcs = mcs.hist(region=reg,histname=histname,icut=icut,sys=sys,mode=mode) if h_mcs: h_subtraction.append(h_mcs.Clone()) h = histutils.add_hists(h_addition) if h_subtraction: h.Add(histutils.add_hists(h_subtraction), -1.0) return h
def __hist__(self, region=None, icut=None, histname=None, sys=None, mode=None): hists = [] for s in self.samples: h = s.hist(region=region, icut=icut, histname=histname, sys=sys, mode=mode) if h: hists.append(h) h = histutils.add_hists(hists) return h
def __hist__(self, region=None, histname=None, icut=None, sys=None, mode=None): # ---------------- # addition regions # ---------------- h_addition = [] for reg in self.addition_regions: if "fakes" in self.sample.name: h_data_minus_mc = self.data_minus_mc.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_data_minus_mc: h_addition.append(h_data_minus_mc.Clone()) elif "data" in self.sample.name: h_data = self.data_sample.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_data: h_addition.append(h_data.Clone()) elif self.sample.type == "mc": for mcs in self.mc_samples: if mcs.name in self.sample.name: h_mcs = mcs.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_mcs: h_addition.append(h_mcs.Clone()) # ------------------- # subtraction regions # ------------------- h_subtraction = [] for reg in self.subtraction_regions: if "fakes" in self.sample.name: h_data_minus_mc = self.data_minus_mc.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_data_minus_mc: h_subtraction.append(h_data_minus_mc.Clone()) elif "data" in self.sample.name: h_data = self.data_sample.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_data: h_subtraction.append(h_data.Clone()) elif self.sample.type == "mc": for mcs in self.mc_samples: if mcs.name in self.sample.name: h_mcs = mcs.hist(region=reg, histname=histname, icut=icut, sys=sys, mode=mode) if h_mcs: h_subtraction.append(h_mcs.Clone()) h = histutils.add_hists(h_addition) if h_subtraction: h.Add(histutils.add_hists(h_subtraction), -1.0) return h
def plot_hist( backgrounds=None, signal=None, data=None, region=None, label=None, icut=None, histname=None, log=False, logx=False, blind=None, xmin=None, xmax=None, rebin=None, rebinVar=[], sys_dict=None, do_ratio_plot=True, save_eps=False, plotsfile=None, sig_rescale=None, xlabel=None, ): ''' TODO: * move this to a new module when finished * write description for this function ''' print 'making plot: ', histname, ' in region', region print 'rebinVar', rebinVar print xlabel #assert signal, "ERROR: no signal provided for plot_hist" assert backgrounds, "ERROR: no background provided for plot_hist" samples = list(backgrounds) if signal: samples += signal if data: samples += [data] ## generate nominal hists hists = get_hists( region=region, icut=icut, histname=histname, samples=samples, rebin=rebin, rebinVar=rebinVar, sys_dict=sys_dict, ) ## sum nominal background h_bkg_list = [] for b in backgrounds: if not b in hists.keys(): continue h_bkg_list.append(hists[b]) h_total = histutils.add_hists(h_bkg_list) ## get stat / sys bands if sys_dict: total_hists = get_total_stat_sys_hists(h_bkg_list, sys_dict) g_stat = make_band_graph_from_hist(total_hists[0]) g_stat.SetFillColor(ROOT.kGray) g_stat.SetLineColor(ROOT.kGray) g_tot = make_band_graph_from_hist(total_hists[3], total_hists[4]) g_tot.SetFillColor(ROOT.kOrange - 9) g_tot.SetLineColor(ROOT.kOrange - 9) else: h_total_stat = make_stat_hist(h_total) g_stat = make_band_graph_from_hist(h_total_stat) g_stat.SetFillColor(ROOT.kGray) g_stat.SetLineColor(ROOT.kGray) g_tot = None ## blind data and create ratio h_data = None h_ratio = None if data: h_data = hists[data] h_data.SetMarkerSize(0.8) h_data.Sumw2(0) h_data.SetBinErrorOption(1) if blind: apply_blind(h_data, blind) h_ratio = h_data.Clone('%s_ratio' % (h_data.GetName())) h_ratioGr = ROOT.TGraphAsymmErrors() h_ratioGr.SetMarkerSize(0.8) ## dont use Divide as it will propagate MC stat error to the ratio. #h_ratio.Divide(h_total) for i in range(1, h_ratio.GetNbinsX() + 1): if h_total.GetBinContent(i) != 0 and h_data.GetBinContent(i) != 0: h_ratio.SetBinContent( i, h_ratio.GetBinContent(i) / h_total.GetBinContent(i)) h_ratio.SetBinError( i, h_ratio.GetBinError(i) / h_total.GetBinContent(i)) h_ratioGr.SetPoint(h_ratioGr.GetN(), h_ratio.GetBinCenter(i), h_ratio.GetBinContent(i)) h_ratioGr.SetPointError( h_ratioGr.GetN() - 1, 0, 0, h_data.GetBinErrorLow(i) / h_total.GetBinContent(i), h_data.GetBinErrorUp(i) / h_total.GetBinContent(i)) else: h_ratio.SetBinContent(i, -100) h_ratio.SetBinError(i, 0) h_ratioGr.SetPoint(h_ratioGr.GetN(), h_ratio.GetBinCenter(i), h_ratio.GetBinContent(i)) h_ratioGr.SetPointError(h_ratioGr.GetN() - 1, 0, 0, 0, 0) yaxistitle = None for b in reversed(backgrounds): if not b in hists.keys(): continue else: yaxistitle = hists[b].GetYaxis().GetTitle() break ## create stack h_stack = ROOT.THStack() #for s in reversed(signal+backgrounds): for b in reversed(backgrounds): if not b in hists.keys(): continue h_stack.Add(hists[b]) if signal: nLegend = len(signal + backgrounds) + 2 else: nLegend = len(backgrounds) + 2 x_legend = 0.63 x_leg_shift = 0 y_leg_shift = -0.1 legYCompr = 8.0 legYMax = 0.85 legYMin = legYMax - (legYMax - (0.55 + y_leg_shift)) / legYCompr * nLegend legXMin = x_legend + x_leg_shift legXMax = legXMin + 0.25 ## create legend (could use metaroot functionality?) if not do_ratio_plot: legXMin -= 0.005 legXMax -= 0.058 leg = ROOT.TLegend(legXMin / 1.2, legYMin + 0.05 + (legYMax - legYMin) / 1.9, legXMax + 0.08, legYMax + 0.05) leg.SetBorderSize(0) leg.SetNColumns(2) leg.SetFillColor(0) leg.SetFillStyle(0) leg.SetTextSize(0.045) if not do_ratio_plot: leg.SetTextSize(0.035) if data: leg.AddEntry(h_data, "#font[42]{" + str(data.tlatex) + "}", 'P') for b in backgrounds: if not b in hists.keys(): continue leg.AddEntry(hists[b], "#font[42]{" + str(b.tlatex) + "}", 'F') leg2 = ROOT.TLegend(legXMin / 1.2, legYMin + 0.05 + (legYMax - legYMin) / 2.5 - 0.07, legXMax + 0.08 - 0.2, legYMin + 0.05 + (legYMax - legYMin) / 1.9) leg2.SetBorderSize(0) leg2.SetFillColor(0) leg2.SetFillStyle(0) leg2.SetTextSize(0.045) if not do_ratio_plot: leg2.SetTextSize(0.035) if signal: for s in signal: sig_tag = s.tlatex if sig_rescale: sig_tag = "%d #times " % int(sig_rescale) + sig_tag if not s in hists.keys(): continue #leg2.AddEntry(hists[s],"\font[42]{"+str(sig_tag)+"}",'F') leg2.AddEntry(hists[s], str(sig_tag), 'F') ## create canvas reg = region if not reg: reg = "" name = '_'.join([reg, histname]).replace('/', '_') cname = "c_final_%s" % name if do_ratio_plot: c = ROOT.TCanvas(cname, cname, 600, 600) else: c = ROOT.TCanvas(cname, cname, 600, 600) if xmin == None: xmin = h_total.GetBinLowEdge(1) if xmax == None: xmax = h_total.GetBinLowEdge(h_total.GetNbinsX() + 1) ymin = 1.e-2 if log else 0.0 ymax = h_total.GetMaximum() for b in backgrounds: if not b in hists.keys(): continue ymax = max([ymax, hists[b].GetMaximum()]) if data: ymax = max([ymax, h_data.GetMaximum()]) if log: ymax *= 4000. else: ymax *= 1.7 xtitle = h_total.GetXaxis().GetTitle() if do_ratio_plot: rsplit = 0.3 else: rsplit = 0. pad1 = ROOT.TPad("pad1", "top pad", 0., rsplit, 1., 1.) pad1.SetLeftMargin(0.15) pad1.SetLeftMargin(0.15) pad1.SetTicky() pad1.SetTickx() if do_ratio_plot: pad1.SetBottomMargin(0.04) pad1.SetTopMargin(0.07) else: pad1.SetBottomMargin(0.15) pad1.Draw() if do_ratio_plot: pad2 = ROOT.TPad("pad2", "bottom pad", 0, 0, 1, rsplit) pad2.SetTopMargin(0.04) pad2.SetBottomMargin(0.40) pad2.SetLeftMargin(0.15) pad2.SetTicky() pad2.SetTickx() pad2.SetGridy() #if do_ratio_plot: pad2.Draw() pad2.Draw() pad1.cd() ytitle = "Events" if not rebin: ytitle = yaxistitle elif rebin != 1 and "GeV" in xtitle: ytitle += " / %s GeV" % rebin fr1 = pad1.DrawFrame(xmin, ymin, xmax, ymax, ';%s;%s' % (xtitle, ytitle)) if do_ratio_plot: fr1.GetXaxis().SetTitleSize(0) fr1.GetXaxis().SetLabelSize(0) xaxis1 = fr1.GetXaxis() yaxis1 = fr1.GetYaxis() scale = (1.3 + rsplit) if not do_ratio_plot: xaxis1.SetTitleSize(0.7 * xaxis1.GetTitleSize() * scale) xaxis1.SetLabelSize(0.7 * xaxis1.GetLabelSize() * scale) xaxis1.SetTickLength(xaxis1.GetTickLength() * scale) xaxis1.SetTitleOffset(xaxis1.GetTitleOffset() / scale) xaxis1.SetLabelOffset(1. * xaxis1.GetLabelOffset() / scale) xaxis1.SetNoExponent() xaxis1.SetMoreLogLabels() yaxis1.SetTitleSize(yaxis1.GetTitleSize() * scale / 1.3) yaxis1.SetTitleOffset(2.1 * yaxis1.GetTitleOffset() / scale / 1.8) yaxis1.SetLabelSize(0.8 * yaxis1.GetLabelSize() * scale / 1.09) yaxis1.SetLabelOffset(1. * yaxis1.GetLabelOffset() / scale) xaxis1.SetNdivisions(510) yaxis1.SetNdivisions(510) h_stack.Draw("SAME,HIST") if signal: for s in reversed(signal): if not s in hists.keys(): continue if sig_rescale: hists[s].Scale(sig_rescale) hists[s].Draw("SAME,HIST") if data: h_data.Draw("SAME X0 P E") pad1.SetLogy(log) if logx != None: pad1.SetLogx(logx) leg.Draw() if signal: leg2.Draw() pad1.RedrawAxis() tlatex = ROOT.TLatex() tlatex.SetNDC() tlatex.SetTextSize(0.05) lx = 0.6 # for ATLAS internal ly = 0.845 tlatex.SetTextFont(42) ty = 0.96 th = 0.07 tx = 0.18 lumi = backgrounds[0].estimator.hm.target_lumi / 1000. textsize = 0.8 if not do_ratio_plot: textsize = 0.8 latex_y = ty - 2. * th + 0.05 tlatex.DrawLatex(tx, latex_y - 0.054, '#font[42]{#sqrt{s} = 13 TeV, %2.1f fb^{-1}}' % (lumi)) ROOT.ATLASLabel(tx, latex_y, "Internal", 1) if label: latex_y -= 0.06 #for i,line in enumerate(label): # tlatex.DrawLatex(tx,latex_y-i*0.06,"#scale[%lf]{%s}"%(textsize,line)) tlatex.DrawLatex(tx, latex_y - 0.04, "#font[42]{%s}" % label) if blind: line = ROOT.TLine() line.SetLineColor(ROOT.kBlack) line.SetLineStyle(2) line.DrawLine(blind, ymin, blind, ymax) bltext = ROOT.TLatex() bltext.SetTextFont(42) bltext.SetTextSize(0.04) bltext.SetTextAngle(90.) bltext.SetTextAlign(31) bltext.DrawLatex(blind, ymax, 'Blind ') if do_ratio_plot: pad2.cd() fr2 = pad2.DrawFrame(xmin, 0.49, xmax, 1.51, ';%s;Data / Bkg.' % (xtitle)) xaxis2 = fr2.GetXaxis() yaxis2 = fr2.GetYaxis() scale = (1. / rsplit) yaxis2.SetTitleSize(yaxis2.GetTitleSize() * scale / 1.2) yaxis2.SetLabelSize(yaxis2.GetLabelSize() * scale / 1.2) yaxis2.SetTitleOffset(2.1 * yaxis2.GetTitleOffset() / scale / 2) yaxis2.SetLabelOffset(0.4 * yaxis2.GetLabelOffset() * scale) xaxis2.SetTitleSize(xaxis2.GetTitleSize() * scale / 1.2) xaxis2.SetLabelSize(0.8 * xaxis2.GetLabelSize() * scale) xaxis2.SetTickLength(xaxis2.GetTickLength() * scale) xaxis2.SetTitleOffset(3.2 * xaxis2.GetTitleOffset() / scale / 1.2) xaxis2.SetLabelOffset(2.5 * xaxis2.GetLabelOffset() / scale) yaxis2.SetNdivisions(510) xaxis2.SetNdivisions(510) if logx: pad2.SetLogx(logx) xaxis2.SetMoreLogLabels() xaxis2.SetNoExponent() else: pass if g_tot: g_tot.Draw("E2") g_stat.Draw("SAME,E2") leg.AddEntry(g_stat, "#font[42]{" + str("MC Stat.") + "}", 'F') leg.AddEntry(g_tot, "#font[42]{" + str("Sys. Unc.") + "}", 'F') else: g_stat.Draw("E2") leg.AddEntry(g_stat, "#font[42]{" + str("MC Stat.") + "}", 'F') arrows = [] if data: #h_ratio.Draw("SAME X0 P E0") h_ratioGr.Draw("SAME E0 P") h_ratioGr.SetLineWidth(2) for bin_itr in range(1, h_ratio.GetNbinsX() + 1): if (h_total.GetBinContent(bin_itr) == 0 or h_data.GetBinContent(bin_itr) == 0): continue if (h_ratio.GetBinContent(bin_itr) - h_data.GetBinErrorLow(bin_itr) / h_total.GetBinContent(bin_itr)) > 1.51: arrowX = h_ratio.GetBinCenter(bin_itr) arrow = ROOT.TArrow(arrowX, 1.35, arrowX, 1.5, 0.012, "=>") arrow.SetLineWidth(2) arrow.SetLineColor(ROOT.kRed + 1) arrow.SetFillColor(ROOT.kRed + 1) arrows += [arrow] arrow.Draw() elif (h_ratio.GetBinContent(bin_itr) + h_data.GetBinErrorUp(bin_itr) / h_total.GetBinContent(bin_itr) ) < 0.49 and h_ratio.GetBinContent(bin_itr) not in [ -100, 0 ]: arrowX = h_ratio.GetBinCenter(bin_itr) arrow = ROOT.TArrow(arrowX, 0.50, arrowX, 0.65, 0.012, "<=") arrow.SetLineWidth(2) arrow.SetLineColor(ROOT.kRed + 1) arrow.SetFillColor(ROOT.kRed + 1) arrows += [arrow] arrow.Draw() pad2.RedrawAxis() pad2.RedrawAxis("g") if xlabel: if not do_ratio_plot: xaxis1.SetTitle(xlabel) else: xaxis2.SetTitle(xlabel) print 'saving plot...' if save_eps: eps_file = plotsfile.replace(".root", ".eps") if not log: c.SaveAs(eps_file) else: c.SaveAs(eps_file.replace(".eps", "_LOG.eps")) fout = ROOT.TFile.Open(plotsfile, 'UPDATE') fout.WriteTObject(c) fout.Close()
def plot_hist( backgrounds = None, signal = None, data = None, region = None, label = None, icut = None, histname = None, log = False, logx = False, blind = None, xmin = None, xmax = None, rebin = None, sys_dict = None, do_ratio_plot = False, save_eps = False, plotsfile = None, sig_rescale = None, ): ''' TODO: * move this to a new module when finished * write description for this function ''' print 'making plot: ', histname, ' in region', region #assert signal, "ERROR: no signal provided for plot_hist" assert backgrounds, "ERROR: no background provided for plot_hist" samples = backgrounds + signal if data: samples += [data] ## generate nominal hists hists = get_hists( region=region, icut=icut, histname=histname, samples=samples, rebin=rebin, sys_dict=sys_dict, ) ## sum nominal background h_bkg_list = [] for b in backgrounds: if not b in hists.keys(): continue h_bkg_list.append(hists[b]) h_total = histutils.add_hists(h_bkg_list) ## get stat / sys bands if sys_dict: total_hists = get_total_stat_sys_hists(h_bkg_list,sys_dict) g_stat = make_band_graph_from_hist(total_hists[0]) g_stat.SetFillColor(ROOT.kGray+1) g_tot = make_band_graph_from_hist(total_hists[3],total_hists[4]) g_tot.SetFillColor(ROOT.kRed) else: h_total_stat = make_stat_hist(h_total) g_stat = make_band_graph_from_hist(h_total_stat) g_stat.SetFillColor(ROOT.kGray+1) g_tot = None ## blind data and create ratio h_data = None h_ratio = None if data: h_data = hists[data] if blind: apply_blind(h_data,blind) h_ratio = h_data.Clone('%s_ratio'%(h_data.GetName())) h_ratio.Divide(h_total) yaxistitle = None for b in reversed(backgrounds): if not b in hists.keys(): continue else : yaxistitle = hists[b].GetYaxis().GetTitle() break ## create stack h_stack = ROOT.THStack() #for s in reversed(signal+backgrounds): for b in reversed(backgrounds): if not b in hists.keys(): continue h_stack.Add(hists[b]) nLegend = len(signal+backgrounds) + 1 x_legend = 0.63 x_leg_shift = -0.055 y_leg_shift = 0.0 legYCompr = 8.0 legYMax = 0.85 legYMin = legYMax - (legYMax - (0.55 + y_leg_shift)) / legYCompr * nLegend legXMin = x_legend + x_leg_shift legXMax = legXMin + 0.4 ## create legend (could use metaroot functionality?) if not do_ratio_plot: legXMin -= 0.005 legXMax -= 0.058 leg = ROOT.TLegend(legXMin,legYMin,legXMax,legYMax) leg.SetBorderSize(0) leg.SetFillColor(0) leg.SetFillStyle(0) if data: leg.AddEntry(h_data,data.tlatex,'PL') if signal: for s in signal: sig_tag = s.tlatex if sig_rescale: sig_tag = "%d #times "%int(sig_rescale) + sig_tag if not s in hists.keys(): continue leg.AddEntry(hists[s],sig_tag,'F') for b in backgrounds: if not b in hists.keys(): continue leg.AddEntry(hists[b],b.tlatex,'F') ## create canvas reg = region if not reg: reg = "" name = '_'.join([reg,histname]).replace('/','_') cname = "c_final_%s"%name if do_ratio_plot: c = ROOT.TCanvas(cname,cname,750,800) else: c = ROOT.TCanvas(cname,cname,800,700) if xmin==None: xmin = h_total.GetBinLowEdge(1) if xmax==None: xmax = h_total.GetBinLowEdge(h_total.GetNbinsX()+1) ymin = 1.e-3 ymax = h_total.GetMaximum() for b in backgrounds: if not b in hists.keys(): continue ymax = max([ymax,hists[b].GetMaximum()]) if data: ymax = max([ymax,h_data.GetMaximum()]) if log: ymax *= 100000. else: ymax *= 1.8 xtitle = h_total.GetXaxis().GetTitle() if do_ratio_plot: rsplit = 0.3 else: rsplit = 0. pad1 = ROOT.TPad("pad1","top pad",0.,rsplit,1.,1.) pad1.SetLeftMargin(0.15) pad1.SetTicky() pad1.SetTickx() if do_ratio_plot: pad1.SetBottomMargin(0.04) else: pad1.SetBottomMargin(0.15) pad1.Draw() if do_ratio_plot: pad2 = ROOT.TPad("pad2","bottom pad",0,0,1,rsplit) pad2.SetTopMargin(0.04) pad2.SetBottomMargin(0.40) pad2.SetLeftMargin(0.15) pad2.SetTicky() pad2.SetTickx() pad2.SetGridy() #if do_ratio_plot: pad2.Draw() pad2.Draw() pad1.cd() ytitle = "Events" if not rebin: ytitle = yaxistitle elif rebin!=1: if not "BDT" in xtitle: ytitle += " / %s"%rebin if ("eta" in xtitle) or ("phi" in xtitle) or ("trk" in xtitle): pass else: ytitle += " GeV" else: ytitle += " / %s"%(0.05) fr1 = pad1.DrawFrame(xmin,ymin,xmax,ymax,';%s;%s'%(xtitle,ytitle)) if do_ratio_plot: fr1.GetXaxis().SetTitleSize(0) fr1.GetXaxis().SetLabelSize(0) xaxis1 = fr1.GetXaxis() yaxis1 = fr1.GetYaxis() scale = (1.3+rsplit) if not do_ratio_plot: xaxis1.SetTitleSize( xaxis1.GetTitleSize() * scale ) xaxis1.SetLabelSize( 0.9 * xaxis1.GetLabelSize() * scale ) xaxis1.SetTickLength( xaxis1.GetTickLength() * scale ) xaxis1.SetTitleOffset( 1.3* xaxis1.GetTitleOffset() / scale ) xaxis1.SetLabelOffset( 1.* xaxis1.GetLabelOffset() / scale ) yaxis1.SetTitleSize( yaxis1.GetTitleSize() * scale ) yaxis1.SetTitleOffset( 2.1 * yaxis1.GetTitleOffset() / scale ) yaxis1.SetLabelSize( 0.8 * yaxis1.GetLabelSize() * scale ) yaxis1.SetLabelOffset( 1. * yaxis1.GetLabelOffset() / scale ) xaxis1.SetNdivisions(510) yaxis1.SetNdivisions(510) h_stack.Draw("SAME,HIST") if signal: for s in reversed(signal): if not s in hists.keys(): continue if sig_rescale: hists[s].Scale(sig_rescale) hists[s].Draw("SAME,HIST") if data: h_data.Draw("SAME") pad1.SetLogy(log) pad1.SetLogx(logx) leg.Draw() pad1.RedrawAxis() tlatex = ROOT.TLatex() tlatex.SetNDC() tlatex.SetTextSize(0.05) lx = 0.6 # for ATLAS internal ly = 0.845 tlatex.SetTextFont(42) ty = 0.96 th = 0.07 tx = 0.18 lumi = backgrounds[0].estimator.hm.target_lumi/1000. textsize = 0.8 if not do_ratio_plot: textsize = 0.8 latex_y = ty-2.*th tlatex.DrawLatex(tx,latex_y,'#scale[%lf]{#scale[%lf]{#int}L dt = %2.1f fb^{-1}, #sqrt{s} = 13 TeV}'%(textsize,0.8*textsize,lumi) ) if label: latex_y -= 0.06 #for i,line in enumerate(label): # tlatex.DrawLatex(tx,latex_y-i*0.06,"#scale[%lf]{%s}"%(textsize,line)) tlatex.DrawLatex(tx,latex_y - 0.06,"#scale[%lf]{%s}"%(textsize,label)) if blind: line = ROOT.TLine() line.SetLineColor(ROOT.kBlack) line.SetLineStyle(2) line.DrawLine(blind,ymin,blind,ymax) bltext = ROOT.TLatex() bltext.SetTextFont(42) bltext.SetTextSize(0.04) bltext.SetTextAngle(90.) bltext.SetTextAlign(31) bltext.DrawLatex(blind,ymax, 'Blind ') if do_ratio_plot: pad2.cd() fr2 = pad2.DrawFrame(xmin,0.49,xmax,1.51,';%s;Data / Bkg_{SM}'%(xtitle)) xaxis2 = fr2.GetXaxis() yaxis2 = fr2.GetYaxis() scale = (1. / rsplit) yaxis2.SetTitleSize( yaxis2.GetTitleSize() * scale ) yaxis2.SetLabelSize( yaxis2.GetLabelSize() * scale ) yaxis2.SetTitleOffset( 2.1* yaxis2.GetTitleOffset() / scale ) yaxis2.SetLabelOffset(0.4 * yaxis2.GetLabelOffset() * scale ) xaxis2.SetTitleSize( xaxis2.GetTitleSize() * scale ) xaxis2.SetLabelSize( 0.8 * xaxis2.GetLabelSize() * scale ) xaxis2.SetTickLength( xaxis2.GetTickLength() * scale ) xaxis2.SetTitleOffset( 3.2* xaxis2.GetTitleOffset() / scale ) xaxis2.SetLabelOffset( 2.5* xaxis2.GetLabelOffset() / scale ) yaxis2.SetNdivisions(510) xaxis2.SetNdivisions(510) if logx: pad2.SetLogx(logx) xaxis2.SetMoreLogLabels() else: pass if g_tot: g_tot.Draw("E2") g_stat.Draw("SAME,E2") else: g_stat.Draw("E2") if data: h_ratio.Draw("SAME") pad2.RedrawAxis() print 'saving plot...' if save_eps: eps_file = plotsfile.replace(".root",".eps") if not log: c.SaveAs(eps_file) else: c.SaveAs(eps_file.replace(".eps","_LOG.eps")) fout = ROOT.TFile.Open(plotsfile,'UPDATE') fout.WriteTObject(c) fout.Close()
def __hist__(self, region=None, histname=None, icut=None, sys=None, mode=None): """ implementation of nominal hist getter """ # compute k-factors for OS and SS regions kf_OS = {} kf_SS = {} # initialise k-factors for s in self.mc_samples: kf_OS[s] = 1.0 kf_SS[s] = 1.0 kf_regions = self.kf_regions # compute k-factors for s in self.kf_regions.keys(): tmp_samples = list(self.mc_samples) tmp_samples.remove(s) data_sub = copy(self.data_minus_mc) data_sub.mc_samples = tmp_samples kf_OS[s] = histutils.full_integral( data_sub.hist(region=kf_regions[s]["OS"], histname=histname, icut=kf_regions[s]["ncuts"], sys=sys, mode=mode)) kf_OS[s] /= histutils.full_integral( s.hist(region=kf_regions[s]["OS"], histname=histname, icut=kf_regions[s]["ncuts"], sys=sys, mode=mode)) kf_SS[s] = histutils.full_integral( data_sub.hist(region=kf_regions[s]["SS"], histname=histname, icut=kf_regions[s]["ncuts"], sys=sys, mode=mode)) kf_SS[s] /= histutils.full_integral( s.hist(region=kf_regions[s]["SS"], histname=histname, icut=kf_regions[s]["ncuts"], sys=sys, mode=mode)) # compute rqcd transfer factor # adding k_factors to the estimators self.data_minus_mc_num.mc_samples_rescales = kf_OS self.data_minus_mc_den.mc_samples_rescales = kf_SS rqcd_regions = self.rqcd_regions rqcd = histutils.full_integral( self.data_minus_mc_num.hist( region=rqcd_regions[self.data_sample]["num"], histname=histname, icut=rqcd_regions[self.data_sample]["ncuts"], sys=sys, mode=mode)) rqcd /= histutils.full_integral( self.data_minus_mc_den.hist( region=rqcd_regions[self.data_sample]["den"], histname=histname, icut=rqcd_regions[self.data_sample]["ncuts"], sys=sys, mode=mode)) if self.print_info: print print print "++++++++++++++++++++++++++++++++++++++++" print "Iteration for %s" % self.sample.name print "++++++++++++++++++++++++++++++++++++++++" print print "k-factors for %s, sys %s, sys_mode %s" % (histname, sys, mode) print "----------------------------------------" print "Sample | Region | k-factor | Rqcd" print "----------------------------------------" for s in self.kf_regions.keys(): print "%s | %s | %.3lf | %.3lf" % (s.name, kf_regions[s]["OS"], kf_OS[s], rqcd) print "%s | %s | %.3lf | %.3lf" % (s.name, kf_regions[s]["SS"], kf_SS[s], rqcd) print addon_regions = self.addon_regions h_fakes = self.data_sample.hist( region=addon_regions[self.data_sample]["SS"], histname=histname, icut=addon_regions[self.data_sample]["ncuts"]) h_fakes.Scale(rqcd) h_addon = {} h_addon[self.data_sample] = h_fakes.Clone() for s in addon_regions.keys(): if s == self.data_sample: continue h_addon[s] = s.hist(region=addon_regions[s]["OS"], histname=histname, icut=addon_regions[s]["ncuts"], sys=sys, mode=mode).Clone() h_addon[s].Scale(kf_OS[s]) h_addon[s].Add( s.hist(region=addon_regions[s]["SS"], histname=histname, icut=addon_regions[s]["ncuts"], sys=sys, mode=mode).Clone(), -1.0 * rqcd * kf_SS[s]) """ ToDo: implement sys uncertainty for the scales!!! """ if sys and "scale" in sys.name: pass if not self.sample.name == "fakes": for s in h_addon.keys(): if self.sample.name == s.name: return h_addon[s] else: return histutils.add_hists(h_addon.values())
def plot_hist( backgrounds=None, signal=None, data=None, region=None, label=None, icut=None, histname=None, log=False, logx=False, blind=None, xmin=None, xmax=None, rebin=None, sys_dict=None, do_ratio_plot=False, plotsfile=None, sig_rescale=None, ): ''' TODO: * move this to a new module when finished * write description for this function ''' print 'making plot: ', histname, ' in region', region assert signal, "ERROR: no signal provided for plot_hist" assert backgrounds, "ERROR: no background provided for plot_hist" samples = backgrounds + signal if data: samples += [data] ## generate nominal hists hists = get_hists( region=region, icut=icut, histname=histname, samples=samples, rebin=rebin, sys_dict=sys_dict, ) ## sum nominal background h_samp_list = [] for s in backgrounds + signal: if not s in hists.keys(): continue h_samp_list.append(hists[s]) h_total = histutils.add_hists(h_samp_list) ## get stat / sys bands if sys_dict: total_hists = get_total_stat_sys_hists(h_samp_list, sys_dict) g_stat = make_band_graph_from_hist(total_hists[0]) g_stat.SetFillColor(ROOT.kGray + 1) g_tot = make_band_graph_from_hist(total_hists[3], total_hists[4]) g_tot.SetFillColor(ROOT.kRed) else: h_total_stat = make_stat_hist(h_total) g_stat = make_band_graph_from_hist(h_total_stat) g_stat.SetFillColor(ROOT.kGray + 1) g_tot = None ## blind data and create ratio h_data = None h_ratio = None if data: h_data = hists[data] if blind: apply_blind(h_data, blind) h_ratio = h_data.Clone('%s_ratio' % (h_data.GetName())) h_ratio.Divide(h_total) yaxistitle = None for b in reversed(backgrounds): if not b in hists.keys(): continue else: yaxistitle = hists[b].GetYaxis().GetTitle() break ## create stack h_stack = ROOT.THStack() for b in reversed(signal + backgrounds): if not b in hists.keys(): continue h_stack.Add(hists[b]) nLegend = len(signal + backgrounds) + 1 x_legend = 0.63 x_leg_shift = -0.055 y_leg_shift = 0.0 legYCompr = 8.0 legYMax = 0.85 legYMin = legYMax - (legYMax - (0.55 + y_leg_shift)) / legYCompr * nLegend legXMin = x_legend + x_leg_shift legXMax = legXMin + 0.4 ## create legend (could use metaroot functionality?) if not do_ratio_plot: legXMin -= 0.005 legXMax -= 0.058 leg = ROOT.TLegend(legXMin, legYMin, legXMax, legYMax) leg.SetBorderSize(0) leg.SetFillColor(0) leg.SetFillStyle(0) if data: leg.AddEntry(h_data, data.tlatex, 'PL') for s in signal: sig_tag = s.tlatex if sig_rescale: sig_tag = "%d #times " % int(sig_rescale) + sig_tag if not s in hists.keys(): continue leg.AddEntry(hists[s], sig_tag, 'F') for b in backgrounds: if not b in hists.keys(): continue leg.AddEntry(hists[b], b.tlatex, 'F') ## create canvas reg = region if not reg: reg = "" name = '_'.join([reg, histname]).replace('/', '_') cname = "c_final_%s" % name if do_ratio_plot: c = ROOT.TCanvas(cname, cname, 750, 800) else: c = ROOT.TCanvas(cname, cname, 800, 700) if xmin == None: xmin = h_total.GetBinLowEdge(1) if xmax == None: xmax = h_total.GetBinLowEdge(h_total.GetNbinsX() + 1) ymin = 1.e-3 ymax = h_total.GetMaximum() for s in signal: if not s in hists.keys(): continue ymax = max([ymax, hists[s].GetMaximum()]) if data: ymax = max([ymax, h_data.GetMaximum()]) if log: ymax *= 100000. else: ymax *= 1.8 xtitle = h_total.GetXaxis().GetTitle() if do_ratio_plot: rsplit = 0.3 else: rsplit = 0. pad1 = ROOT.TPad("pad1", "top pad", 0., rsplit, 1., 1.) pad1.SetLeftMargin(0.15) pad1.SetTicky() pad1.SetTickx() if do_ratio_plot: pad1.SetBottomMargin(0.04) else: pad1.SetBottomMargin(0.15) pad1.Draw() if do_ratio_plot: pad2 = ROOT.TPad("pad2", "bottom pad", 0, 0, 1, rsplit) pad2.SetTopMargin(0.04) pad2.SetBottomMargin(0.40) pad2.SetLeftMargin(0.15) pad2.SetTicky() pad2.SetTickx() pad2.SetGridy() #if do_ratio_plot: pad2.Draw() pad2.Draw() pad1.cd() ytitle = "Events" if not rebin: ytitle = yaxistitle elif rebin != 1: if not "BDT" in xtitle: ytitle += " / %s" % rebin if ("eta" in xtitle) or ("phi" in xtitle) or ("trk" in xtitle): pass else: ytitle += " GeV" else: ytitle += " / %s" % (0.05) fr1 = pad1.DrawFrame(xmin, ymin, xmax, ymax, ';%s;%s' % (xtitle, ytitle)) if do_ratio_plot: fr1.GetXaxis().SetTitleSize(0) fr1.GetXaxis().SetLabelSize(0) xaxis1 = fr1.GetXaxis() yaxis1 = fr1.GetYaxis() scale = (1.3 + rsplit) if not do_ratio_plot: xaxis1.SetTitleSize(xaxis1.GetTitleSize() * scale) xaxis1.SetLabelSize(0.9 * xaxis1.GetLabelSize() * scale) xaxis1.SetTickLength(xaxis1.GetTickLength() * scale) xaxis1.SetTitleOffset(1.3 * xaxis1.GetTitleOffset() / scale) xaxis1.SetLabelOffset(1. * xaxis1.GetLabelOffset() / scale) yaxis1.SetTitleSize(yaxis1.GetTitleSize() * scale) yaxis1.SetTitleOffset(2.1 * yaxis1.GetTitleOffset() / scale) yaxis1.SetLabelSize(0.8 * yaxis1.GetLabelSize() * scale) yaxis1.SetLabelOffset(1. * yaxis1.GetLabelOffset() / scale) xaxis1.SetNdivisions(510) yaxis1.SetNdivisions(510) h_stack.Draw("SAME,HIST") """ for s in reversed(signal): if not s in hists.keys(): continue if sig_rescale: hists[s].Scale(sig_rescale) hists[s].Draw("SAME,HIST") """ if data: h_data.Draw("SAME") pad1.SetLogy(log) pad1.SetLogx(logx) leg.Draw() pad1.RedrawAxis() tlatex = ROOT.TLatex() tlatex.SetNDC() tlatex.SetTextSize(0.05) lx = 0.6 # for ATLAS internal ly = 0.845 tlatex.SetTextFont(42) ty = 0.96 th = 0.07 tx = 0.18 lumi = backgrounds[0].estimator.hm.target_lumi / 1000. textsize = 0.8 if not do_ratio_plot: textsize = 0.8 latex_y = ty - 2. * th tlatex.DrawLatex( tx, latex_y, '#scale[%lf]{#scale[%lf]{#int}L dt = %2.1f fb^{-1}, #sqrt{s} = 13 TeV}' % (textsize, 0.8 * textsize, lumi)) if label: latex_y -= 0.06 #for i,line in enumerate(label): # tlatex.DrawLatex(tx,latex_y-i*0.06,"#scale[%lf]{%s}"%(textsize,line)) tlatex.DrawLatex(tx, latex_y - 0.06, "#scale[%lf]{%s}" % (textsize, label)) if blind: line = ROOT.TLine() line.SetLineColor(ROOT.kBlack) line.SetLineStyle(2) line.DrawLine(blind, ymin, blind, ymax) bltext = ROOT.TLatex() bltext.SetTextFont(42) bltext.SetTextSize(0.04) bltext.SetTextAngle(90.) bltext.SetTextAlign(31) bltext.DrawLatex(blind, ymax, 'Blind ') if do_ratio_plot: pad2.cd() fr2 = pad2.DrawFrame(xmin, 0.49, xmax, 1.51, ';%s;Data / Bkg_{SM}' % (xtitle)) xaxis2 = fr2.GetXaxis() yaxis2 = fr2.GetYaxis() scale = (1. / rsplit) yaxis2.SetTitleSize(yaxis2.GetTitleSize() * scale) yaxis2.SetLabelSize(yaxis2.GetLabelSize() * scale) yaxis2.SetTitleOffset(2.1 * yaxis2.GetTitleOffset() / scale) yaxis2.SetLabelOffset(0.4 * yaxis2.GetLabelOffset() * scale) xaxis2.SetTitleSize(xaxis2.GetTitleSize() * scale) xaxis2.SetLabelSize(0.8 * xaxis2.GetLabelSize() * scale) xaxis2.SetTickLength(xaxis2.GetTickLength() * scale) xaxis2.SetTitleOffset(3.2 * xaxis2.GetTitleOffset() / scale) xaxis2.SetLabelOffset(2.5 * xaxis2.GetLabelOffset() / scale) yaxis2.SetNdivisions(510) xaxis2.SetNdivisions(510) if logx: pad2.SetLogx(logx) xaxis2.SetMoreLogLabels() else: pass if g_tot: g_tot.Draw("E2") g_stat.Draw("SAME,E2") else: g_stat.Draw("E2") if data: h_ratio.Draw("SAME") pad2.RedrawAxis() print 'saving plot...' if not log: c.SaveAs("%s.eps" % c.GetName()) else: c.SaveAs("%s_LOG.eps" % c.GetName()) fout = ROOT.TFile.Open(plotsfile, 'UPDATE') fout.WriteTObject(c) fout.Close()