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))
Esempio n. 2
0
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)))
Esempio n. 7
0
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)))
Esempio n. 9
0
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)
Esempio n. 10
0
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)))
Esempio n. 12
0
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))
Esempio n. 14
0
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)))
Esempio n. 16
0
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)
Esempio n. 17
0
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)
Esempio n. 18
0
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)
Esempio n. 19
0
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)
Esempio n. 20
0
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)
Esempio n. 23
0
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)
Esempio n. 25
0
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]")
Esempio n. 26
0
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)
Esempio n. 27
0
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)")
Esempio n. 28
0
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)
Esempio n. 29
0
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)
Esempio n. 30
0
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)))
Esempio n. 32
0
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
Esempio n. 34
0
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)