def compare_scenarios_by_pu_eta_bins(eta_bins, pu_labels, graph_lists, title, oDir, ylim=None, lowpt_zoom=False): for eta_min, eta_max in pairwise(eta_bins): for pu_ind, pu_label in enumerate(pu_labels): pu_graphs = [x[pu_ind] for x in graph_lists] # tweak names and colors for i, contr in enumerate(pu_graphs): contr.line_color = colors[i] contr.marker_color = colors[i] contr.obj_name = "eta_%g_%g/resRefRef_%g_%g_diff" % (eta_min, eta_max, eta_min, eta_max) fmt_dict = dict(eta_min=eta_min, eta_max=eta_max, pu_label=pu_label) plt_title = title.format(**fmt_dict) p = Plot(contributions=pu_graphs, what='graph', xtitle=pt_ref_str, ytitle=res_ref_str, title=plt_title, ylim=[0, 0.7], xlim=[0, 500]) p.legend.SetX1(0.4) p.plot() filename = 'compare_fall15_dummyLayer1_newLayer1_withJEC_eta_%g_%g_%s.pdf' % (eta_min, eta_max, pu_label) p.save(os.path.join(oDir, filename)) if lowpt_zoom: p = Plot(contributions=pu_graphs, what='graph', xtitle=pt_ref_str, ytitle=res_ref_str, title=plt_title, ylim=[0, 0.7], xlim=zoom_pt) p.legend.SetX1(0.4) p.plot() filename = 'compare_fall15_dummyLayer1_newLayer1_withJEC_eta_%g_%g_%s_ptZoomed.pdf' % (eta_min, eta_max, pu_label) p.save(os.path.join(oDir, filename))
def make_comparison_plot_ingredients(entries, rebin=1, normalise_hist=True, mean_rel_error=1.0, **plot_kwargs): """Make the Plot object for a comparison plot. User can then add other elements to the plot. Parameters ---------- entries : list[(object, dict)] List of ROOT object & it's configuration dict, where the dict is a set of kwargs passed to the Contribution object rebin : int, optional Rebin factor normalise_hist : bool, optional Normalise each histogram's integral to unity mean_rel_error : float, optional Remove contributions that have a mean realtive error more than this value mean realtive error = mean of all the error/bin contents **plot_kwargs Any other kwargs to be passed to the Plot object contructor Returns ------- Plot Plot object to be modified, plotted, etc Raises ------ RuntimeError If there are 0 contributions """ conts = [ Contribution(ent[0], normalise_hist=normalise_hist, rebin_hist=rebin, **ent[1]) for ent in entries ] # if get_hist_mean_rel_error(ent[0]) < mean_rel_error and ent[0].Integral() > 0] do_legend = len(conts) > 1 if len(conts) == 0: raise RuntimeError("0 contributions for this plot") do_subplot = any(c.subplot for c in conts) if (len(conts) == 1 or not do_subplot) and "subplot_type" in plot_kwargs: plot_kwargs['subplot_type'] = None p = Plot(conts, what="hist", ytitle="p.d.f", legend=do_legend, **plot_kwargs) if do_legend: p.legend.SetX1(0.5) p.legend.SetX2(0.95) if len(entries) > 4: p.legend.SetY1(0.67) else: p.legend.SetY1(0.78) p.legend.SetY2(0.95) return p
def do_pf_fraction_plot(hist_map, pt_bins, output_filename): """Plot PF particle type fractioin for matches, binned by GenParticle pT""" entries = [] for pt_low, pt_high, mark in zip(pt_bins[:-1], pt_bins[1:], cu.Marker().cycle()): values = {} for pf_ind, (pf_name, hist) in hist_map.items(): ax = hist.GetXaxis() binx1 = ax.FindBin(pt_low) binx2 = ax.FindBin(pt_high) - 1 if pt_high == ax.GetBinUpEdge(ax.GetLast()): binx2 = ax.GetLast() biny1 = 1 biny2 = hist.GetNbinsY() binz1 = 1 binz2 = hist.GetNbinsZ() values[pf_ind] = hist.Integral( binx1, binx2, biny1, biny2, binz1, binz2) # integral includes the last bin sum_values = sum(values.values()) fracs = {k: (v / sum_values) for k, v in values.items()} h = ROOT.TH1D("h_pt_bin_%gto%g" % (pt_low, pt_high), "", len(values), 0, len(values)) ax = h.GetXaxis() for ind, k in enumerate(sorted(fracs.keys()), 1): h.SetBinContent(ind, fracs[k]) h.SetBinError(ind, sqrt(values[k]) / sum_values) ax.SetBinLabel(ind, hist_map[k][0]) c = Contribution(h, label='%g < GenParticle p_{T} < %g GeV' % (pt_low, pt_high), line_width=1, marker_size=0.75, marker_style=mark, normalise_hist=False) entries.append(c) ROOT.gStyle.SetPalette(55) plot = Plot(entries, 'hist', xtitle='PF particle type', ytitle='Fraction matched as type', ylim=(1E-3, 2), has_data=False) plot.default_canvas_size = (800, 600) plot.plot("NOSTACK PMC PLC HISTE") plot.set_logy(do_more_labels=False) plot.save(output_filename) ROOT.gStyle.SetPalette(ROOT.kViridis)
def compare_eta_by_pu_bins(graphs, pu_labels, title, oDir, ylim=None, lowpt_zoom=True): """Compare eta bins for graphs for a given PU bin. Does central, fowrad, and central+forward. Parameters ---------- graphs : list[Contribution] Contributions corresponding to eta bins (0PU, PU0to10, 15to25, 30to40) title : str Title to put on plots oDir : str Output directory for plots ylim : list, optional Set y axis range lowpt_zoom : bool, optional Zoom in on low pt range """ cu.check_dir_exists_create(oDir) eta_scenarios = [binning.eta_bins_central, binning.eta_bins_forward, binning.eta_bins] eta_scenario_labels = ['central', 'forward', 'all'] for eta_bins, eta_label in izip(eta_scenarios, eta_scenario_labels): for pu_ind, pu_label in enumerate(pu_labels): new_graphs = [] rename_dict = dict(pu_label=pu_label) for eta_ind, (eta_min, eta_max) in enumerate(pairwise(eta_bins)): rename_dict['eta_min'] = eta_min rename_dict['eta_max'] = eta_max contr = deepcopy(graphs[pu_ind]) contr.obj_name = graphs[pu_ind].obj_name.format(**rename_dict) contr.line_color = colors[eta_ind] contr.marker_color = colors[eta_ind] contr.label = "%g < |#eta^{L1}| < %g" % (eta_min, eta_max) new_graphs.append(contr) if not ylim: ylim = [0.5, 4] p = Plot(contributions=new_graphs, what='graph', xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), ylim=ylim) p.plot() p.save(os.path.join(oDir, 'compare_%sEta_%s.pdf' % (eta_label, pu_label))) if lowpt_zoom: p = Plot(contributions=new_graphs, what='graph', xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim) p.plot() p.save(os.path.join(oDir, 'compare_%sEta_%s_pTzoomed.pdf' % (eta_label, pu_label)))
def plot_cutflow_hist(hist, output_filename, title='', has_data=False): """Plot one cutflow histogram. Normalises so bins are fractions of the first""" frac_hist = hist.Clone() first_bin = hist.GetBinContent(1) for i in range(1, frac_hist.GetNbinsX()+1): frac_hist.SetBinContent(i, hist.GetBinContent(i) / first_bin) frac_hist.SetBinError(i, hist.GetBinError(i) / first_bin) col = ROOT.kBlue entry = [Contribution(frac_hist, label='', line_color=col, line_width=2, line_style=1, marker_color=col, marker_size=0.75, marker_style=cu.Marker.get('circle'), normalise_hist=False)] hmax = frac_hist.GetMaximum() hmin = frac_hist.GetMinimum(0) hdiff = hmax-hmin ymin = max(0, hmin - (hdiff*0.1)) ymax = hmax + (hdiff*0.25) plot = Plot(entry, 'hist', xtitle='', ytitle='Fraction', title=title, ylim=(ymin, ymax), legend=False, has_data=has_data) plot.default_canvas_size = (800, 600) plot.plot("NOSTACK HISTE") plot.save(output_filename)
def compare_by_eta_pu_bins(graphs_list, file_identifier, pu_labels, title, oDir, ylim=None, lowpt_zoom=True): """Compare graphs for each (eta, PU) bin. Parameters ---------- graphs_list : list[list[Contribution]] List of list of contributions, so you can any number of sets of contributions on a graph. file_identifier : str String to be inserted into resultant plot filename. title : str Title to put on plots oDir : str Output directory for plots ylim : list, optional Set y axis range lowpt_zoom : bool, optional Zoom in on low pt range """ cu.check_dir_exists_create(oDir) for (eta_min, eta_max) in pairwise(binning.eta_bins): rename_dict = dict(eta_min=eta_min, eta_max=eta_max) eta_min_str = '{:g}'.format(eta_min).replace('.', 'p') eta_max_str = '{:g}'.format(eta_max).replace('.', 'p') new_graphs_list = [setup_new_graphs(g, rename_dict) for g in graphs_list] if not ylim: ylim = [0.5, 3.5] if eta_min > 2 else [0.5, 4] for i, pu_label in enumerate(pu_labels): rename_dict['pu_label'] = pu_label p = Plot(contributions=[ng[i] for ng in new_graphs_list], what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), ylim=ylim) p.plot() p.legend.SetX1(0.5) p.save(os.path.join(oDir, "compare_%s_eta_%s_%s_%s.pdf" % (file_identifier, eta_min_str, eta_max_str, pu_label))) if lowpt_zoom: # zoom in on low pT p = Plot(contributions=[ng[i] for ng in new_graphs_list], what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim) p.plot() p.legend.SetX1(0.5) p.save(os.path.join(oDir, "compare_%s_eta_%s_%s_%s_pTzoomed.pdf" % (file_identifier, eta_min_str, eta_max_str, pu_label)))
def draw_folded_hists(hist_mc_folded, hist_mc_reco, hist_data_reco, output_filename, title=""): entries = [] if hist_mc_folded: entries.append( Contribution(hist_mc_folded, label="Folded MC [detector-level]", line_color=ROOT.kGreen + 2, line_width=1, marker_color=ROOT.kGreen + 2, marker_size=0, normalise_hist=False, subplot=hist_data_reco), ) if hist_mc_reco: entries.append( Contribution(hist_mc_reco, label="Reco MC [detector-level]", line_color=ROOT.kAzure + 2, line_width=1, line_style=2, marker_color=ROOT.kAzure + 2, marker_size=0, normalise_hist=False, subplot=hist_data_reco), ) if hist_data_reco: entries.append( Contribution(hist_data_reco, label="Reco Data [detector-level]", line_color=ROOT.kRed, line_width=0, marker_color=ROOT.kRed, marker_size=0.6, marker_style=20, normalise_hist=False), ) plot = Plot(entries, what='hist', title=title, xtitle="Bin number", ytitle="N", subplot_type='ratio', subplot_title='MC/Data', subplot_limits=(0.25, 1.75)) plot.default_canvas_size = (800, 600) plot.plot("NOSTACK HISTE") plot.main_pad.SetLogy(1) ymax = max(h.GetMaximum() for h in [hist_mc_folded, hist_mc_reco, hist_data_reco] if h) plot.container.SetMaximum(ymax * 100) plot.container.SetMinimum(1) plot.legend.SetY1NDC(0.77) plot.legend.SetX2NDC(0.85) plot.save(output_filename)
def compare_PU_by_eta_bins(graphs, title, oDir, ylim=None, lowpt_zoom=True): """Plot graph contributions, with a different plot for each eta bin. Relies on each Contribution.obj_name in graphs being templated with the variables `eta_min` and `eta_max`. Parameters ---------- graphs : list[Contribution] List of Contribution objects to be included on any one plot. title : str Title to put on plots oDir : str Output directory for plots ylim : list, optional Set y axis range lowpt_zoom : bool, optional Zoom in on low pt range """ cu.check_dir_exists_create(oDir) for i, (eta_min, eta_max) in enumerate(pairwise(binning.eta_bins)): rename_dict = dict(eta_min=eta_min, eta_max=eta_max) eta_min_str = '{:g}'.format(eta_min).replace('.', 'p') eta_max_str = '{:g}'.format(eta_max).replace('.', 'p') # make a copy as we have to change the graph names new_graphs = setup_new_graphs(graphs, rename_dict) if not ylim: ylim = [0.5, 3] if eta_min > 2 else [0.5, 3] p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), ylim=ylim) p.plot() p.save(os.path.join(oDir, "compare_PU_eta_%s_%s.pdf" % (eta_min_str, eta_max_str))) if lowpt_zoom: # zoom in on low pT p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim) p.plot() p.save(os.path.join(oDir, "compare_PU_eta_%s_%s_pTzoomed.pdf" % (eta_min_str, eta_max_str)))
def print_hist_comparison(entries, plots_kwargs, output_filename): """Print multiple hists on canvas, no rescaling, no stacking entries: list[(object, kwargs for Contribution)] """ conts = [Contribution(e[0], **e[1]) for e in entries] logy = plots_kwargs.get('logy', False) if "logy" in plots_kwargs: del plots_kwargs['logy'] plot = Plot(conts, what="hist", **plots_kwargs) plot.plot("HISTE NOSTACK") if logy: plot.set_logy() plot.save(output_filename)
def do_response_graph(pt_bins, zpj_fits, dj_fits, title, output_filename): """Create and plot graph from fit results Parameters ---------- zpj_fits : TF1 Description dj_fits : TF1 Description output_filename : str Description """ gr_zpj = fits_to_graph(pt_bins, zpj_fits) gr_qcd = fits_to_graph(pt_bins, dj_fits) conts = [ Contribution(gr_zpj, label=qgc.DY_ZpJ_LABEL, line_color=qgc.DY_COLOUR, marker_color=qgc.DY_COLOUR, marker_style=22), Contribution(gr_qcd, label=qgc.QCD_Dijet_LABEL, line_color=qgc.QCD_COLOUR, marker_color=qgc.QCD_COLOUR, marker_style=23) ] xmin = pt_bins[0][0] xmax = pt_bins[-1][1] plot = Plot(conts, what="graph", legend=True, xlim=(xmin, xmax), title=title, xtitle="p_{T}^{GenJet} [GeV]", ytitle="Mean fitted response #pm fit error") plot.plot("ALP") plot.set_logx() line_center = ROOT.TLine(xmin, 1, xmax, 1) line_center.SetLineStyle(2) line_center.Draw("SAME") line_upper = ROOT.TLine(xmin, 1.1, xmax, 1.1) line_upper.SetLineStyle(2) line_upper.Draw("SAME") line_lower = ROOT.TLine(xmin, 0.9, xmax, 0.9) line_lower.SetLineStyle(2) line_lower.Draw("SAME") plot.save(output_filename)
def compare_PU_by_eta_bins(graphs, title, oDir, ylim=None, lowpt_zoom=True): """Plot graph contributions, with a different plot for each eta bin. Parameters ---------- graphs : list[Contribution] List of Contribution objects to be included on any one plot. title : str Title to put on plots oDir : str Output directory for plots ylim : list, optional Set y axis range lowpt_zoom : bool, optional Zoom in on low pt range """ for i, (eta_min, eta_max) in enumerate(pairwise(binning.eta_bins)): rename_dict = dict(eta_min=eta_min, eta_max=eta_max) # make a copy as we have to change the graph names new_graphs = setup_new_graphs(graphs, rename_dict) if not ylim: ylim = [0.5, 3.5] if eta_min > 2 else [0.5, 4] p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), ylim=ylim) p.plot() p.save(os.path.join(oDir, "compare_PU_eta_%g_%g.pdf" % (eta_min, eta_max))) if lowpt_zoom: # zoom in on low pT p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)", title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim) p.plot() p.save(os.path.join(oDir, "compare_PU_eta_%g_%g_pTzoomed.pdf" % (eta_min, eta_max)))
def plot_ddelta(ddelta_hist, output_filename, xtitle, ytitle, title=""): cont = Contribution(ddelta_hist) p = Plot([cont], what="hist", legend=None, xtitle=xtitle, ytitle=ytitle, title=title) p.plot("HISTE") p.save(output_filename)
def plot_unfolded_normalised_pt_bin_offset(self, bin_offset_2=0): for ibin, (bin_edge_low, bin_edge_high) in enumerate(zip(self.bins[:-1], self.bins[1:])): # print(bin_edge_low, bin_edge_high) ind2 = ibin+bin_offset_2 if ind2 < 0: # print("...skipping") continue hbc1_args = dict(ind=ibin, binning_scheme='generator') unfolded1_hist_bin_stat_errors = self.hist_bin_chopper1.get_pt_bin_normed_div_bin_width('unfolded_stat_err', **hbc1_args) hbc2_args = dict(ind=ind2, binning_scheme='generator') unfolded2_hist_bin_stat_errors = self.hist_bin_chopper2.get_pt_bin_normed_div_bin_width('unfolded_stat_err', **hbc2_args) entries = [ Contribution(unfolded1_hist_bin_stat_errors, label="Data (stat. unc.)\n%s" % self.setup1.label, line_color=self.plot_styles['unfolded_stat_colour'], line_width=self.line_width, line_style=1, marker_color=self.plot_styles['unfolded_stat_colour'], marker_style=cu.Marker.get('circle'), marker_size=0.75), Contribution(unfolded2_hist_bin_stat_errors, label="Data (stat. unc.)\n%s" % self.setup2.label, line_color=self.plot_styles['unfolded_unreg_colour'], line_width=self.line_width, line_style=1, marker_color=self.plot_styles['unfolded_unreg_colour'], marker_style=cu.Marker.get('square', filled=False), marker_size=0.75, subplot=unfolded1_hist_bin_stat_errors), ] if not self.check_entries(entries, "plot_unfolded_normalised_pt_bin_offset %d" % (ibin)): return plot = Plot(entries, ytitle=self.setup1.pt_bin_normalised_differential_label, title=self.get_pt_bin_title(bin_edge_low, bin_edge_high), xlim=qgp.calc_auto_xlim(entries), subplot_limits=(0.8, 1.2), **self.pt_bin_plot_args) self._modify_plot(plot) plot.subplot_title = "* / %s" % (self.region1['label']) plot.plot("NOSTACK E1") plot.save("%s/compare_unfolded_%s_bin_%d_divBinWidth.%s" % (self.setup1.output_dir, self.setup1.append, ibin, self.setup1.output_fmt))
def do_roc_plot(hist_signal, hist_background, output_filename): """"Make a single ROC plot""" gr = make_roc_graph(hist_signal, hist_background) cont = Contribution(gr, marker_style=21) p = Plot([cont], "graph", xtitle="#epsilon_{ g}", ytitle="#epsilon_{ q}", xlim=[0, 1], ylim=[0, 1], legend=False) p.plot("AL") p.save(output_filename)
def do_pt_transfer_plot(tdir, plot_dir): """Plot ratio between pt bins of the spectrum. Check to make sure xfer factor << drop in pt""" plot_dir = os.path.join(plot_dir, tdir.GetName()) cu.check_dir_exists_create(plot_dir) hist_name = "pt_jet_response_binning" h = cu.get_from_tfile(tdir, hist_name) binning = [ h.GetXaxis().GetBinLowEdge(bin_ind) for bin_ind in range(1, h.GetNbinsX() + 1) ] hist_factors = ROOT.TH1F( "hist_factors" + cu.get_unique_str(), ";p_{T}^{Reco} [GeV];Fraction rel to previous bin", len(binning) - 1, array('d', binning)) for bin_ind in range(2, h.GetNbinsX() + 1): cont = h.GetBinContent(bin_ind) cont_prev = h.GetBinContent(bin_ind - 1) if cont == 0 or cont_prev == 0: continue factor = cont / cont_prev hist_factors.SetBinContent(bin_ind, factor) hist_factors.SetBinError(bin_ind, 0) col_purity = ROOT.kBlack conts = [ Contribution(hist_factors, label="Factor relative to previous bin", line_color=col_purity, marker_color=col_purity), # Contribution(hist_purity, label="Purity (gen in right bin)", line_color=col_purity, marker_color=col_purity), ] xlim = [30, binning[-1]] plot = Plot(conts, what='hist', xlim=xlim) plot.plot() plot.set_logx() plot.save(os.path.join(plot_dir, 'pt_migration_factors.%s' % (OUTPUT_FMT)))
def do_roc_plot(eff_dict, output_filename): """Turn dict of efficiencies into ROC plot Parameters ---------- eff_dict : TYPE Description output_filename : TYPE Description """ signal_effs = [0] * len(eff_dict.values()[0]) bkg_effs = [0] * len(eff_dict.values()[0]) for k, v in eff_dict.iteritems(): if k.replace("Dijet_Presel_", "").lstrip("_unknown_").lstrip("_q").startswith("g"): print(k) for ind, eff in enumerate(v): signal_effs[ind] += eff else: for ind, eff in enumerate(v): bkg_effs[ind] += eff # divide by totals for ind, (s, b) in enumerate(zip(signal_effs, bkg_effs)): total = s + b signal_effs[ind] /= total bkg_effs[ind] /= total print(signal_effs) print(bkg_effs) gr = ROOT.TGraph(len(signal_effs), array('d', bkg_effs), array('d', signal_effs)) cont = Contribution(gr, marker_style=21) p = Plot([cont], "graph", xtitle="fraction jet2!=g", ytitle="fraction jet2=g", xlim=[0, 1], ylim=[0, 1], legend=False) p.plot("AP") p.save(output_filename)
def do_pt_plot(pythia_dir, herwig_dir, selection, hist_name, output_name, title=""): h_pythia = grab_obj( "%s/uhh2.AnalysisModuleRunner.MC.MC_%s_.root" % (pythia_dir, selection), hist_name) h_herwig = grab_obj( "%s/uhh2.AnalysisModuleRunner.MC.MC_%s_.root" % (herwig_dir, selection), hist_name) c_pythia = Contribution(h_pythia, label="MG+Pythia", line_color=ROOT.kBlue, marker_color=ROOT.kBlue, fill_color=ROOT.kBlue, normalise_hist=True) # c_herwig = Contribution(h_herwig, label="Herwig", line_color=ROOT.kRed, normalise_hist=True) c_herwig = Contribution(h_herwig, label="Pythia only", line_color=ROOT.kRed, marker_color=ROOT.kRed, fill_color=ROOT.kRed, normalise_hist=True) p = Plot([c_pythia, c_herwig], what="hist", legend=True, subplot_type='ratio', subplot=c_pythia, title=title) p.plot("NOSTACK HISTE") p.main_pad.SetLogy() p.container.SetMinimum(1E-12) p.subplot_container.SetMaximum(1.5) p.subplot_container.SetMinimum(0) p.canvas.Update() p.save(output_name)
def plot_corrections(corrections_graph, xtitle, title, output_filename): # print(x_values) # print(corrections) conts = [ Contribution(corrections_graph, label="Correction", line_color=ROOT.kRed, marker_color=ROOT.kRed, line_width=2, marker_size=1, marker_style=20, fit_match_style=False) ] # plot = Plot(conts, what='graph', xtitle=xtitle, ytitle="Correction", title=title, has_data=False, ylim=[0, 2.5]) plot = Plot(conts, what='both', xtitle=xtitle, ytitle="Correction", title=title, has_data=False, ylim=[0, 2.5]) plot.plot("ALP") plot.save(output_filename)
def do_deltas_plot(graph_contribs, output_filename, bin_labels, title="", xtitle=""): do_legend = len(graph_contribs) > 1 p = Plot(graph_contribs, what="graph", title=title, xtitle=xtitle, ytitle="Separation #Delta", legend=do_legend) if do_legend: p.legend.SetX1(0.7) p.legend.SetY1(0.15) p.legend.SetY2(0.35) p.plot("AP") # p.container.GetXaxis().LabelsOption("h") xax = p.container.GetXaxis() for i, lab in enumerate(bin_labels): bin_ind = xax.FindBin(i) # need this as they don't correspond at all! p.container.GetXaxis().SetBinLabel(bin_ind, lab) p.container.SetMinimum(0) p.save(output_filename)
def compare_flavour_fractions_vs_pt(input_files, dirnames, pt_bins, labels, flav, output_filename, title="", var_prepend="", which_jet="both", xtitle="p_{T}^{jet} [GeV]", n_partons='all', is_preliminary=True): """Plot a specified flavour fraction vs pT for several sources. Each entry in input_files, dirnames, and labels corresponds to one line n_partons can be a str, 'all', '1', etc, or a list of str to include TODO: fix this - bit stupid input format """ bin_centers = [0.5 * (x[0] + x[1]) for x in pt_bins] bin_widths = [0.5 * (x[1] - x[0]) for x in pt_bins] if isinstance(n_partons, str): n_partons = [n_partons] contribs = [] for n_parton_ind, n_parton in enumerate(n_partons): metric = 'pt' if n_parton.lower() != 'all': metric = 'pt_npartons_%s' % n_parton info = [ get_flavour_efficiencies( ifile, bins=pt_bins, hist_name=get_flavour_hist_name( dirname=dname, var_prepend=var_prepend, which_jet=(which_jet if "Dijet" in dname else "both"), metric=metric)) for ifile, dname in zip(input_files, dirnames) ] N = len(bin_centers) colours = [ROOT.kBlack, ROOT.kBlue, ROOT.kRed, ROOT.kGreen + 2] for i, fdict in enumerate(info): if flav in ['u', 'd', 's', 'c', 'b', 't', 'g']: obj = fdict[flav].CreateGraph() else: raise RuntimeError("Robin broke 1-X functionality") obj = ROOT.TGraphErrors( N, np.array(bin_centers), 1. - np.array(fdict[flav.replace("1-", '')]), np.array(bin_widths), np.zeros(N)) if obj.GetN() == 0: continue n_parton_str = "" if n_parton == "all" else " (%s-parton)" % n_parton c = Contribution(obj, label="%s%s" % (labels[i], n_parton_str), line_color=colours[i] + n_parton_ind, line_width=1, line_style=n_parton_ind + 1, marker_style=20 + i, marker_color=colours[i] + n_parton_ind, marker_size=1, leg_draw_opt="LP") contribs.append(c) flav_str = FLAV_STR_DICT[flav] ytitle = "Fraction of %s %ss" % (flav_str.lower(), get_jet_str('')) p = Plot(contribs, what='graph', xtitle=xtitle, ytitle=ytitle, title=title, xlim=(pt_bins[0][0], pt_bins[-1][1]), ylim=(0, 1), has_data=False, is_preliminary=is_preliminary) p.default_canvas_size = (600, 600) try: p.plot("AP") p.main_pad.SetBottomMargin(0.16) p.get_modifier().GetXaxis().SetTitleOffset(1.4) p.get_modifier().GetXaxis().SetTitleSize(.045) p.legend.SetX1(0.56) p.legend.SetY1(0.65) p.legend.SetY2(0.87) p.set_logx(do_more_labels=True, do_exponent=False) p.save(output_filename) except ZeroContributions: pass
def do_jet_pt_rel_error_with_var_cuts(histname, cuts, input_filename, output_filename): ROOT.gStyle.SetPalette(palette_1D) tf = cu.open_root_file(input_filename) h3d = cu.get_from_tfile(tf, histname) if h3d.GetEntries() == 0: return pt_hists = [] for cut in cuts: max_bin = h3d.GetZaxis().FindFixBin(cut) # print("cut:", cut, "bin:", max_bin) h = h3d.ProjectionY("pt_var_lt_%g" % cut, 0, -1, 0, max_bin, "e") h2 = h.Clone() h2.Rebin(2) if h.GetEntries() > 0: h3 = qgp.hist_divide_bin_width(h2) # convert bin contents to bin error/bin contents for ibin in range(1, h2.GetNbinsX()+1): if h3.GetBinContent(ibin) == 0: continue h3.SetBinContent(ibin, h3.GetBinError(ibin) / h3.GetBinContent(ibin)) h3.SetBinError(ibin, 0) pt_hists.append(h3) line_styles = [1, 2, 3] n_line_styles = len(line_styles) conts = [Contribution(h, label=" < %g" % cut, line_color=cu.get_colour_seq(ind, len(cuts)), line_style=line_styles[ind % n_line_styles], line_width=2, marker_color=cu.get_colour_seq(ind, len(cuts)), subplot=pt_hists[-1]) for ind, (h, cut) in enumerate(zip(pt_hists, cuts))] jet_str = pt_genjet_str if "_vs_pt_genjet_vs_" in histname else pt_str weight_str = "(unweighted)" if "unweighted" in histname else "(weighted)" ratio_lims = (0.98, 1.02) if "unweighted" in histname else None plot = Plot(conts, what='hist', title='%s for cuts on %s %s' % (jet_str, get_var_str(histname), weight_str), xtitle=None, ytitle='Relative error', # xlim=None, ylim=None, legend=True, subplot_type='ratio', subplot_title='* / var < %g' % cuts[-1], subplot_limits=ratio_lims, has_data=False) plot.y_padding_max_log = 200 plot.subplot_maximum_ceil = 2 plot.subplot_maximum_floor = 1.02 plot.subplot_minimum_ceil = 0.98 plot.legend.SetY1(0.7) plot.legend.SetY2(0.89) plot.legend.SetX1(0.78) plot.legend.SetX2(0.88) plot.plot("NOSTACK HISTE", "NOSTACK HIST") plot.set_logx(True, do_more_labels=True) plot.set_logy(True, do_more_labels=False) plot.save(output_filename)
def do_jet_pt_with_var_cuts(histname, cuts, input_filename, output_filename): ROOT.gStyle.SetPalette(palette_1D) total = len(cuts) - 1 + .1 # slight offset to not hit the maximum or minimum # if len(cuts) <= 3: # ROOT.gStyle.SetPalette(ROOT.kCool) # num_colours = ROOT.TColor.GetPalette().fN - 1 # print('num_colours:', num_colours) # for index in range(len(cuts)): # print(num_colours, index, len(cuts), index / len(cuts), num_colours * index / total) # print(index, ROOT.TColor.GetColorPalette(int(num_colours * 1. * index / total))) tf = cu.open_root_file(input_filename) h3d = cu.get_from_tfile(tf, histname) if h3d.GetEntries() == 0: return pt_hists = [] for cut in cuts: max_bin = h3d.GetZaxis().FindFixBin(cut) # print("cut:", cut, "bin:", max_bin) h = h3d.ProjectionY("pt_var_lt_%g" % cut, 0, -1, 0, max_bin, "e") h2 = h.Clone() h2.Rebin(2) if h.GetEntries() > 0: h3 = qgp.hist_divide_bin_width(h2) pt_hists.append(h3) line_styles = [1, 2, 3] if len(cuts) <= 3: line_styles = [1] n_line_styles = len(line_styles) ref_ind = 0 conts = [Contribution(h, label=" < %g" % cut, line_color=cu.get_colour_seq(ind, total), line_style=line_styles[ind % n_line_styles], line_width=2, marker_color=cu.get_colour_seq(ind, total), subplot=pt_hists[ref_ind] if ind != ref_ind else None) for ind, (h, cut) in enumerate(zip(pt_hists, cuts))] jet_str = pt_genjet_str if "_vs_pt_genjet_vs_" in histname else pt_str weight_str = "(unweighted)" if "unweighted" in histname else "(weighted)" ratio_lims = (0.5, 2.5) ratio_lims = (0.5, 1.1) plot = Plot(conts, what='hist', title='%s for cuts on %s %s' % (jet_str, get_var_str(histname), weight_str), xtitle=None, ytitle='N', # xlim=None, ylim=None, legend=True, subplot_type='ratio', subplot_title='* / var < %g' % cuts[ref_ind], subplot_limits=ratio_lims, has_data=False) plot.y_padding_max_log = 200 plot.subplot_maximum_ceil = 4 plot.subplot_maximum_floor = 1.02 plot.subplot_minimum_ceil = 0.98 plot.legend.SetY1(0.7) plot.legend.SetY2(0.89) plot.legend.SetX1(0.78) plot.legend.SetX2(0.88) plot.plot("NOSTACK HISTE", "NOSTACK HIST") plot.set_logx(True, do_more_labels=True) plot.set_logy(True, do_more_labels=False) plot.save(output_filename)
def do_component_plots(mgpythia_dir, pythia_only_dir, plot_dir): # Do 2D plots for diff ptMin folders jet_flavs = ["", "g", "q"] ptmin_vals = [50, 100, 200, 400, 800] ptmin_vals = [100, 800] # first the pt vs ones: plotnames = [ "genjet_pt_vs_constituent_pt", "genjet_pt_vs_constituent_zi", "genjet_pt_vs_constituent_deta", "genjet_pt_vs_constituent_dphi", "genjet_pt_vs_constituent_dr" ] for plotname, ptmin, renorm, logz, flav in product(plotnames, ptmin_vals, ['Y', None], [True, False], jet_flavs): rebin = [1, 1] ylim = [ptmin, 2000] dirname = "Dijet_genjet_ptMin_%d" % ptmin this_hist = os.path.join(dirname, flav + plotname) log_append = "_logZ" if logz else "" qgg.do_2D_plot( grab_obj(os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist), output_filename= "%s/constituent_plots/ptMin_%d/%s_mgpythia_norm%s%s.%s" % (plot_dir, ptmin, flav + plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="MG+Pythia", rebin=rebin, recolour=True, ylim=ylim, logz=logz) qgg.do_2D_plot( grab_obj(os.path.join(pythia_only_dir, qgc.QCD_FILENAME), this_hist), output_filename= "%s/constituent_plots/ptMin_%d/%s_pythiaOnly_norm%s%s.%s" % (plot_dir, ptmin, flav + plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="Pythia only", rebin=rebin, recolour=True, ylim=ylim, logz=logz) # Now LHA vs X ones plotnames = ["genjet_LHA_vs_zi", "genjet_LHA_vs_thetai"] for plotname, ptmin, renorm, logz, flav in product(plotnames, ptmin_vals, ['X', 'Y', None], [True, False], jet_flavs): rebin = [4, 4] xlim = [0, 0.5] if ("zi" in plotname and renorm != "X") else None ylim = None dirname = "Dijet_genjet_ptMin_%d" % ptmin this_hist = os.path.join(dirname, flav + plotname) log_append = "_logZ" if logz else "" qgg.do_2D_plot( grab_obj(os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist), output_filename= "%s/constituent_plots/ptMin_%d/%s_mgpythia_norm%s%s.%s" % (plot_dir, ptmin, flav + plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="MG+Pythia, %s-jet, ptMin = %d GeV" % (flav, ptmin), rebin=rebin, recolour=True, xlim=xlim, ylim=ylim, logz=logz) qgg.do_2D_plot( grab_obj(os.path.join(pythia_only_dir, qgc.QCD_FILENAME), this_hist), output_filename= "%s/constituent_plots/ptMin_%d/%s_pythiaOnly_norm%s%s.%s" % (plot_dir, ptmin, flav + plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="Pythia only, %s-jet, ptMin = %d GeV" % (flav, ptmin), rebin=rebin, recolour=True, xlim=xlim, ylim=ylim, logz=logz) def do_2D_plot_with_contours(obj, contour_obj, output_filename, renorm_axis=None, title=None, rebin=None, recolour=True, xlim=None, ylim=None, logx=False, logy=False, logz=False): """Like normal 2D plotter but contour_obj will be plotted using contours""" if rebin: obj.Rebin2D(*rebin) if renorm_axis: obj_renorm = cu.make_normalised_TH2(obj, renorm_axis, recolour) else: obj_renorm = obj if title: obj_renorm.SetTitle(title) canvas = ROOT.TCanvas(ROOT.TUUID().AsString(), "", 800, 800) canvas.SetTicks(1, 1) canvas.SetLeftMargin(0.13) canvas.SetBottomMargin(0.11) if logx: canvas.SetLogx(1) if logy: canvas.SetLogy(1) if logz: canvas.SetLogz(1) obj_renorm.Draw("COLZ") if xlim is not None: obj_renorm.GetXaxis().SetRangeUser(*xlim) if ylim is not None: obj_renorm.GetYaxis().SetRangeUser(*ylim) obj_renorm.GetYaxis().SetTitleOffset(1.7) obj_renorm.GetXaxis().SetTitleOffset(1.2) if contour_obj: contour_obj.Draw("CONT3 SAME") output_filename = os.path.abspath(output_filename) odir = os.path.dirname(output_filename) if not os.path.isdir(odir): os.makedirs(odir) canvas.SaveAs(output_filename) # Do 2D plots for premade jet pt cut objs jet_pt_vals = [(100, 200), (800, 1000)] for (jet_pt_min, jet_pt_max), renorm, logz in product(jet_pt_vals, ['X', 'Y', None][2:], [True, False]): rebin = [1, 1] xlim = [0, 1] ylim = [0, 0.05] dirname = "Dijet_genjet" jet_type = "g" plotname = jet_type + "genjet_constituent_zi_vs_constituent_thetai_pt%dto%d" % ( jet_pt_min, jet_pt_max) this_hist = os.path.join(dirname, plotname) log_append = "_logZ" if logz else "" contour_hist = grab_obj(os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist).Clone("contours") for xbin in range(1, contour_hist.GetNbinsX() + 1): for ybin in range(1, contour_hist.GetNbinsY() + 1): xval = 0.5 * (contour_hist.GetXaxis().GetBinCenter(xbin) + contour_hist.GetXaxis().GetBinCenter(xbin + 1)) yval = 0.5 * (contour_hist.GetYaxis().GetBinCenter(ybin) + contour_hist.GetYaxis().GetBinCenter(ybin + 1)) contour_hist.SetBinContent(xbin, ybin, math.sqrt(xval / 0.4) * yval) levels = array('d', [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5]) contour_hist.SetContour(len(levels), levels) contour_hist.SetLineColor(ROOT.kRed) do_2D_plot_with_contours( grab_obj(os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist), contour_hist, output_filename="%s/constituent_plots/%s_mgpythia_norm%s%s.%s" % (plot_dir, plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="MG+Pythia, %d < p_{T}^{j} < %d GeV" % (jet_pt_min, jet_pt_max), rebin=rebin, recolour=True, xlim=xlim, ylim=ylim, logz=logz) do_2D_plot_with_contours( grab_obj(os.path.join(pythia_only_dir, qgc.QCD_FILENAME), this_hist), contour_hist, output_filename="%s/constituent_plots/%s_pythiaOnly_norm%s%s.%s" % (plot_dir, plotname, renorm, log_append, OUTPUT_FMT), renorm_axis=renorm, title="Pythia only, %d < p_{T}^{j} < %d GeV" % (jet_pt_min, jet_pt_max), rebin=rebin, recolour=True, xlim=xlim, ylim=ylim, logz=logz) # Do 1D projection plots for (jet_pt_min, jet_pt_max) in jet_pt_vals: lw = 2 dirname = "Dijet_genjet" jet_type = "g" plotname = jet_type + "genjet_constituent_zi_vs_constituent_thetai_pt%dto%d" % ( jet_pt_min, jet_pt_max) this_hist = os.path.join(dirname, plotname) # Do projection plots for various zi bins cut_zi_bins = [(0, 0.001), (0, 0.005), (0, 0.01), (0, 0.05), (0.05, 0.1), (0, 0.1), (0.1, 0.2), (0.3, 0.4), (0.4, 0.5), (0.8, 1.0), (0, 1)] for i, (start_val, end_val) in enumerate(cut_zi_bins): entries_normal = [] h2d_mgpythia = grab_obj( os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist) mgpythia_kwargs = dict(line_color=qgc.QCD_COLOUR, fill_color=qgc.QCD_COLOUR, label="MG+Pythia", line_width=lw) entries_normal.append( (qgg.get_projection_plot(h2d_mgpythia, start_val, end_val, 'y'), mgpythia_kwargs)) h2d_pythiaonly = grab_obj( os.path.join(pythia_only_dir, qgc.QCD_FILENAME), this_hist) pythiaonly_kwargs = dict(line_color=ROOT.kRed, fill_color=ROOT.kRed, label="Pythia only", line_width=lw) entries_normal.append( (qgg.get_projection_plot(h2d_pythiaonly, start_val, end_val, 'y'), pythiaonly_kwargs)) ofilename = jet_type + "genjet_constituent_thetai_binned_zi%gto%g_jetPt%dto%d" % ( start_val, end_val, jet_pt_min, jet_pt_max) rebin = 5 if end_val <= 0.1 else 2 xlim = None if end_val <= 0.1 else [0, 0.6] if end_val >= 1: rebin = 4 xlim = [0, 1.2] qgg.do_comparison_plot( entries_normal, "%s/constituent_plots/%s.%s" % (plot_dir, ofilename, OUTPUT_FMT), rebin=rebin, title="%g < z_{i} < %g, %d < p_{T}^{jet} < %d GeV" % (start_val, end_val, jet_pt_min, jet_pt_max), xtitle="#theta_{i}", xlim=xlim, ylim=None, subplot_type="ratio", subplot_title="#splitline{Ratio wrt}{MG+Pythia}") # Do projections hists for various theta_i bins cut_thetai_bins = [(0, 0.01), (0.01, 0.02), (0.02, 0.05), (0.05, 0.10), (0.1, 0.15), (0.15, 0.2), (0.2, 0.3), (0.3, 0.4), (0.4, 0.6), (0.6, 0.8), (0.8, 1), (1, 1.5), (0, 2)][-1:] deltas = [] delta_components = [] colours = [ ROOT.kBlue, ROOT.kRed, ROOT.kGreen + 2, ROOT.kOrange - 3, ROOT.kMagenta, ROOT.kAzure + 1 ] for i, (start_val, end_val) in enumerate(cut_thetai_bins[::]): entries_normal = [] h2d_mgpythia = grab_obj( os.path.join(mgpythia_dir, qgc.QCD_FILENAME), this_hist) mgpythia_kwargs = dict(line_color=qgc.QCD_COLOUR, fill_color=qgc.QCD_COLOUR, label="MG+Pythia", line_width=lw) h_mgpythia = qgg.get_projection_plot(h2d_mgpythia, start_val, end_val, 'x') h_mgpythia.Rebin(4) entries_normal.append( (h_mgpythia.Clone(ROOT.TUUID().AsString()), mgpythia_kwargs)) h2d_pythiaonly = grab_obj( os.path.join(pythia_only_dir, qgc.QCD_FILENAME), this_hist) pythiaonly_kwargs = dict(line_color=ROOT.kRed, fill_color=ROOT.kRed, label="Pythia only", line_width=lw) h_pythiaonly = qgg.get_projection_plot(h2d_pythiaonly, start_val, end_val, 'x') h_pythiaonly.Rebin(4) entries_normal.append((h_pythiaonly.Clone(ROOT.TUUID().AsString()), pythiaonly_kwargs)) # rebin = 5 if end_val <= 0.1 else 2 rebin = None xlim = [0, 0.5] if end_val <= 0.1 else [0, 0.2] if end_val == 2: xlim = [0, 0.2] ofilename = jet_type + "genjet_constituent_zi_binned_thetai%gto%g_jetPt%dto%d" % ( start_val, end_val, jet_pt_min, jet_pt_max) qgg.do_comparison_plot( entries_normal, "%s/constituent_plots/%s.%s" % (plot_dir, ofilename, OUTPUT_FMT), rebin=rebin, title="%g < #theta_{i} < %g, %d < p_{T}^{jet} < %d GeV" % (start_val, end_val, jet_pt_min, jet_pt_max), xtitle="z_{i}", xlim=xlim, subplot_type="ratio", subplot_title="#splitline{Ratio wrt}{MG+Pythia}") ddelta_hist = qgd.get_ddelta_plot(h_mgpythia, h_pythiaonly) this_colour = colours[i % len(colours)] line_style = 1 + i // len(colours) c = Contribution(ddelta_hist, label="%g-%g" % (start_val, end_val), line_width=1, line_style=line_style, marker_color=this_colour, line_color=this_colour, fill_color=this_colour) delta_components.append(c) deltas.append(qgd.calculate_delta(ddelta_hist)) p = Plot(delta_components, what="hist", ytitle="p.d.f", xlim=[0, 0.2], title="%d < p_{T}^{jet} < %d GeV" % (jet_pt_min, jet_pt_max)) p.plot("NOSTACK HISTE") p.save("%s/constituent_plots/ddelta_thetai_jetPt%dto%d.%s" % (plot_dir, jet_pt_min, jet_pt_max, OUTPUT_FMT)) gr = qgd.construct_deltas_graph(deltas[::]) c = Contribution(gr, label="BLAH", marker_style=0) graph_contribs = [] graph_contribs.append(c) bin_labels = ["{:g} - {:g}".format(*b) for b in cut_thetai_bins] qgd.do_deltas_plot(graph_contribs, "%s/constituent_plots/delta_thetai_jetPt%dto%d.%s" % (plot_dir, jet_pt_min, jet_pt_max, OUTPUT_FMT), bin_labels=bin_labels, title="%d < p_{T}^{jet} < %d GeV" % (jet_pt_min, jet_pt_max), xtitle="#theta_{i}")
def do_1D_plot(hists, output_filename, components_styles_dicts=None, draw_opts="NOSTACK HISTE", do_ratio=True, logx=False, logy=False, normalise_hists=True, title=""): if (len(hists) != len(components_styles_dicts)): raise RuntimeError("# hists != # components_styles_dicts (%d vs %d)" % (len(hists), len(components_styles_dicts))) hists = [h.Clone(h.GetName() + str(uuid1())) for h in hists] contributions = [ Contribution(hist, normalise_hist=normalise_hists, **csd) for hist, csd in zip(hists, components_styles_dicts) ] if len(contributions) == 0: return # Ignore if all empty objs total_entries = sum(c.obj.GetEntries() for c in contributions) if total_entries == 0: print("WARNING: all plots have 0 entries") return min_val = min([h.GetMinimum(0) for h in hists]) max_val = max([h.GetMaximum() for h in hists]) # print("Auto y limits:", min_val, max_val) if logy: ylim = [0.5 * min_val, 50 * max_val] else: # ylim = [0.5*min_val, 1.5*max_val] ylim = [0, 1.5 * max_val] # Auto calc x limits to avoid lots of empty bins high_bin = max([find_largest_filled_bin(h)[0] for h in hists]) low_bin = min([find_first_filled_bin(h)[0] for h in hists]) xlim = [ hists[0].GetBinLowEdge(low_bin - 1), hists[0].GetBinLowEdge(high_bin + 2) ] p = Plot( contributions, what='hist', ytitle="p.d.f." if normalise_hists else "N", title=title, xlim=xlim, ylim=ylim, subplot_type="ratio" if do_ratio else None, subplot_title="Herwig / PY8", subplot=contributions[0], subplot_limits=(0.5, 1.5), ) # p.legend.SetX1(0.55) # # p.legend.SetX2(0.95) # p.legend.SetY1(0.7) # p.legend.SetY2(0.85) p.legend.SetX1(0.5) p.legend.SetX2(0.97) if len(contributions) > 4: p.legend.SetY1(0.6) else: p.legend.SetY1(0.7) p.legend.SetY2(0.9) p.plot(draw_opts) if logy: p.set_logy() if logx: p.set_logx() p.save(output_filename)
def do_pt_min_delta_plots(sources, plot_dir="deltas_ptmin", zpj_dirname="ZPlusJets_QG", dj_dirname="Dijet_QG", var_list=None, var_prepend="", flavour_tag=False, save_component_hists=False, ofmt="pdf"): """Do plots comparing power of different ptMin cuts""" var_list = var_list or COMMON_VARS ptmin_bins = [50, 100, 200, 400, 800][:-1] zpj_flav = "q" if flavour_tag else "" dj_flav = "g" if flavour_tag else "" output_append = "_flavMatched" if flavour_tag else "" for ang in var_list: v = "%s%s_vs_pt" % (var_prepend, ang.var) graph_contribs, bin_labels = [], [] for source_ind, source in enumerate(sources): deltas, components = [], [] # for the component comparison plot colours = [ ROOT.kBlue, ROOT.kRed, ROOT.kGreen + 2, ROOT.kOrange - 3, ROOT.kMagenta, ROOT.kAzure + 1 ] for pt_min, this_colour in zip(ptmin_bins, colours): h2d_dyj = grab_obj( os.path.join(source['root_dir'], qgc.DY_FILENAME), "%s_ptMin_%d/%s%s" % (source.get( 'zpj_dirname', zpj_dirname), pt_min, zpj_flav, v)) h2d_qcd = grab_obj( os.path.join(source['root_dir'], qgc.QCD_FILENAME), "%s_ptMin_%d/%s%s" % (source.get('dj_dirname', dj_dirname), pt_min, dj_flav, v)) start_val, end_val = 80, 2000 h_dy = get_projection_plot(h2d_dyj, start_val, end_val) if (h_dy.Integral() > 0): h_dy.Scale(1. / (h_dy.GetBinWidth(1) * h_dy.Integral())) h_qcd = get_projection_plot(h2d_qcd, start_val, end_val) if (h_qcd.Integral() > 0): h_qcd.Scale(1. / (h_qcd.GetBinWidth(1) * h_qcd.Integral())) ddelta_hist = get_ddelta_plot(h_dy, h_qcd) c = Contribution(ddelta_hist, line_width=1, marker_color=this_colour, line_color=this_colour, fill_color=this_colour, label="p_{T}^{Min} = %d GeV" % pt_min, rebin_hist=1) components.append(c) deltas.append(calculate_delta(ddelta_hist)) if source_ind == 0: bin_labels.append("%d" % pt_min) if save_component_hists: # need to clone here otherwise the colour will be set inside # plot_delta, which in turn will nullify whatever colours we chose above. plot_ddelta( ddelta_hist.Clone(ROOT.TUUID().AsString()), "%s/delta_ptmin_components/%s_ddelta_ptMin_%d%s.%s" % (plot_dir, ang.var, pt_min, output_append, ofmt), xtitle=ang.name + " (" + ang.lambda_str + ")", ytitle="d#Delta/d" + ang.lambda_str) if save_component_hists: # plot all differential distributions for this pt bin on one plot p = Plot(components, what="hist", xtitle=ang.name, ytitle="p.d.f") p.plot("NOSTACK HISTE") p.save( "%s/delta_ptmin_components/%s_ddelta_ptMin_comparison%s.%s" % (plot_dir, ang.var, output_append, ofmt)) gr = construct_deltas_graph(deltas) gr.SetName(source.get("label", "")) if 'style' in source and 'line_width' not in source['style']: source['style']['line_width'] = 2 c = Contribution(gr, label=source.get("label", "").lstrip(", "), marker_style=0, **source.get("style", {})) graph_contribs.append(c) do_deltas_plot(graph_contribs, "%s/ptMins_%s%s.%s" % (plot_dir, ang.var, output_append, ofmt), bin_labels=bin_labels, title="%s [%s]" % (ang.name, ang.lambda_str), xtitle="p_{T}^{min} [GeV]")
def make_plot(entries, output_filename, plot_kwargs, projection_axis='x', start_val=None, end_val=None, is_pdgid_plot=False, logy=False): """Make a plot from entries. Each one is a projection of a 2D plot. Parameters ---------- entries : list[dict] List of plot entries. Each is represented by a dict output_filename : str Filename for output plot plot_kwargs : dict kwargs for Plot constructor projection_axis : str, optional Axis to use for projection. If None, must be specified in entry. start_val : None, optional If set, use this to make 1D projection plot. Cuts on X axis. Otherwise should be set per entry. end_val : None, optional If set, use this to make 1D projection plot. Cuts on X axis. Otherwise should be set per entry. is_pdgid_plot : bool, optional True if for PDGIDs (sets special size & binning) logy : bool, optional Description Raises ------ RuntimeError Description """ conts = [] if not is_pdgid_plot: for ent in entries: h2d = cu.get_from_tfile( ent['file'], "ak4pfchsl1/" + ent['histname'] + "_JetEta0to0.783") start_val = ent.get('start_val', start_val) end_val = ent.get('end_val', end_val) if start_val is None or end_val is None: raise RuntimeError("Expected start_val and end_val") hist = cu.get_projection_plot( h2d, start_val, end_val, ent.get('projection_axis', projection_axis)) if hist.GetEntries() == 0: ent['used'] = False continue contrib = Contribution(hist, label=ent['label'], line_width=lw, line_color=ent['colour'], line_style=ent.get('line_style', 1), marker_size=ent.get('marker_size', 0), marker_color=ent['colour'], marker_style=ent.get('marker_style', 1), normalise_hist=True, rebin_hist=ent.get('rebin', None)) conts.append(contrib) ent['used'] = True else: # For PDGID plots, we want a different canvas aspect ratio, and only to include bins # with non-0 contents. We also relabel bins. custom_bins = [] for ent in entries: h2d = cu.get_from_tfile( ent['file'], "ak4pfchsl1/" + ent['histname'] + "_JetEta0to0.783") start_val = ent.get('start_val', start_val) end_val = ent.get('end_val', end_val) if not start_val or not end_val: raise RuntimeError("Expected start_val and end_val") hist = cu.get_projection_plot( h2d, start_val, end_val, ent.get('projection_axis', projection_axis)) ax = hist.GetXaxis() bins = dict() for i in range(1, hist.GetNbinsX() + 1): value = ax.GetBinLowEdge(i) cont = hist.GetBinContent(i) err = hist.GetBinError(i) if cont > 0: bins[value] = [cont, err] # print(custom_bins[-1]) custom_bins.append(bins) nbins = max([len(d) for d in custom_bins]) first_keys = set(custom_bins[0].keys()) for cb in custom_bins[1:]: first_keys = first_keys.union(set(cb.keys())) all_keys = sorted(list(first_keys)) print(all_keys) for cbin, ent in zip(custom_bins, entries): h = ROOT.TH1D(cu.get_unique_str(), ";PDGID;N", nbins, 0, nbins) for ind, k in enumerate(all_keys, 1): content, error = cbin.get(k, [0, 0]) h.SetBinContent(ind, content) h.SetBinError(ind, error) ax = h.GetXaxis() for i in range(1, nbins + 1): # ax.SetBinLabel(i, str(int(all_keys[i-1]))) pdgid = int(all_keys[i - 1]) ax.SetBinLabel(i, PDGID_STR.get(pdgid, str(pdgid))) h.LabelsOption("v") contrib = Contribution(h, label=ent['label'], line_width=lw, line_color=ent['colour'], line_style=ent.get('line_style', 1), marker_size=ent.get('marker_size', 0), marker_color=ent['colour'], marker_style=ent.get('marker_style', 1), normalise_hist=True, rebin_hist=ent.get('rebin', None)) conts.append(contrib) ent['used'] = True entries = [e for e in entries if e['used']] for ind, ent in enumerate(entries): if not ent['used']: continue if ent.get('subplot_ind', -1) >= 0: conts[ind].subplot = conts[ent['subplot_ind']].obj plot = Plot(conts, what="hist", ytitle="p.d.f.", has_data=False, **plot_kwargs) if is_pdgid_plot and conts[0].obj.GetNbinsX() > 10: plot.default_canvas_size = (800, 800) else: plot.default_canvas_size = (450, 600) plot.legend.SetX1(0.5) plot.legend.SetX2(0.97) if len(entries) > 4: plot.legend.SetY1(0.7) plot.legend.SetNColumns(2) else: plot.legend.SetY1(0.75) plot.legend.SetY2(0.9) plot.plot("HISTE NOSTACK") if logy: plot.set_logy() plot.save(output_filename)
def do_angularity_delta_plots(sources, plot_dir="delta_angularities", zpj_dirname="ZPlusJets_QG", dj_dirname="Dijet_QG", var_list=None, var_prepend="", pt_bins=None, flavour_tag=False, save_component_hists=False, ofmt="pdf"): """Do plots comparing power of different angularities""" var_list = var_list or COMMON_VARS pt_bins = pt_bins or PT_BINS h2d_dyj = None h2d_qcd = None zpj_flav = "q" if flavour_tag else "" dj_flav = "g" if flavour_tag else "" output_append = "_flavMatched" if flavour_tag else "" for (start_val, end_val) in pt_bins: graph_contribs, bin_labels = [], [] for source_ind, source in enumerate(sources): deltas, components = [], [] # construct a graph of angularities for this source for ang in var_list: v = "%s%s_vs_pt" % (var_prepend, ang.var) h2d_dyj = grab_obj( os.path.join(source['root_dir'], qgc.DY_FILENAME), "%s/%s%s" % (source.get('zpj_dirname', zpj_dirname), zpj_flav, v)) h2d_qcd = grab_obj( os.path.join(source['root_dir'], qgc.QCD_FILENAME), "%s/%s%s" % (source.get('dj_dirname', dj_dirname), dj_flav, v)) h_dy = get_projection_plot(h2d_dyj, start_val, end_val) if (h_dy.Integral() > 0): h_dy.Scale(1. / (h_dy.GetBinWidth(1) * h_dy.Integral())) h_qcd = get_projection_plot(h2d_qcd, start_val, end_val) if (h_qcd.Integral() > 0): h_qcd.Scale(1. / (h_qcd.GetBinWidth(1) * h_qcd.Integral())) ddelta_hist = get_ddelta_plot(h_dy, h_qcd) deltas.append(calculate_delta(ddelta_hist)) if source_ind == 0: bin_labels.append("#splitline{%s}{%s}" % (ang.name, ang.lambda_str)) if save_component_hists: plot_ddelta( ddelta_hist.Clone(ddelta_hist.GetName() + "x"), "%s/delta_angularities_components/angularities_pt%dto%d_ddelta_%s_source%d%s.%s" % (plot_dir, start_val, end_val, ang.var, source_ind, output_append, ofmt), xtitle=ang.name + " (" + ang.lambda_str + ")", ytitle="d#Delta/d" + ang.lambda_str) if ang.var != "jet_multiplicity": c = Contribution(ddelta_hist, line_width=1, marker_color=ang.colour, line_color=ang.colour, fill_color=ang.colour, label=ang.name + " (" + ang.lambda_str + ")", rebin_hist=1) components.append(c) if save_component_hists: # plot all differential distributions for this pt bin on one plot p = Plot(components, what="hist", xtitle="#lambda^{#kappa}_{#beta}", ytitle="d#Delta/d#lambda", title="%d < p_{T}^{jet} < %d GeV" % (start_val, end_val)) p.plot("NOSTACK HISTE") prefix = "pt%dto%d" % (start_val, end_val) p.save( "%s/delta_angularities_components/%s_ddelta_angularity_comparison_source%d%s.%s" % (plot_dir, prefix, source_ind, output_append, ofmt)) gr = construct_deltas_graph(deltas) gr.SetName(source.get("label", "")) if 'style' in source and 'line_width' not in source['style']: source['style']['line_width'] = 2 c = Contribution(gr, label=source.get("label", "").lstrip(", "), marker_style=0, **source.get("style", {})) graph_contribs.append(c) do_deltas_plot(graph_contribs, "%s/angularities_pt%dto%d%s.%s" % (plot_dir, start_val, end_val, output_append, ofmt), bin_labels=bin_labels, title="%d < p_{T}^{jet} < %d GeV" % (start_val, end_val), xtitle="Angularity: (#kappa, #beta)")
def compare_flavour_fraction_hists_vs_pt_from_contribs( contribs, flav, output_filename, title="", xtitle="p_{T}^{jet} [GeV]", **plot_kwargs): """Plot a specified flavour fraction vs pT for several sources. TODO: use this one more often - compare_flavour_fractions_vs_pt() is almost identical but has to deal with npartons """ flav_str = FLAV_STR_DICT[flav] ytitle = "Fraction of %s %ss" % (flav_str.lower(), get_jet_str('')) p = Plot(contribs, what='graph', xtitle=xtitle, ytitle=ytitle, title=title, xlim=(50, 2000), ylim=(0, 1), has_data=False, **plot_kwargs) p.default_canvas_size = (600, 600) try: p.plot("AP") p.main_pad.SetBottomMargin(0.16) p.get_modifier().GetXaxis().SetTitleOffset(1.4) p.get_modifier().GetXaxis().SetTitleSize(.045) p.legend.SetX1(0.56) p.legend.SetY1(0.65) p.legend.SetY2(0.87) if len(contribs) >= 4: p.legend.SetY1(0.7) p.legend.SetX1(0.5) p.legend.SetNColumns(2) p.set_logx(do_more_labels=True, do_exponent=False) p.save(output_filename) except ZeroContributions: warnings.warn("No contributions for %s" % output_filename)
def do_flavour_fraction_vs_pt(input_file, hist_name, pt_bins, output_filename, title=""): """Plot all flavour fractions vs PT for one input file & hist_name in the ROOT file""" info = get_flavour_efficiencies(input_file, bins=pt_bins, hist_name=hist_name) leg_draw_opt = "LP" plot_u = Contribution(info['u'].CreateGraph(), label="Up", line_color=ROOT.kRed, marker_color=ROOT.kRed, marker_style=20, leg_draw_opt=leg_draw_opt) plot_d = Contribution(info['d'].CreateGraph(), label="Down", line_color=ROOT.kBlue, marker_color=ROOT.kBlue, marker_style=21, leg_draw_opt=leg_draw_opt) plot_s = Contribution(info['s'].CreateGraph(), label="Strange", line_color=ROOT.kBlack, marker_color=ROOT.kBlack, marker_style=22, leg_draw_opt=leg_draw_opt) plot_c = Contribution(info['c'].CreateGraph(), label="Charm", line_color=ROOT.kGreen + 2, marker_color=ROOT.kGreen + 2, marker_style=23, leg_draw_opt=leg_draw_opt) plot_b = Contribution(info['b'].CreateGraph(), label="Bottom", line_color=ROOT.kOrange - 3, marker_color=ROOT.kOrange - 3, marker_style=33, leg_draw_opt=leg_draw_opt) plot_g = Contribution(info['g'].CreateGraph(), label="Gluon", line_color=ROOT.kViolet, marker_color=ROOT.kViolet, marker_style=29, leg_draw_opt=leg_draw_opt) plot_unknown = Contribution(info['unknown'].CreateGraph(), label="Unknown", line_color=ROOT.kGray + 1, marker_color=ROOT.kGray + 1, marker_style=26, leg_draw_opt=leg_draw_opt) p_flav = Plot( [plot_d, plot_u, plot_s, plot_c, plot_b, plot_g, plot_unknown], what='graph', xtitle="p_{T}^{%s} [GeV]" % get_jet_str(''), ytitle="Fraction", title=title, xlim=(pt_bins[0][0], pt_bins[-1][1]), ylim=[0, 1], has_data=False) p_flav.default_canvas_size = (600, 600) p_flav.plot("AP") p_flav.main_pad.SetBottomMargin(0.16) p_flav.get_modifier().GetXaxis().SetTitleOffset(1.4) p_flav.get_modifier().GetXaxis().SetTitleSize(.045) p_flav.set_logx(do_more_labels=True, do_exponent=False) p_flav.legend.SetX1(0.55) p_flav.legend.SetY1(0.72) p_flav.legend.SetY2(0.85) p_flav.legend.SetNColumns(2) p_flav.save(output_filename)
def compare_flavour_fraction_hists_vs_pt(input_files, hist_names, pt_bins, labels, flav, output_filename, title="", xtitle="p_{T}^{jet} [GeV]", is_preliminary=True): """Plot a specified flavour fraction vs pT for several sources. Each entry in input_files, dirnames, and labels corresponds to one line n_partons can be a str, 'all', '1', etc, or a list of str to include TODO: use this one more often - compare_flavour_fractions_vs_pt() is almost identical but has to deal with npartons """ bin_centers = [0.5 * (x[0] + x[1]) for x in pt_bins] bin_widths = [0.5 * (x[1] - x[0]) for x in pt_bins] contribs = [] info = [ get_flavour_efficiencies(ifile, bins=pt_bins, hist_name=hname) for ifile, hname in zip(input_files, hist_names) ] N = len(bin_centers) colours = [ROOT.kBlack, ROOT.kBlue, ROOT.kRed, ROOT.kGreen + 2] for i, fdict in enumerate(info): if flav in ['u', 'd', 's', 'c', 'b', 't', 'g']: obj = fdict[flav].CreateGraph() else: raise RuntimeError("Robin broke 1-X functionality") obj = ROOT.TGraphErrors( N, np.array(bin_centers), 1. - np.array(fdict[flav.replace("1-", '')]), np.array(bin_widths), np.zeros(N)) if obj.GetN() == 0: continue c = Contribution(obj, label=labels[i], line_color=colours[i], line_width=1, line_style=1, marker_style=20 + i, marker_color=colours[i], marker_size=1, leg_draw_opt="LP") contribs.append(c) flav_str = FLAV_STR_DICT[flav] ytitle = "Fraction of %s %ss" % (flav_str.lower(), get_jet_str('')) p = Plot(contribs, what='graph', xtitle=xtitle, ytitle=ytitle, title=title, xlim=(50, 2000), ylim=(0, 1), has_data=False, is_preliminary=is_preliminary) p.default_canvas_size = (600, 600) try: p.plot("AP") p.main_pad.SetBottomMargin(0.16) p.get_modifier().GetXaxis().SetTitleOffset(1.4) p.get_modifier().GetXaxis().SetTitleSize(.045) p.legend.SetX1(0.56) p.legend.SetY1(0.65) p.legend.SetY2(0.87) p.set_logx(do_more_labels=True, do_exponent=False) p.save(output_filename) except ZeroContributions: pass
def do_response_plot(tdir, plot_dir, var_name, xlabel, log_var=False, rebinx=1, rebiny=1, do_migration_summary_plots=True, do_resolution_plots=True, save_response_hists=False): """Do 2D plots of genjet pt vs recojet pt""" h2d_orig = cu.get_from_tfile(tdir, var_name) h2d = h2d_orig.Clone(cu.get_unique_str()) h2d.RebinX(rebinx) h2d.RebinY(rebiny) pt_regions = [ { "append": "_lowPt", "title": "30 < p_{T}^{Reco} < 100 GeV", }, { "append": "_midPt", "title": "100 < p_{T}^{Reco} < 250 GeV", }, { "append": "_highPt", "title": "p_{T}^{Reco} > 250 GeV", }, ] pt_bin_name = "" for region in pt_regions: if region['append'] in var_name: pt_bin_name = region['title'] title = "%s;%s (GEN);%s (RECO)" % (pt_bin_name, xlabel, xlabel) # title = pt_bin_name canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600) draw_opt = "COLZ TEXT" draw_opt = "COLZ" pad = ROOT.gPad pad.SetBottomMargin(0.12) pad.SetLeftMargin(0.13) pad.SetRightMargin(0.12) canv.SetTicks(1, 1) if log_var: canv.SetLogx() canv.SetLogy() # un normalised h2d.SetTitle(title) h2d.Draw(draw_opt) xax = h2d.GetXaxis() upper_lim = xax.GetBinUpEdge(xax.GetLast()) # print(upper_lim) # upper_lim = 5000 title_offset = 1.5 h2d.SetTitleOffset(title_offset, 'X') xax.SetMoreLogLabels() yax = h2d.GetYaxis() h2d.SetTitleOffset(title_offset * 1.15, 'Y') yax.SetMoreLogLabels() canv.Update() plot_dir = os.path.join(plot_dir, tdir.GetName()) cu.check_dir_exists_create(plot_dir) canv.SaveAs(os.path.join(plot_dir, "%s_linZ.%s" % (var_name, OUTPUT_FMT))) canv.SetLogz() canv.SaveAs(os.path.join(plot_dir, "%s_logZ.%s" % (var_name, OUTPUT_FMT))) # renorm by row (reco bins) canv.SetLogz(0) h2d_renorm_y = cu.make_normalised_TH2(h2d, 'Y', recolour=True, do_errors=True) h2d_renorm_y.SetMarkerSize(0.5) h2d_renorm_y.SetMaximum(1) h2d_renorm_y.Draw(draw_opt) xax = h2d_renorm_y.GetXaxis() upper_lim = xax.GetBinUpEdge(xax.GetLast()) # print(upper_lim) # upper_lim = 5000 title_offset = 1.5 h2d_renorm_y.SetTitleOffset(title_offset, 'X') # xax.SetRangeUser(0, upper_lim) xax.SetMoreLogLabels() yax = h2d_renorm_y.GetYaxis() h2d_renorm_y.SetTitleOffset(title_offset * 1.15, 'Y') # yax.SetRangeUser(0, upper_lim) yax.SetMoreLogLabels() canv.Update() canv.SaveAs( os.path.join(plot_dir, "%s_renormY_linZ.%s" % (var_name, OUTPUT_FMT))) canv.SetLogz() h2d_renorm_y.SetMaximum(1) h2d_renorm_y.SetMinimum(1E-3) canv.SaveAs( os.path.join(plot_dir, "%s_renormY_logZ.%s" % (var_name, OUTPUT_FMT))) # renorm by column (gen bins) canv.Clear() canv.SetLogz(0) h2d_renorm_x = cu.make_normalised_TH2(h2d, 'X', recolour=True, do_errors=True) h2d_renorm_x.SetMarkerSize(0.5) h2d_renorm_x.SetMaximum(1) h2d_renorm_x.Draw(draw_opt) xax = h2d_renorm_x.GetXaxis() upper_lim = xax.GetBinUpEdge(xax.GetLast()) # upper_lim = 5000 title_offset = 1.5 h2d_renorm_x.SetTitleOffset(title_offset, 'X') # xax.SetRangeUser(0, upper_lim) xax.SetMoreLogLabels() yax = h2d_renorm_x.GetYaxis() h2d_renorm_x.SetTitleOffset(title_offset * 1.15, 'Y') # yax.SetRangeUser(0, upper_lim) yax.SetMoreLogLabels() canv.Update() canv.SaveAs( os.path.join(plot_dir, "%s_renormX_linZ.%s" % (var_name, OUTPUT_FMT))) canv.SetLogz() h2d_renorm_x.SetMaximum(1) h2d_renorm_x.SetMinimum(1E-3) canv.SaveAs( os.path.join(plot_dir, "%s_renormX_logZ.%s" % (var_name, OUTPUT_FMT))) # Now do plot of purity, etc if do_migration_summary_plots: qgg.make_migration_summary_plot( h2d_renorm_x, h2d_renorm_y, xlabel=xlabel, output_filename=os.path.join( plot_dir, '%s_migration_summary.%s' % (var_name, OUTPUT_FMT)), log_var=log_var) # Do resolution plots if do_resolution_plots: res_rms, rel_res_rms = make_resolution_plots( h2d_orig, xlabel=xlabel, output_filename=os.path.join( plot_dir, '%s_resolution_summary_rms.%s' % (var_name, OUTPUT_FMT)), do_fit=False, do_rms=True, log_var=log_var, save_response_hists=False) res_quantiles, rel_res_quantiles = make_resolution_plots( h2d_orig, xlabel=xlabel, output_filename=os.path.join( plot_dir, '%s_resolution_summary_quantiles.%s' % (var_name, OUTPUT_FMT)), do_fit=False, do_rms=False, quantiles=None, # auto determine log_var=log_var, save_response_hists=save_response_hists) # compare RMS and quantile results conts = [ Contribution( res_rms, label="#sqrt{RMS} #pm #frac{#sqrt{#delta RMS}}{#LT %s #GT}" % (xlabel), line_color=ROOT.kRed, marker_color=ROOT.kRed), Contribution(res_quantiles, label="68% quantile", line_color=ROOT.kBlue, marker_color=ROOT.kBlue) ] ylabel = "#frac{#sigma(RECO/GEN)}{GEN}" if "_rel_" in var_name else "#frac{#sigma(RECO)}{GEN}" res_plot = Plot(conts, what='graph', xtitle=xlabel, ytitle=ylabel, legend=True, ylim=[0, 3]) res_plot.legend.SetX1(0.5) res_plot.legend.SetX2(0.9) res_plot.legend.SetY1(0.7) res_plot.legend.SetY2(0.85) res_plot.plot('ALP') res_plot.save( os.path.join( plot_dir, '%s_resolution_rms_vs_quantiles.%s' % (var_name, OUTPUT_FMT)))
def do_flavour_fraction_vs_eta(input_file, dirname, eta_bins, output_filename, title="", var_prepend="", which_jet="both", append=""): """Plot all flavour fractions vs eta for one input file & dirname in the ROOT file""" info = get_flavour_efficiencies( input_file, bins=eta_bins, hist_name=get_flavour_hist_name( dirname=dirname, var_prepend=var_prepend, which_jet="both", # since no jet/jet1/jet2 in hist name metric='eta' + append)) leg_draw_opt = "LP" plot_u = Contribution(info['u'].CreateGraph(), label="Up", line_color=ROOT.kRed, marker_color=ROOT.kRed, marker_style=20, leg_draw_opt=leg_draw_opt) plot_d = Contribution(info['d'].CreateGraph(), label="Down", line_color=ROOT.kBlue, marker_color=ROOT.kBlue, marker_style=21, leg_draw_opt=leg_draw_opt) plot_s = Contribution(info['s'].CreateGraph(), label="Strange", line_color=ROOT.kBlack, marker_color=ROOT.kBlack, marker_style=22, leg_draw_opt=leg_draw_opt) plot_c = Contribution(info['c'].CreateGraph(), label="Charm", line_color=ROOT.kGreen + 2, marker_color=ROOT.kGreen + 2, marker_style=23, leg_draw_opt=leg_draw_opt) plot_b = Contribution(info['b'].CreateGraph(), label="Bottom", line_color=ROOT.kOrange - 3, marker_color=ROOT.kOrange - 3, marker_style=33, leg_draw_opt=leg_draw_opt) plot_g = Contribution(info['g'].CreateGraph(), label="Gluon", line_color=ROOT.kViolet, marker_color=ROOT.kViolet, marker_style=29, leg_draw_opt=leg_draw_opt) plot_unknown = Contribution(info['unknown'].CreateGraph(), label="Unknown", line_color=ROOT.kGray + 1, marker_color=ROOT.kGray + 1, marker_style=26, leg_draw_opt=leg_draw_opt) p_flav = Plot( [plot_d, plot_u, plot_s, plot_c, plot_b, plot_g, plot_unknown], what='graph', xtitle="y^{%s}" % get_jet_str(''), ytitle="Fraction", title=title, xlim=(eta_bins[0][0], eta_bins[-1][1]), ylim=[0, 1], has_data=False) p_flav.default_canvas_size = (600, 600) p_flav.plot("AP") p_flav.main_pad.SetBottomMargin(0.16) p_flav.get_modifier().GetXaxis().SetTitleOffset(1.4) p_flav.get_modifier().GetXaxis().SetTitleSize(.045) p_flav.legend.SetX1(0.55) p_flav.legend.SetY1(0.72) p_flav.legend.SetY2(0.85) p_flav.legend.SetNColumns(2) p_flav.save(output_filename)
def make_resolution_plots(h2d, xlabel, output_filename, do_fit=True, do_rms=True, quantiles=None, log_var=False, save_response_hists=False): """Make graph of resolution vs variables. Also optionally save all input histograms to file. """ one_sigma = 0.682689 quantiles = quantiles or [0.5 * (1 - one_sigma), 1 - 0.5 * (1 - one_sigma)] ax = h2d.GetXaxis() bin_edges = [ax.GetBinLowEdge(i) for i in range(1, ax.GetNbins() + 1)] bin_centers, sigmas, sigmas_unc = [], [], [] rel_sigmas, rel_sigmas_unc = [], [] # bin_centers = [ax.GetBinCenter(i) for i in range(1, ax.GetNbins()+1)] for var_min, var_max in zip(bin_edges[:-1], bin_edges[1:]): h_projection = qgg.get_projection_plot(h2d, var_min, var_max, cut_axis='x') if h_projection.GetEffectiveEntries() < 20: continue # h_projection.Rebin(rebin) h_projection.Scale(1. / h_projection.Integral()) bin_centers.append(0.5 * (var_max + var_min)) if do_fit: do_gaus_fit(h_projection) fit = h_projection.GetFunction("gausFit") # label += "\n" # label += fit_results_to_str(fit) # bin_centers.append(fit.GetParameter(1)) sigmas.append(fit.GetParameter(2)) rel_sigmas.append(fit.GetParameter(2) / bin_centers[-1]) sigmas_unc.append(fit.GetParError(2)) rel_sigmas_unc.append(fit.GetParError(2) / bin_centers[-1]) else: if do_rms: sigmas.append(sqrt(h_projection.GetRMS())) rel_sigmas.append( sqrt(h_projection.GetRMS()) / bin_centers[-1]) sigmas_unc.append(sqrt(h_projection.GetRMSError())) rel_sigmas_unc.append( sqrt(h_projection.GetRMSError()) / bin_centers[-1]) elif quantiles: if len(quantiles) != 2: raise RuntimeError("Need 2 quantiles") q = array('d', quantiles) results = array('d', [0.] * len(quantiles)) h_projection.GetQuantiles(len(quantiles), results, q) sigmas.append(results[1] - results[0]) sigmas_unc.append(0) rel_sigmas.append((results[1] - results[0]) / bin_centers[-1]) rel_sigmas_unc.append(0) else: raise RuntimeError( "Need either do_fit, do_rms, or 2-tuple in quantiles") if save_response_hists: xlabel = h_projection.GetXaxis().GetTitle() cont = Contribution(h_projection, label="GEN: %g-%g" % (var_min, var_max)) p = Plot([cont], what='hist') p.plot('HISTE') rsp_filename = os.path.abspath( output_filename.replace( ".%s" % OUTPUT_FMT, "_hist%gto%g.%s" % (var_min, var_max, OUTPUT_FMT))) rsp_dir = os.path.dirname(rsp_filename) rsp_file = os.path.basename(rsp_filename) p.save(os.path.join(rsp_dir, "responseHists", rsp_file)) gr = ROOT.TGraphErrors(len(bin_centers), array('d', bin_centers), array('d', sigmas), array('d', [0] * len(bin_centers)), array('d', sigmas_unc)) gr_cont = Contribution(gr, label="") ylabel = "" if do_fit: ylabel = "Fit #sigma" elif do_rms: ylabel = "#sqrt{RMS}" elif quantiles: ylabel = "Central %g" % one_sigma plot = Plot([gr_cont], what='graph', xtitle=xlabel, ytitle=ylabel, xlim=[bin_edges[0], bin_edges[-1]], ylim=[0, max(sigmas) * 1.2], legend=False) plot.plot() if log_var: plot.set_logx() plot.save(output_filename) gr_rel = ROOT.TGraphErrors(len(bin_centers), array('d', bin_centers), array('d', rel_sigmas), array('d', [0] * len(bin_centers)), array('d', rel_sigmas_unc)) gr_rel_cont = Contribution(gr_rel, label="") ylabel = "Relative %s" % ylabel plot = Plot([gr_rel_cont], what='graph', xtitle=xlabel, ytitle=ylabel, xlim=[bin_edges[0], bin_edges[-1]], ylim=[min(rel_sigmas) / 1.2, max(rel_sigmas) * 1.2], legend=False) plot.plot() plot.set_logy() if log_var: plot.set_logx() plot.save( output_filename.replace(".%s" % OUTPUT_FMT, "_relative.%s" % OUTPUT_FMT)) return gr, gr_rel
def do_projection_plots(in_file, plot_dir, do_fit=True, skip_dirs=None): hist_name = "pt_jet_response" tfile = cu.open_root_file(in_file) dirs = cu.get_list_of_element_names(tfile) for mydir in dirs: if skip_dirs and mydir in skip_dirs: continue if hist_name not in cu.get_list_of_element_names(tfile.Get(mydir)): continue print("Doing", mydir) h2d = cu.grab_obj_from_file(in_file, "%s/%s" % (mydir, hist_name)) ax = h2d.GetXaxis() bin_edges = [ax.GetBinLowEdge(i) for i in range(1, ax.GetNbins() + 2)] bin_centers, sigmas, sigmas_unc = [], [], [] for pt_min, pt_max in zip(bin_edges[:-1], bin_edges[1:]): obj = qgg.get_projection_plot(h2d, pt_min, pt_max, cut_axis='x') if obj.GetEffectiveEntries() < 20: continue # obj.Rebin(rebin) obj.Scale(1. / obj.Integral()) label = "%s < p_{T}^{Gen} < %s GeV" % (str(pt_min), str(pt_max)) if do_fit: do_gaus_fit(obj) fit = obj.GetFunction("gausFit") label += "\n" label += fit_results_to_str(fit) # bin_centers.append(fit.GetParameter(1)) bin_centers.append(0.5 * (pt_max + pt_min)) sigmas.append(fit.GetParameter(2)) sigmas_unc.append(fit.GetParError(2)) # output_filename = os.path.join(plot_dir, "%s_%s_ptGen%sto%s.%s" % (mydir, hist_name, str(pt_min), str(pt_max), OUTPUT_FMT)) # cont = Contribution(obj, label=label) # delta = pt_max - pt_min # # xlim = (pt_min - 10*delta, pt_max + 10*delta) # xlim = (obj.GetMean()-3*obj.GetRMS(), obj.GetMean()+3*obj.GetRMS()) # ylim = (0, obj.GetMaximum()*1.1) # plot = Plot([cont], what='hist', # xtitle="p_{T}^{Reco} [GeV]", xlim=xlim, ylim=ylim) # plot.plot() # don't use histe as it wont draw the fit # plot.save(output_filename) gr = ROOT.TGraphErrors(len(bin_centers), array('d', bin_centers), array('d', sigmas), array('d', [0] * len(bin_centers)), array('d', sigmas_unc)) factor = 0.2 gr_ideal = ROOT.TGraphErrors( len(bin_centers), array('d', bin_centers), array('d', [factor * pt for pt in bin_centers]), array('d', [0] * len(bin_centers)), array('d', [0] * len(bin_centers))) gr_cont = Contribution(gr, label='Measured') gr_ideal_cont = Contribution(gr_ideal, label=str(factor) + '*p_{T}', line_color=ROOT.kBlue, marker_color=ROOT.kBlue) plot = Plot([gr_cont, gr_ideal_cont], what='graph', xtitle="p_{T}^{Reco}", ytitle="#sigma [GeV]", ylim=[0, 100], xlim=[10, 4000]) plot.plot() plot.set_logx() output_filename = os.path.join( plot_dir, "%s_%s_sigma_plot.%s" % (mydir, hist_name, OUTPUT_FMT)) plot.save(output_filename)
def do_1D_plot(hists, output_filename, components_styles_dicts=None, draw_opts="NOSTACK HISTE", do_ratio=True, logx=False, logy=False, normalise_hists=True, title=""): if (len(hists) != len(components_styles_dicts)): raise RuntimeError("# hists != # components_styles_dicts (%d vs %d)" % (len(hists), len(components_styles_dicts))) hists = [h.Clone(cu.get_unique_str()) for h in hists] contributions = [Contribution(hist, normalise_hist=normalise_hists, label=csd.get('label', 'x'), **csd.get('style', {})) for hist, csd in zip(hists, components_styles_dicts)] if len(contributions) == 0: return # Ignore if all empty objs total_entries = sum(c.obj.GetEntries() for c in contributions) if total_entries == 0: print("WARNING: all plots have 0 entries") return min_val = min([h.GetMinimum(0) for h in hists]) max_val = max([h.GetMaximum() for h in hists]) # print("Auto y limits:", min_val, max_val) if logy: ylim = [0.5*min_val, 50*max_val] else: # ylim = [0.5*min_val, 1.5*max_val] ylim = [0, 1.5*max_val] # Auto calc x limits to avoid lots of empty bins high_bin = max([find_largest_filled_bin(h)[0] for h in hists]) low_bin = min([find_first_filled_bin(h)[0] for h in hists]) xlim = [hists[0].GetBinLowEdge(low_bin-1), hists[0].GetBinLowEdge(high_bin+2)] subplot_title = "* / %s" % contributions[0].label if len(contributions[0].label) > 10: # need padding to centralise it padding = ' ' * int(len(contributions[0].label)/2) subplot_title = "#splitline{%s* /%s}{%s}" % (padding, padding, contributions[0].label) p = Plot(contributions, what='hist', ytitle="#DeltaN/N" if normalise_hists else "N", title=title, xlim=xlim, ylim=ylim, subplot_type="ratio" if do_ratio else None, subplot_title=subplot_title, subplot=contributions[0], # subplot_limits=(0.5, 1.5), # subplot_limits=(0, 2) if logy else (0.5, 1.5), subplot_limits=(0, 2.5) if logy else (0.5, 1.5), ) # p.legend.SetX1(0.55) # # p.legend.SetX2(0.95) # p.legend.SetY1(0.7) # p.legend.SetY2(0.85) p.legend.SetX1(0.5) p.legend.SetX2(0.97) if len(contributions) > 4: p.legend.SetY1(0.6) else: p.legend.SetY1(0.7) p.legend.SetY2(0.9) p.plot(draw_opts) if logy: p.set_logy(do_more_labels=False) if logx: p.set_logx(do_more_labels=False) # p.save(os.path.join(output_dir, obj_name+".%s" % (OUTPUT_FMT))) p.save(output_filename)