def make_plots(filenames, oDir, hist_names, title):

    c = ROOT.TCanvas("", "", 800, 600)
    c.SetTicks(1, 1)

    files = [cu.open_root_file(f.filename) for f in filenames]

    for hname in hist_names:
        # print hname
        hists = [cu.get_from_file(f, hname).Clone() for f in files]

        leg = ROOT.TLegend(0.6, 0.6, 0.85, 0.85)

        for i, h in enumerate(hists):
            norm_hist(h)
            h.Rebin(2)
            h.SetTitle('%s: %s' % (title, hname))
            h.SetLineColor(filenames[i].color)
            if i == 0:
                h.Draw("HISTE")
            else:
                h.Draw("HISTE SAME")
            leg.AddEntry(h, filenames[i].label, "L")

        leg.Draw()

        outname = os.path.join(oDir, hname+'.pdf')
        cu.check_dir_exists_create(os.path.dirname(outname))
        c.SaveAs(os.path.join(oDir, hname+'.pdf'))
Exemple #2
0
def plot_response_hists(response_hists, output_dir):
    cu.check_dir_exists_create(output_dir)
    for ind, h in enumerate(response_hists):
        c = ROOT.TCanvas(cu.get_unique_str(), "", 600, 800)
        h.Draw("HISTE")
        c.SaveAs(
            os.path.join(output_dir,
                         "response_hist_%d.%s" % (ind, OUTPUT_FMT)))
def plot_corr_results(in_name):
    """Puts correction plots from ROOT file in one pdf.

    Parameters
    ----------
    in_name : str
        Name of ROOT file to process (output from runCalibration.py)
    """
    print "Opening", in_name
    in_stem = os.path.basename(in_name).replace(".root", "")
    input_file = cu.open_root_file(in_name)

    # Setup output directory & filenames
    odir = os.path.join(os.path.dirname(os.path.abspath(in_name)), in_stem)
    cu.check_dir_exists_create(odir)

    out_name = os.path.join(odir, in_stem + ".pdf")
    out_stem = out_name.replace(".pdf", "")
    print "Writing to", out_name

    # Start beamer file - make main tex file
    # Use template - change title, subtitle, include file
    frontpage_title = "Correction value plots, binned by $|\eta|$"
    sub = in_stem.replace("output_", "").replace("_", "\_").replace("_ak", r"\\_ak")
    subtitle = "{\\tt " + sub + "}"
    main_file = out_stem + ".tex"
    slides_file = out_stem + "_slides.tex"
    make_main_tex_file(frontpage_title, subtitle, AUTHOR, main_file, slides_file)

    # Now make the slides file to be included in main file
    with open(slides_file, "w") as slides:
        titles = []
        plotnames = []
        etaBins = binning.eta_bins
        for i, (eta_min, eta_max) in enumerate(binning.pairwise(etaBins)):
            plotname = "l1corr_eta_%g_%g" % (eta_min, eta_max)
            bin_title = "%g <  |\eta^{L1}| < %g" % (eta_min, eta_max)
            xtitle = "<p_{T}^{L1}> [GeV]"
            ytitle = "Correction = 1/<p_{T}^{L1}/p_{T}^{Ref}>"
            output_plots = [os.path.join(odir, plotname + ext) for ext in ['.tex', '.pdf']]
            if plot_to_file(input_file, plotname, output_plots,
                            xtitle=xtitle, ytitle=ytitle, title="",
                            drawfit=True, extend_fit=True):
                titles.append("$%s$" % bin_title)
                plotnames.append(os.path.join(odir, plotname + ".tex"))
            # When we have 4 plots, or reached the end, write to a slide
            if (((i + 1) % 4 == 0) and (i != 0)) or (i == len(etaBins) - 2):
                print "Writing slide"
                slidetitle = "Correction value"
                slides.write(bst.make_slide(bst.four_plot_slide, titles, plotnames, slidetitle))
                titles = []
                plotnames = []

    compile_pdf(main_file, out_name, odir, 1)
def plot_corr_results(in_name):
    """Puts correction plots from ROOT file in one pdf.

    Parameters
    ----------
    in_name : str
        Name of ROOT file to process (output from runCalibration.py)
    """
    print "Opening", in_name
    in_stem = os.path.basename(in_name).replace(".root", "")
    input_file = cu.open_root_file(in_name)

    # Setup output directory & filenames
    odir = os.path.join(os.path.dirname(os.path.abspath(in_name)), in_stem)
    cu.check_dir_exists_create(odir)

    out_name = os.path.join(odir, in_stem + ".pdf")
    out_stem = out_name.replace(".pdf", "")
    print "Writing to", out_name

    # Start beamer file - make main tex file
    # Use template - change title, subtitle, include file
    frontpage_title = "Correction value plots, binned by $|\eta|$"
    sub = in_stem.replace("output_", "").replace("_", "\_").replace("_ak", r"\\_ak")
    subtitle = "{\\tt " + sub + "}"
    main_file = out_stem + ".tex"
    slides_file = out_stem + "_slides.tex"
    make_main_tex_file(frontpage_title, subtitle, AUTHOR, main_file, slides_file)

    # Now make the slides file to be included in main file
    with open(slides_file, "w") as slides:
        titles = []
        plotnames = []
        etaBins = binning.eta_bins
        for i, (eta_min, eta_max) in enumerate(binning.pairwise(etaBins)):
            plotname = "l1corr_eta_%g_%g" % (eta_min, eta_max)
            bin_title = "%g <  |\eta^{L1}| < %g" % (eta_min, eta_max)
            xtitle = "<p_{T}^{L1}> [GeV]"
            ytitle = "Correction = 1/<p_{T}^{L1}/p_{T}^{Ref}>"
            output_plots = [os.path.join(odir, plotname + ext) for ext in ['.tex', '.pdf']]
            if plot_to_file(input_file, plotname, output_plots,
                            xtitle=xtitle, ytitle=ytitle, title="",
                            drawfit=True, extend_fit=True):
                titles.append("$%s$" % bin_title)
                plotnames.append(os.path.join(odir, plotname + ".tex"))
            # When we have 4 plots, or reached the end, write to a slide
            if (((i + 1) % 4 == 0) and (i != 0)) or (i == len(etaBins) - 2):
                print "Writing slide"
                slidetitle = "Correction value"
                slides.write(bst.make_slide(bst.four_plot_slide, titles, plotnames, slidetitle))
                titles = []
                plotnames = []

    compile_pdf(main_file, out_name, odir, 1)
Exemple #5
0
def print_plots(directory, output_dir, title=""):
    plot_names = get_list_of_obj(directory)
    cu.check_dir_exists_create(output_dir)
    for pname in plot_names:
        hist = directory.Get(pname)
        c = ROOT.TCanvas(str(uuid1()), "", 600, 600)
        c.SetLogz()
        hist.SetTitle(title)
        hist.Draw("COLZ TEXT89")
        c.SaveAs(os.path.join(output_dir, pname + "." + OUTPUT_FMT))

        c.Clear()
        hist_normed = cu.make_normalised_TH2(hist, "Y", False)
        hist_normed.SetMinimum(1E-4)
        hist_normed.Draw("COLZ TEXT89")
        c.SaveAs(os.path.join(output_dir, pname + "_normed." + OUTPUT_FMT))
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_res_pt_bin(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the L1 resolution for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/res_l1_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    try:
        h_res = cu.get_from_file(res_file, hname)
    except IOError:
        print '!! Cannot get', hname
        return None
    c = generate_canvas()
    h_res.Draw()
    h_res.SetAxisRange(-2, 2, "X")
    h_res.SetTitle(";%s;N" % res_l1_str)
    subdir = "%s/eta_%g_%g" % (oDir, eta_min, eta_max)
    cu.check_dir_exists_create("%s/eta_%g_%g" % (oDir, eta_min, eta_max))
    filename = "%s/res_l1_eta_%g_%g_%g_%g.%s" % (subdir, eta_min, eta_max, pt_min, pt_max, oFormat)
    c.SaveAs(filename)
    return filename
def do_2d_plot(h2d, output_filename, renorm=None, logx=False, logy=False, logz=False, xtitle=None, ytitle=None, rebinx=1, rebiny=1):
    canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
    canv.SetLogx(logx)
    canv.SetLogy(logy)
    canv.SetLogz(logz)
    h2d_new = h2d.Clone(cu.get_unique_str())
    h2d_new.RebinX(rebinx)
    h2d_new.RebinY(rebiny)
    if renorm.lower() in ['x', 'y']:
        h2d_new = cu.make_normalised_TH2(h2d_new, renorm, True)
    if xtitle:
        h2d_new.GetXaxis().SetTitle(xtitle);
    if ytitle:
        h2d_new.GetYaxis().SetTitle(ytitle);
    h2d_new.Draw("COLZ")
    dirname = os.path.dirname(os.path.abspath(output_filename))
    cu.check_dir_exists_create(dirname)
    canv.SaveAs(output_filename)
def compare_by_eta_pu_bins(graphs_list, file_identifier, pu_labels, title, oDir, ylim=None, lowpt_zoom=True):
    """Compare graphs for each (eta, PU) bin.

    Parameters
    ----------
    graphs_list : list[list[Contribution]]
        List of list of contributions, so you can any
        number of sets of contributions on a graph.
    file_identifier : str
        String to be inserted into resultant plot filename.
    title : str
        Title to put on plots
    oDir : str
        Output directory for plots
    ylim : list, optional
        Set y axis range
    lowpt_zoom : bool, optional
        Zoom in on low pt range
    """
    cu.check_dir_exists_create(oDir)
    for (eta_min, eta_max) in pairwise(binning.eta_bins):
        rename_dict = dict(eta_min=eta_min, eta_max=eta_max)
        eta_min_str = '{:g}'.format(eta_min).replace('.', 'p')
        eta_max_str = '{:g}'.format(eta_max).replace('.', 'p')
        new_graphs_list = [setup_new_graphs(g, rename_dict) for g in graphs_list]

        if not ylim:
            ylim = [0.5, 3.5] if eta_min > 2 else [0.5, 4]
        for i, pu_label in enumerate(pu_labels):
            rename_dict['pu_label'] = pu_label
            p = Plot(contributions=[ng[i] for ng in new_graphs_list], what="graph",
                     xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)",
                     title=title.format(**rename_dict), ylim=ylim)
            p.plot()
            p.legend.SetX1(0.5)
            p.save(os.path.join(oDir, "compare_%s_eta_%s_%s_%s.pdf" % (file_identifier, eta_min_str, eta_max_str, pu_label)))
            if lowpt_zoom:
                # zoom in on low pT
                p = Plot(contributions=[ng[i] for ng in new_graphs_list], what="graph",
                         xtitle="<p_{T}^{L1}>", ytitle="Correction value (= 1/response)",
                         title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim)
                p.plot()
                p.legend.SetX1(0.5)
                p.save(os.path.join(oDir, "compare_%s_eta_%s_%s_%s_pTzoomed.pdf" % (file_identifier, eta_min_str, eta_max_str, pu_label)))
def do_jet_index_plots(tdir, plot_dir):
    """Do 2D plots of genjet index vs recojet index"""
    plot_dir = os.path.join(plot_dir, tdir.GetName())
    cu.check_dir_exists_create(plot_dir)
    stem = "genjet_ind_recojet_ind_pt_"
    for plot_name in cu.get_list_of_element_names(tdir):
        if not plot_name.startswith(stem):
            continue
        h2d = cu.get_from_tfile(tdir, plot_name)
        h2d.SetTitle(h2d.GetTitle())
        renorm_h2d = cu.make_normalised_TH2(h2d, 'X', recolour=False)
        # renorm_h2d = h2d
        canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
        pad = ROOT.gPad
        pad.SetBottomMargin(0.12)
        pad.SetLeftMargin(0.13)
        pad.SetRightMargin(0.12)
        canv.SetTicks(1, 1)
        renorm_h2d.Draw("COLZ TEXT")
        renorm_h2d.SetMaximum(1)
        renorm_h2d.SetMinimum(0)
        title_offset = 1.5
        renorm_h2d.SetTitleOffset(title_offset, 'X')
        renorm_h2d.SetTitleOffset(title_offset * 1.15, 'Y')

        canv.SaveAs(
            os.path.join(plot_dir,
                         "%s_renormX_linZ.%s" % (plot_name, OUTPUT_FMT)))
        # canv.SetLogz()
        # renorm_h2d.SetMinimum(1E-3)
        # canv.SaveAs(os.path.join(plot_dir, "%s_renormX_logZ.%s" % (plot_name, OUTPUT_FMT)))

        canv.Clear()
        renorm_h2d = cu.make_normalised_TH2(h2d, 'Y', recolour=False)
        renorm_h2d.Draw("COLZ TEXT")
        renorm_h2d.SetMaximum(1)
        renorm_h2d.SetMinimum(0)
        title_offset = 1.5
        renorm_h2d.SetTitleOffset(title_offset, 'X')
        renorm_h2d.SetTitleOffset(title_offset * 1.15, 'Y')
        canv.SaveAs(
            os.path.join(plot_dir,
                         "%s_renormY_linZ.%s" % (plot_name, OUTPUT_FMT)))
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)))
Exemple #12
0
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, 2] if eta_min > 2 else [0.5, 2.5]
        p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>",
                 ytitle="Correction value (= 1/response)",
                 title=title.format(**rename_dict), ylim=ylim)
        p.plot()
        p.save(os.path.join(oDir, "compare_PU_eta_%s_%s.pdf" % (eta_min_str, eta_max_str)))

        if lowpt_zoom:
            # zoom in on low pT
            p = Plot(contributions=new_graphs, what="graph", xtitle="<p_{T}^{L1}>",
                     ytitle="Correction value (= 1/response)",
                     title=title.format(**rename_dict), xlim=zoom_pt, ylim=ylim)
            p.plot()
            p.save(os.path.join(oDir, "compare_PU_eta_%s_%s_pTzoomed.pdf" % (eta_min_str, eta_max_str)))
def plot_pt_diff(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the difference between L1 and ref jet pT, for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/ptDiff_ref_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    try:
        h_diff = cu.get_from_file(res_file, hname)
    except IOError:
        print '!! Cannot get', hname
        return None
    c = generate_canvas()
    h_diff.Draw()
    h_diff.SetMaximum(h_diff.GetMaximum() * 1.2)
    # h_diff.SetLineWidth(2)
    func = h_diff.GetListOfFunctions().At(0)
    if func:
        func.SetLineWidth(2)
    h_diff.SetTitle("%g < %s < %g, %g < p_{T}^{%s} < %g;%s;N" % (eta_min, eta_l1_str, eta_max, pt_min, ref_str, pt_max, pt_diff_str))
    subdir = "%s/eta_%g_%g" % (oDir, eta_min, eta_max)
    cu.check_dir_exists_create("%s/eta_%g_%g" % (oDir, eta_min, eta_max))
    filename = "%s/pt_diff_eta_%g_%g_%g_%g.%s" % (subdir, eta_min, eta_max, pt_min, pt_max, oFormat)
    c.SaveAs(filename)
    return 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)))
                            do_dijet_forward_groomed=args.doDijetForwardGroomed,
                            do_zpj=args.doZPJ,
                            do_zpj_groomed=args.doZPJGroomed,
                            source=args.sourceDir1)
    if len(regions) == 0:
        raise RuntimeError("Need at least 1 region")

    if args.angles[0] == "all":
        angles = qgc.COMMON_VARS
    else:
        angles = [a for a in qgc.COMMON_VARS if a.var in args.angles]

    if len(angles) == 0:
        raise RuntimeError("Need at least 1 angle")

    cu.check_dir_exists_create(args.outputDir)

    num_all_iterations = len(regions) * len(angles)
    counter = 1

    has_data1 = not ('_MC_all' in args.sourceDir1 or '_MC_split' in args.sourceDir1)
    has_data2 = not ('_MC_all' in args.sourceDir2 or '_MC_split' in args.sourceDir2)

    jet_algo1 = "AK4"
    if "ak8puppi" in args.sourceDir1:
        jet_algo1 = "AK8"

    jet_algo2 = "AK4"
    if "ak8puppi" in args.sourceDir2:
        jet_algo2 = "AK8"
                        action='store_true',
                        help='Ignore missing bins/values')
    args = parser.parse_args()

    if (len(args.yodaInputDijet) != len(args.yodaLabel)
        and len(args.yodaInputZPJ) != len(args.yodaLabel)):
        raise RuntimeError("Number of --yodaInputDijet/yodaInputZPJ must match number of --yodaLabel")

    if len(args.yodaInputDijet) == 0:
        raise RuntimeError("Need at least one YODA input")

    # -----------------------------------------------------------------------
    # Get stats from YODA files, add to dataframe
    # -----------------------------------------------------------------------
    df = get_dataframe_from_yoda_inputs(zip(args.yodaInputDijet, args.yodaInputZPJ, args.yodaLabel),
                                        data_ak4_dirname=args.ak4source,
                                        data_ak8_dirname=args.ak8source,
                                        ignore_missing=args.ignoreMissing)
    convert_df_types(df)
    print(df.head())
    print(df.tail())
    print(len(df.index), 'entries in dataframe')
    print(df.dtypes)

    # Save dataframe to file
    # -----------------------------------------------------------------------
    print("Saving dataframe to", args.h5output)
    cu.check_dir_exists_create(os.path.dirname(args.h5output))
    # need format='table' to store category dtype
    df.to_hdf(args.h5output, key='df', format='table')
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--input",
        help=
        "Input ROOT file with response & resolution graphs (from jet_response_and_resolution_x)",
        required=True)
    parser.add_argument("--outputDir",
                        help="Output directory for plots",
                        default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots", default="")
    parser.add_argument("--sampleName",
                        help="Sample name string for plots",
                        default="")
    args = parser.parse_args(in_args)

    cu.check_dir_exists_create(args.outputDir)

    lw = 1
    entry_dicts = [
        {
            "flav": "AbsCorVsJetPt",
            "label": "All",
            "colour": ROOT.kBlack,
            "marker_style": ROOT.kFullCircle,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.2
        },
        {
            "flav": "ud_AbsCorVsJetPt",
            "label": "ud",
            "colour": ROOT.kRed,
            "marker_style": ROOT.kFullSquare,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.2
        },
        {
            "flav": "s_AbsCorVsJetPt",
            "label": "s",
            "colour": ROOT.kBlue,
            "marker_style": ROOT.kFullTriangleUp,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.4
        },
        {
            "flav": "c_AbsCorVsJetPt",
            "label": "c",
            "colour": ROOT.kGreen + 2,
            "marker_style": ROOT.kFullTriangleDown,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.4
        },
        {
            "flav": "b_AbsCorVsJetPt",
            "label": "b",
            "colour": ROOT.kOrange - 3,
            "marker_style": ROOT.kFullDiamond,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.6
        },
        {
            "flav": "g_AbsCorVsJetPt",
            "label": "g",
            "colour": ROOT.kAzure + 1,
            "marker_style": 29,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.8
        },
    ]

    # Loop through all different ak4pfchs, etc
    dirs = cu.get_list_of_element_names(cu.open_root_file(args.input))
    for mydir in dirs[:]:
        jec_text = ROOT.TPaveText(0.14, 0.91, 0.2, 0.92, "NDC")
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.71, 0.2, 0.74, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace(
            "PUPPI", " PUPPI").replace("L1L2L3",
                                       " + L1L2L3").replace("L1", " + L1")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        sample_text = ROOT.TPaveText(0.93, 0.91, 0.94, 0.92, "NDC")
        # sample_text.AddText("Flat QCD 13 TeV")
        sample_text.AddText(args.sampleName + " 13 TeV")
        sample_text.SetTextFont(42)
        sample_text.SetTextSize(FONT_SIZE)
        sample_text.SetTextAlign(ROOT.kHAlignRight + ROOT.kVAlignBottom)
        sample_text.SetBorderSize(0)
        sample_text.SetFillStyle(0)
        sample_text.Draw()

        other_elements = [jec_text, dir_text, sample_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input, mydir)

        # Do all flavs rsp vs pt for given eta bin
        common_eta_bins = cu.get_common_eta_bins(obj_list)
        for eta_bin in common_eta_bins:
            entries = []

            # repsonse
            # for fdict in entry_dicts:
            #     entry = deepcopy(fdict)
            #     entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
            #     entry["line_color"] = fdict['colour']
            #     entry["marker_color"] = fdict['colour']
            #     entries.append(entry)
            # bin_title = eta_bin.replace("to", " < |#eta| < ").replace("JetEta", "")
            # do_comparison_graph(entries, bin_title=bin_title,
            #                     xtitle="p_{T}^{Gen} [GeV]", ytitle="Response", logx=True,
            #                     xlimits=(10, 5000), y_limit_protection=(0.5, 1.5),
            #                     other_elements=other_elements,
            #                     output_filename=os.path.join(plot_dir, "rsp_vs_pt_%s.pdf" % (eta_bin)))

            # correction
            entries = []
            bin_title = eta_bin.replace("to",
                                        " < #eta < ").replace("JetEta", "")
            for fdict in entry_dicts:
                entry = deepcopy(fdict)
                entry["graph"] = cu.grab_obj_from_file(
                    args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                entry["line_color"] = fdict['colour']
                entry["marker_color"] = fdict['colour']

                entries.append(entry)
                do_comparison_graph([entry],
                                    bin_title=bin_title,
                                    xtitle="p_{T}^{Reco} [GeV]",
                                    ytitle="Correction",
                                    logx=True,
                                    y_limit_protection=(0.7, 1.8),
                                    other_elements=other_elements,
                                    draw_fit_graph_ratio=True,
                                    output_filename=os.path.join(
                                        plot_dir, "%s_%s_logX.pdf" %
                                        (fdict['flav'], eta_bin)))

                do_comparison_graph([entry],
                                    bin_title=bin_title,
                                    xtitle="p_{T}^{Reco} [GeV]",
                                    ytitle="Correction",
                                    logx=False,
                                    y_limit_protection=(0.7, 1.8),
                                    other_elements=other_elements,
                                    draw_fit_graph_ratio=True,
                                    output_filename=os.path.join(
                                        plot_dir, "%s_%s_linX.pdf" %
                                        (fdict['flav'], eta_bin)))

            do_comparison_graph(entries,
                                bin_title=bin_title,
                                xtitle="p_{T}^{Reco} [GeV]",
                                ytitle="Correction",
                                logx=True,
                                y_limit_protection=(0.7, 1.8),
                                other_elements=other_elements,
                                draw_fit_graph_ratio=True,
                                output_filename=os.path.join(
                                    plot_dir,
                                    "corr_vs_pt_%s_logX.pdf" % (eta_bin)))

            do_comparison_graph(entries,
                                bin_title=bin_title,
                                xtitle="p_{T}^{Reco} [GeV]",
                                ytitle="Correction",
                                logx=False,
                                y_limit_protection=(0.7, 1.8),
                                other_elements=other_elements,
                                draw_fit_graph_ratio=True,
                                output_filename=os.path.join(
                                    plot_dir,
                                    "corr_vs_pt_%s_linX.pdf" % (eta_bin)))

    return 0
                'jet_thrust_charged': (1E-10, 1E-4),
            },
        },
    ]

    # If True, use part of MC for response matrix, and separate part for unfolding
    # as independent test
    MC_split = False
    mc_append = "_split" if MC_split else "_all"

    # Subtract fakes from reconstructed hists, using MC fakes as template
    subtract_fakes = True
    sub_append = "_subFakes" if subtract_fakes else ""

    output_dir = "folding_better_target0p5%s%s" % (mc_append, sub_append)
    cu.check_dir_exists_create(output_dir)

    # TODO automate this
    jet_algo = "AK4 PF PUPPI"

    # Save hists etc to ROOT file for access later
    output_tfile = ROOT.TFile("%s/folding_result.root" % (output_dir),
                              "RECREATE")
    print("Saving hists to ROOT file:", output_tfile.GetName())

    for region in regions[:]:

        # Setup pt bins
        # -------------
        # need different ones for Z+Jets region
        is_zpj = "ZPlusJets" in region['name']
                        default="groomed")
    parser.add_argument("--target",
                        help="Target purity/stability to put on plot",
                        default=None)
    args = parser.parse_args()
    print(args)

    input_dir, input_basename = os.path.split(args.input)
    default_plot_dir = os.path.join(
        input_dir, "rebinning_" + os.path.splitext(input_basename)[0])
    plot_dir = args.outputDir if args.outputDir else default_plot_dir

    default_output_root_filename = os.path.join(plot_dir,
                                                "rebinned_" + input_basename)
    output_root_filename = args.outputFile if args.outputFile else default_output_root_filename
    cu.check_dir_exists_create(
        os.path.dirname(os.path.abspath(output_root_filename)))
    output_tfile = cu.open_root_file(output_root_filename, 'RECREATE')

    source_plot_dir_names = None
    region_labels = None
    if "qcd" in args.input.lower():
        source_plot_dir_names = [
            "Dijet_QG_central_tighter",
            "Dijet_QG_forward_tighter",
            "Dijet_QG_central_tighter_groomed",
            "Dijet_QG_forward_tighter_groomed",
            ("Dijet_QG_central_tighter",
             "Dijet_QG_forward_tighter"),  # do sum over these regions
            ("Dijet_QG_central_tighter_groomed",
             "Dijet_QG_forward_tighter_groomed")
        ][-2:]
def main(in_args=sys.argv[1:]):
    print in_args
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--pairs",
                        help="input ROOT file with matched pairs from RunMatcher")

    parser.add_argument("--res",
                        help="input ROOT file with resolution plots from makeResolutionPlots.py")

    parser.add_argument("--checkcal",
                        help="input ROOT file with calibration check plots from checkCalibration.py")

    parser.add_argument("--calib",
                        help="input ROOT file from output of runCalibration.py")

    parser.add_argument("--oDir",
                        help="Directory to save plots. Default is in same location as ROOT file.")
    parser.add_argument("--detail",
                        help="Plot all the individual component hists for each eta bin. There are a lot!",
                        action='store_true')
    parser.add_argument("--format",
                        help="Format for plots (PDF, png, etc). Note that 2D correlation plots will "
                             "always be PNGs to avoid large files.",
                        default="pdf")
    parser.add_argument("--title",
                        help="Title for plots.")
    parser.add_argument('--zip',
                        help="Zip filename for zipping up all plots. Don't include extension")

    # FIXME
    # parser.add_argument("--etaInd",
                        # help="list of eta bin index/indices to run over")
    parser.add_argument("--gifs",
                        help="Make GIFs (only applicable if --detail is also used)",
                        action='store_true')
    parser.add_argument("--gifexe",
                        help='Convert executable to use. Default is result of `which convert`')
    args = parser.parse_args(args=in_args)

    print args

    if args.detail:
        print "Warning: producing all component hists. This could take a while..."

    if args.gifs:
        if args.detail:
            print "Making animated graphs from fit plots."
        else:
            print "To use the --gifs flag, you also need --detail"

    if not args.gifexe:
        args.gifexe = find_executable('convert')
        if not args.gifexe:
            print 'Cannot find convert exe, not making gifs'
            args.gif = False
        else:
            print 'Using %s to make GIFs' % args.gifexe

    # customise titles
    # note the use of global keyword
    if args.title:
        global plot_title
        plot_title = args.title

    if args.oDir == os.getcwd():
        print "Warning: plots will be made in $PWD!"

    # auto determine output directory
    if not args.oDir:
        filename, stem = '', ''
        if args.pairs:
            filename, stem = args.pairs, 'pairs_'
        elif args.checkcal:
            filename, stem = args.checkcal, 'check_'
        elif args.res:
            filename, stem = args.res, 'res_'
        elif args.calib:
            filename, stem = args.calib, 'output_'
        new_dir = os.path.basename(filename).replace(".root", '').replace(stem, 'showoff_')

        args.oDir = os.path.join(os.path.dirname(os.path.abspath(filename)), new_dir)

    cu.check_dir_exists_create(args.oDir)
    print "Output directory:", args.oDir


    # Choose eta
    ptBins = binning.pt_bins_stage2

    # Do plots with output from RunMatcher
    # ------------------------------------------------------------------------
    if args.pairs:
        pairs_file = cu.open_root_file(args.pairs)
        pairs_tree = cu.get_from_file(pairs_file, "valid")

        # eta binned
        for emin, emax in pairwise(binning.eta_bins):
            plot_dR(pairs_tree, eta_min=emin, eta_max=emax, cut="1", oDir=args.oDir)
            plot_pt_both(pairs_tree, eta_min=emin, eta_max=emax, cut="1", oDir=args.oDir)

        # plot_dR(pairs_tree, eta_min=0, eta_max=5, cut="1", oDir=args.oDir)  # all eta
        # plot_pt_both(pairs_tree, eta_min=0, eta_max=5, cut="1", oDir=args.oDir)  # all eta
        plot_eta_both(pairs_tree, oDir=args.oDir)  # all eta

        plot_dR(pairs_tree, eta_min=0, eta_max=3, cut="1", oDir=args.oDir)  # central
        plot_pt_both(pairs_tree, eta_min=0, eta_max=3, cut="1", oDir=args.oDir)  # central

        plot_dR(pairs_tree, eta_min=3, eta_max=5, cut="1", oDir=args.oDir)  # forward
        plot_pt_both(pairs_tree, eta_min=3, eta_max=5, cut="1", oDir=args.oDir)  # forward

        pairs_file.Close()

    # Do plots with output from makeResolutionPlots.py
    # ------------------------------------------------------------------------
    if args.res:
        res_file = cu.open_root_file(args.res)

        # exclusive eta graphs
        for eta_min, eta_max in pairwise(binning.eta_bins):
            print eta_min, eta_max

            plot_res_all_pt(res_file, eta_min, eta_max, args.oDir, args.format)

            if args.detail:
                list_dir = os.path.join(args.oDir, 'eta_%g_%g' % (eta_min, eta_max))
                cu.check_dir_exists_create(list_dir)

                pt_diff_filenames = []

                ptBins = binning.pt_bins_stage2_8 if eta_min < 2.9 else binning.pt_bins_stage2_8_wide
                for pt_min, pt_max in pairwise(ptBins):
                    pt_diff_fname = plot_pt_diff(res_file, eta_min, eta_max, pt_min, pt_max, args.oDir, 'png')
                    pt_diff_filenames.append(pt_diff_fname)

                pt_diff_filenames_file = os.path.join(list_dir, 'list_pt_diff.txt')
                write_filelist(pt_diff_filenames, pt_diff_filenames_file)

                if args.gifs:
                    make_gif(pt_diff_filenames_file, pt_diff_filenames_file.replace('.txt', '.gif'), args.gifexe)

        # inclusive eta graphs
        for (eta_min, eta_max) in [[0, 3], [3, 5]]:
            print eta_min, eta_max
            plot_res_all_pt(res_file, eta_min, eta_max, args.oDir, args.format)
            plot_ptDiff_Vs_pt(res_file, eta_min, eta_max, args.oDir, args.format)

            if args.detail:
                list_dir = os.path.join(args.oDir, 'eta_%g_%g' % (eta_min, eta_max))
                cu.check_dir_exists_create(list_dir)

                pt_diff_filenames = []

                ptBins = binning.pt_bins_stage2_8 if eta_min < 2.9 else binning.pt_bins_stage2_8_wide
                for pt_min, pt_max in pairwise(ptBins):
                    pt_diff_fname = plot_pt_diff(res_file, eta_min, eta_max, pt_min, pt_max, args.oDir, 'png')
                    pt_diff_filenames.append(pt_diff_fname)

                pt_diff_filenames_file = os.path.join(list_dir, 'list_pt_diff.txt')
                write_filelist(pt_diff_filenames, pt_diff_filenames_file)

                if args.gifs:
                    make_gif(pt_diff_filenames_file, pt_diff_filenames_file.replace('.txt', '.gif'), args.gifexe)

        # plot_eta_pt_rsp_2d(res_file, binning.eta_bins, binning.pt_bins[4:], args.oDir, args.format)

        # components of these:
        # if args.detail:
        #     ptBins = binning.pt_bins_stage2_8 if not forward_bin else binning.pt_bins_stage2_8_wide
        #     for pt_min, pt_max in pairwise(ptBins):
        #         plot_pt_diff(res_file, 0, 3, pt_min, pt_max, args.oDir, args.format)
                # plot_pt_diff(res_file, 0, 5, pt_min, pt_max, args.oDir, args.format)
                # plot_pt_diff(res_file, 3, 5, pt_min, pt_max, args.oDir, args.format)

        res_file.Close()

    # Do plots with output from checkCalibration.py
    # ------------------------------------------------------------------------
    if args.checkcal:

        etaBins = binning.eta_bins
        check_file = cu.open_root_file(args.checkcal)

        # ptBinsWide = list(np.arange(10, 250, 8))

        # indiviudal eta bins
        for eta_min, eta_max in pairwise(etaBins):
            for (normX, logZ) in product([True, False], [True, False]):
                plot_l1_Vs_ref(check_file, eta_min, eta_max, logZ, args.oDir, 'png')
                plot_rsp_Vs_l1(check_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')
                plot_rsp_Vs_ref(check_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')
                plot_rsp_Vs_pt_candle_violin(check_file, eta_min, eta_max, "l1", args.oDir, 'png')
                plot_rsp_Vs_pt_candle_violin(check_file, eta_min, eta_max, "gen", args.oDir, 'png')

            if args.detail:
                list_dir = os.path.join(args.oDir, 'eta_%g_%g' % (eta_min, eta_max))
                cu.check_dir_exists_create(list_dir)

                # print individual histograms, and make a list suitable for imagemagick to turn into a GIF
                pt_plot_filenames = plot_rsp_pt_hists(check_file, eta_min, eta_max, ptBins, "pt", args.oDir, 'png')
                pt_plot_filenames_file = os.path.join(list_dir, 'list_pt.txt')
                write_filelist(pt_plot_filenames, pt_plot_filenames_file)

                # print individual histograms, and make a list suitable for imagemagick to turn into a GIF
                ptRef_plot_filenames = plot_rsp_pt_hists(check_file, eta_min, eta_max, ptBins, "ptRef", args.oDir, 'png')
                ptRef_plot_filenames_file = os.path.join(list_dir, 'list_ptRef.txt')
                write_filelist(ptRef_plot_filenames, ptRef_plot_filenames_file)

                # make dem GIFs
                if args.gifs:
                    for inf in [pt_plot_filenames_file, ptRef_plot_filenames_file]:
                        make_gif(inf, inf.replace('.txt', '.gif'), args.gifexe)

        # Graph of response vs pt, but in bins of eta
        x_range = [0, 150]  # for zoomed-in low pt
        x_range = None
        plot_rsp_pt_binned_graph(check_file, etaBins, "pt", args.oDir, args.format, x_range=x_range)
        plot_rsp_pt_binned_graph(check_file, etaBins, "ptRef", args.oDir, args.format, x_range=x_range)

        all_rsp_pt_plot_filenames = []
        all_rsp_ptRef_plot_filenames = []

        # Loop over central/forward eta, do 2D plots, and graphs, and component hists
        for (eta_min, eta_max) in [[0, 3], [3, 5]]:
            print eta_min, eta_max

            for (normX, logZ) in product([True, False], [True, False]):
                plot_l1_Vs_ref(check_file, eta_min, eta_max, logZ, args.oDir, 'png')
                plot_rsp_Vs_l1(check_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')
                plot_rsp_Vs_ref(check_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')

            if args.detail:
                plot_rsp_pt_hists(check_file, eta_min, eta_max, ptBins, "pt", args.oDir, 'png')
                plot_rsp_pt_hists(check_file, eta_min, eta_max, ptBins, "ptRef", args.oDir, 'png')

            # graphs
            plot_rsp_eta_exclusive_graph(check_file, eta_min, eta_max, binning.check_pt_bins, 'pt', args.oDir, args.format)
            plot_rsp_eta_exclusive_graph(check_file, eta_min, eta_max, binning.check_pt_bins, 'ptRef', args.oDir, args.format)

            plot_rsp_pt_graph(check_file, eta_min, eta_max, args.oDir, args.format, x_range)
            plot_rsp_ptRef_graph(check_file, eta_min, eta_max, args.oDir, args.format, x_range)

            for etamin, etamax in pairwise(etaBins):
                if etamin < eta_min or etamax > eta_max:
                    continue
                print etamin, etamax
                this_rsp_pt_plot_filenames = []
                this_rsp_ptRef_plot_filenames = []
                # component hists/fits for the eta graphs, binned by pt
                for pt_min, pt_max in binning.check_pt_bins:
                    pt_filename = plot_rsp_eta_bin_pt(check_file, etamin, etamax, 'pt', pt_min, pt_max, args.oDir, 'png')
                    this_rsp_pt_plot_filenames.append(pt_filename)
                    ptRef_filename = plot_rsp_eta_bin_pt(check_file, etamin, etamax, 'ptRef', pt_min, pt_max, args.oDir, 'png')
                    this_rsp_ptRef_plot_filenames.append(ptRef_filename)

                pt_list_file = os.path.join(args.oDir, 'list_pt_eta_%g_%g.txt' % (etamin, etamax))
                write_filelist(this_rsp_pt_plot_filenames, pt_list_file)
                if args.gifs:
                    make_gif(pt_list_file, pt_list_file.replace('.txt', '.gif'), args.gifexe)

                ptRef_list_file = os.path.join(args.oDir, 'list_ptRef_eta_%g_%g.txt' % (etamin, etamax))
                write_filelist(this_rsp_ptRef_plot_filenames, ptRef_list_file)
                if args.gifs:
                    make_gif(ptRef_list_file, ptRef_list_file.replace('.txt', '.gif'), args.gifexe)

                all_rsp_pt_plot_filenames.extend(this_rsp_pt_plot_filenames)
                all_rsp_ptRef_plot_filenames.extend(this_rsp_ptRef_plot_filenames)

        pt_list_file = os.path.join(args.oDir, 'list_pt_eta_%g_%g.txt' % (etaBins[0], etaBins[-1]))
        write_filelist(all_rsp_pt_plot_filenames, pt_list_file)
        if args.gifs:
            make_gif(pt_list_file, pt_list_file.replace('.txt', '.gif'), args.gifexe)

        ptRef_list_file = os.path.join(args.oDir, 'list_ptRef_eta_%g_%g.txt' % (etaBins[0], etaBins[-1]))
        write_filelist(all_rsp_ptRef_plot_filenames, ptRef_list_file)
        if args.gifs:
            make_gif(ptRef_list_file, ptRef_list_file.replace('.txt', '.gif'), args.gifexe)

        check_file.Close()

    # Do plots with output from runCalibration.py
    # ------------------------------------------------------------------------
    if args.calib:

        calib_file = cu.open_root_file(args.calib)

        for eta_min, eta_max in pairwise(binning.eta_bins[:-1]):

            print eta_min, eta_max

            # 2D correlation heat maps
            for (normX, logZ) in product([True, False], [True, False]):
                plot_rsp_Vs_ref(calib_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')
                plot_rsp_Vs_l1(calib_file, eta_min, eta_max, normX, logZ, args.oDir, 'png')

            # individual fit histograms for each pt bin
            if args.detail:

                list_dir = os.path.join(args.oDir, 'eta_%g_%g' % (eta_min, eta_max))
                cu.check_dir_exists_create(list_dir)

                if eta_min > 2.9:
                    ptBins = binning.pt_bins_stage2_hf

                rsp_plot_filenames = []
                pt_plot_filenames = []

                for pt_min, pt_max in pairwise(ptBins):
                    rsp_name = plot_rsp_eta_pt_bin(calib_file, eta_min, eta_max, pt_min, pt_max, args.oDir, 'png')
                    rsp_plot_filenames.append(rsp_name)
                    pt_name = plot_pt_bin(calib_file, eta_min, eta_max, pt_min, pt_max, args.oDir, 'png')
                    pt_plot_filenames.append(pt_name)

                # print individual histograms, and make a list suitable for imagemagick to turn into a GIF
                rsp_plot_filenames_file = os.path.join(list_dir, 'list_rsp.txt')
                write_filelist(rsp_plot_filenames, rsp_plot_filenames_file)

                # print individual histograms, and make a list suitable for imagemagick to turn into a GIF
                pt_plot_filenames_file = os.path.join(list_dir, 'list_pt.txt')
                write_filelist(pt_plot_filenames, pt_plot_filenames_file)

                # make dem gifs
                if args.gifs:
                    for inf in [pt_plot_filenames_file, rsp_plot_filenames_file]:
                        make_gif(inf, inf.replace('.txt', '.gif'), args.gifexe)
                else:
                    print "To make animated gif from PNGs using a plot list:"
                    print "convert -dispose Background -delay 50 -loop 0 @%s "\
                        "pt_eta_%g_%g.gif" % (pt_plot_filenames_file, eta_min, eta_max)

            # the correction curve graph
            plot_correction_graph(calib_file, eta_min, eta_max, args.oDir, args.format)

        calib_file.Close()

    if args.zip:
        print 'Zipping up files'
        zip_filename = os.path.basename(args.zip.split('.')[0])
        make_archive(zip_filename, 'gztar', args.oDir)
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument("--input",
                        help="Input ROOT file with correction graphs",
                        action='append')
    parser.add_argument("--label",
                        help="Label for input file",
                        action='append')
    parser.add_argument("--outputDir",
                        help="Output directory for plots",
                        default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots")
    parser.add_argument("--chi2",
                        help="Do Chi2 comparison plot",
                        action='store_true')
    parser.add_argument("--ylim", help="Set explicit y limits", nargs=2)
    parser.add_argument(
        "--slides",
        help="Dump JSON snippet to file for use with beamer-plot-slides",
        default=None)
    parser.add_argument("--vertLine",
                        help="Add a vertical dashed line at this x value",
                        type=float)
    args = parser.parse_args(in_args)
    print(args)

    if not args.input or len(args.input) == 0:
        return 1

    cu.check_dir_exists_create(args.outputDir)

    if len(args.input) != len(args.label):
        raise RuntimeError("Need a --label for each --input")

    do_slides = args.slides not in (None, "")

    lw = 1
    entry_dicts = [
        # {"flav": "AbsCorVsJetPt", "label": "All", "colour": ROOT.kBlack, "marker_style": ROOT.kFullCircle, "line_style": 2, "line_width": lw, "marker_size": 1.2},
        {
            "flav": "ud_AbsCorVsJetPt",
            "label": "ud",
            "colour": ROOT.kRed,
            "marker_style": ROOT.kFullSquare,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 0.8
        },
        {
            "flav": "g_AbsCorVsJetPt",
            "label": "g",
            "colour": ROOT.kAzure + 1,
            "marker_style": 29,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.
        },
        {
            "flav": "s_AbsCorVsJetPt",
            "label": "s",
            "colour": ROOT.kBlue,
            "marker_style": ROOT.kFullTriangleUp,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.
        },
        {
            "flav": "c_AbsCorVsJetPt",
            "label": "c",
            "colour": ROOT.kGreen + 2,
            "marker_style": ROOT.kFullTriangleDown,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.
        },
        {
            "flav": "b_AbsCorVsJetPt",
            "label": "b",
            "colour": ROOT.kOrange - 3,
            "marker_style": ROOT.kFullDiamond,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.2
        },
    ][:]

    sample_str = "QCD MC"

    all_dirs = [
        set(cu.get_list_of_element_names(cu.open_root_file(infile)))
        for infile in args.input
    ]
    dirs = all_dirs[0]
    for d in all_dirs[1:]:
        dirs = dirs & d
    dirs = sorted(list(dirs))[:1]
    print("Doing: ", dirs)
    # Loop through all different ak4pfchs, etc
    slides_contents = []
    for mydir in dirs:
        jec_text = ROOT.TPaveText(0.15, 0.93, 0.2, 0.94, "NDC")
        # jec_label = "Without JEC"
        # jec_label = "With JEC"
        # jec_label = "Summer16_23Sep2016V4"
        # jec_label = "Summer16_03Feb2017_V8"
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.78, 0.2, 0.79, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace(
            "PUPPI", " PUPPI").replace("L1L2L3",
                                       " + L1L2L3").replace("L1", " + L1")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        other_elements = [jec_text, dir_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input[0], mydir)

        ylimits = (float(args.ylim[0]),
                   float(args.ylim[1])) if args.ylim else None

        X_MIN, X_MAX = 7, None
        # For limit protection:
        Y_MIN, Y_MAX = 0.8, 1.6

        py_herwig_ratio_title = "Parton / Hadron"
        py_herwig_ratio_title = "H++ / Py8"

        # Store chi2 for fits over pT
        # Each entry is for a flavour,
        # and is a dict of file label : chi2/dof values
        fit_chi2entries = {}
        for fdict in entry_dicts:
            fit_chi2entries[fdict['label']] = {}
            for label in args.label:
                fit_chi2entries[fdict['label']][label] = []

        # Do all flavs corr vs pt for given eta bin
        common_eta_bins = cu.sort_human(cu.get_common_eta_bins(obj_list))
        for eta_bin in common_eta_bins:
            title = eta_bin.replace("to", " < #eta < ").replace("JetEta", "")
            # Do a per-flavour comparison plot
            outputs = []
            for fdict in entry_dicts:
                entries = []
                chi2entries = []
                for ind, (input_filename,
                          label) in enumerate(zip(args.input, args.label)):
                    entry = deepcopy(fdict)
                    entry["graph"] = cu.grab_obj_from_file(
                        input_filename,
                        "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                    entry['label'] += " [%s]" % label
                    new_colour = cu.get_alternate_colour(fdict['colour'], ind)
                    entry["line_color"] = new_colour
                    entry["marker_color"] = new_colour
                    entry["fill_color"] = new_colour
                    entry["fill_style"] = 1001
                    entry["fill_alpha"] = 0.7
                    entry["ratio"] = None
                    if ind == 1:
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                        entry["line_style"] += 1
                    if ind == 2:
                        entry["line_style"] += 1
                    if ind == 3:
                        entry["line_style"] += 1
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                    entries.append(entry)
                    if ind != 0:
                        entries[-1]['ratio'] = entries[0]['graph']

                    if args.chi2:
                        # chi2entry = deepcopy(entry)
                        # chi2entry["graph"] = cu.grab_obj_from_file(input_filename, "%s/%s_%s" % (mydir, fdict['flav'].replace("corrVs", "Chi2NDoFVs"), eta_bin))
                        # chi2entries.append(chi2entry)
                        if entry['graph'].GetListOfFunctions().GetSize() > 0:
                            fit = entry['graph'].GetListOfFunctions().Last()
                            # chi2 = entry['graph'].Chisquare(fit)  # can't do this as we don't want to use the plateau in chi2
                            chi2 = fit.GetChisquare()
                            ndof = fit.GetNDF()
                            fit_chi2entries[fdict['label']][label].append(
                                chi2 / ndof)

                output_filename = os.path.abspath(
                    os.path.join(
                        plot_dir,
                        "compare_corr_vs_pt_%s_%s_funcGraphRatio.pdf" %
                        (eta_bin, fdict['label'])))
                cu.do_comparison_graph(
                    entries,
                    title=title,
                    sample_title=sample_str,
                    xtitle="p_{T}^{Reco} [GeV]",
                    ytitle="Correction",
                    logx=True,
                    xlimits=(X_MIN, X_MAX),
                    # xlimits=None,
                    y_limit_protection=(Y_MIN, Y_MAX),
                    ylimits=ylimits,
                    other_elements=other_elements,
                    output_filename=output_filename,
                    vertical_line=args.vertLine,
                    do_fit_graph_ratio=True)
                outputs.append(output_filename)

                output_filename = os.path.abspath(
                    os.path.join(
                        plot_dir,
                        "compare_corr_vs_pt_%s_%s_pyHerwigRatio.pdf" %
                        (eta_bin, fdict['label'])))
                cu.do_comparison_graph(
                    entries,
                    title=title,
                    sample_title=sample_str,
                    xtitle="p_{T}^{Reco} [GeV]",
                    ytitle="Correction",
                    logx=True,
                    xlimits=(X_MIN, X_MAX),
                    # xlimits=None,
                    y_limit_protection=(Y_MIN, Y_MAX),
                    ylimits=ylimits,
                    other_elements=other_elements,
                    output_filename=output_filename,
                    vertical_line=args.vertLine,
                    draw_fits=True,
                    do_ratio_plots=True,
                    ratio_title=py_herwig_ratio_title)

                output_filename = os.path.abspath(
                    os.path.join(
                        plot_dir, "compare_corr_vs_pt_%s_%s_pull.pdf" %
                        (eta_bin, fdict['label'])))
                cu.do_comparison_graph(
                    entries,
                    title=title,
                    sample_title=sample_str,
                    xtitle="p_{T}^{Reco} [GeV]",
                    ytitle="Correction",
                    logx=True,
                    xlimits=(X_MIN, X_MAX),
                    # xlimits=None,
                    y_limit_protection=(Y_MIN, Y_MAX),
                    ylimits=ylimits,
                    other_elements=other_elements,
                    output_filename=output_filename,
                    vertical_line=args.vertLine,
                    do_fit_graph_pull=True)
                # if args.chi2:
                #     cu.do_comparison_graph(chi2entries, title=title, sample_title=sample_str,
                #                         xtitle="p_{T}^{Reco} [GeV]", ytitle="#chi^{2}/N_{DoF}", logx=True,
                #                         xlimits=(X_MIN, X_MAX),
                #                         other_elements=other_elements,
                #                         output_filename=os.path.join(plot_dir, "compare_corr_vs_pt_%s_%s_chi2.pdf" % (eta_bin, fdict['label'])))

            # Do a plot with all flavours
            entries = []
            ud_entries, g_entries = [], []
            for fdict in entry_dicts[:]:
                for ind, (input_filename,
                          label) in enumerate(zip(args.input, args.label)):
                    entry = deepcopy(fdict)
                    entry["graph"] = cu.grab_obj_from_file(
                        input_filename,
                        "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                    entry['label'] += " [%s]" % label
                    new_colour = cu.get_alternate_colour(fdict['colour'], ind)
                    entry["line_color"] = new_colour
                    entry["marker_color"] = new_colour
                    entry["fill_color"] = new_colour
                    entry["fill_style"] = 1001
                    entry["fill_alpha"] = 0.8
                    entry['ratio'] = None
                    if ind == 1:
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                        entry["line_style"] += 1
                    if ind == 2:
                        entry["line_style"] += 1
                    if ind == 3:
                        entry["line_style"] += 1
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                    entries.append(entry)
                    if fdict['label'] == "ud":
                        ud_entries.append(entry)
                    elif fdict['label'] == "g":
                        g_entries.append(entry)
                    if ind > 0:
                        entries[-1]['ratio'] = entries[-2]['graph']

            title = eta_bin.replace("to", " < #eta < ").replace("JetEta", "")
            output_filename = os.path.abspath(
                os.path.join(
                    plot_dir,
                    "compare_corr_vs_pt_%s_allFlavs_funcGraphRatio.pdf" %
                    (eta_bin)))
            cu.do_comparison_graph(entries,
                                   title=title,
                                   sample_title=sample_str,
                                   xtitle="p_{T}^{Reco} [GeV]",
                                   ytitle="Correction",
                                   logx=True,
                                   xlimits=(X_MIN, X_MAX),
                                   y_limit_protection=(Y_MIN, Y_MAX),
                                   ylimits=ylimits,
                                   other_elements=other_elements,
                                   output_filename=output_filename,
                                   vertical_line=args.vertLine,
                                   do_fit_graph_ratio=True)
            outputs.insert(0, output_filename)

            output_filename = os.path.abspath(
                os.path.join(
                    plot_dir,
                    "compare_corr_vs_pt_%s_allFlavs_pyHerwigRatio.pdf" %
                    (eta_bin)))
            cu.do_comparison_graph(entries,
                                   title=title,
                                   sample_title=sample_str,
                                   xtitle="p_{T}^{Reco} [GeV]",
                                   ytitle="Correction",
                                   logx=True,
                                   xlimits=(X_MIN, X_MAX),
                                   y_limit_protection=(Y_MIN, Y_MAX),
                                   ylimits=ylimits,
                                   other_elements=other_elements,
                                   output_filename=output_filename,
                                   vertical_line=args.vertLine,
                                   draw_fits=True,
                                   do_ratio_plots=True,
                                   ratio_title=py_herwig_ratio_title)

            # make 1 slide with all flavours for this eta bin
            if do_slides:
                plots = ",\n".join([
                    '            ["{{{fname}}}{ext}", "{title}"]'.format(
                        fname=os.path.splitext(fname)[0],
                        ext=os.path.splitext(fname)[1],
                        title="") for fname in outputs
                ])
                text = """    {{
    "title": "${thistitle}$",
    "plots": [
{plots}
        ]
    }}""".format(thistitle=title.replace("#", r"\\"), plots=plots)

                slides_contents.append(text)

        if args.chi2:
            # for each flav, do a plot of chi2 of total fit vs eta for all files
            all_entries = []
            all_ymax = 0
            for fdict in entry_dicts:
                entries = []
                file_labels = list(fit_chi2entries[fdict['label']].keys())
                ymax = 0
                for ind, flabel in enumerate(file_labels):
                    eta_bins = [get_eta_mid(x) for x in common_eta_bins]
                    y = fit_chi2entries[fdict['label']][flabel]
                    ymax = max(ymax, max(y))
                    ey = [0] * len(y)
                    ex = [get_eta_half_width(x) for x in common_eta_bins]
                    gr = ROOT.TGraphErrors(len(y), array('d', eta_bins),
                                           array('d', y), array('d', ex),
                                           array('d', ey))
                    entry = deepcopy(fdict)
                    entry["graph"] = gr
                    entry['label'] = "%s [%s]" % (fdict['label'], flabel)
                    new_colour = cu.get_alternate_colour(fdict['colour'], ind)
                    entry["line_color"] = new_colour
                    entry["marker_color"] = new_colour
                    entry["fill_color"] = new_colour
                    entry["fill_style"] = 1001
                    entry["fill_alpha"] = 0.8
                    if ind == 1:
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                        entry["line_style"] += 1
                    if ind == 2:
                        entry["line_style"] += 1
                    if ind == 3:
                        entry["line_style"] += 1
                        entry["marker_style"] = cu.get_open_marker(
                            entry['marker_style'])
                    entries.append(entry)
                all_ymax = max(all_ymax, ymax)
                ylimits = [0, ymax * 1.3]
                # if ylimits[1] > 20:
                #     ylimits[1] = 20
                output_filename = os.path.abspath(
                    os.path.join(
                        plot_dir,
                        "compare_chi2_vs_eta_%s.pdf" % (fdict['label'])))
                cu.do_comparison_graph(entries,
                                       title="",
                                       sample_title=sample_str,
                                       xtitle="#eta^{Reco}",
                                       ytitle="#chi^{2} / N_{dof}",
                                       draw_opt="ALP",
                                       ylimits=ylimits,
                                       other_elements=other_elements,
                                       output_filename=output_filename)
                all_entries.extend(entries)

            # do a single plot with all flavs
            ylimits = [0, all_ymax * 1.3]
            if ylimits[1] > 20:
                ylimits[1] = 20
            output_filename = os.path.abspath(
                os.path.join(plot_dir, "compare_chi2_vs_eta_allFlavs.pdf"))
            cu.do_comparison_graph(all_entries,
                                   title="",
                                   sample_title=sample_str,
                                   xtitle="#eta^{Reco}",
                                   ytitle="#chi^{2} / N_{dof}",
                                   draw_opt="ALP",
                                   ylimits=ylimits,
                                   other_elements=other_elements,
                                   output_filename=output_filename)

            # diff_entries = []
            # for ind, (ud, g, label) in enumerate(zip(ud_entries, g_entries, args.label)):
            #     diff_graph = construct_difference_graph(ud['graph'], g['graph'])
            #     diff = deepcopy(ud)
            #     diff['graph'] = diff_graph
            #     diff['label'] = label
            #     diff_entries.append(diff)
            # cu.do_comparison_graph(diff_entries, title=title, sample_title=sample_str,
            #                     xtitle="p_{T}^{Reco} [GeV]", ytitle="Correction (ud) - Correction (g)", logx=True,
            #                     xlimits=(X_MIN, X_MAX), ylimits=(0, 0.08),
            #                     other_elements=other_elements,
            #                     output_filename=os.path.join(plot_dir, "compare_corr_vs_pt_%s_ud_g_diff.pdf" % (eta_bin)))

        # # Do all flavs corr vs eta for given pt bin
        # common_pt_bins = cu.sort_human(cu.get_common_pt_bins(obj_list))
        # for pt_bin in common_pt_bins:
        #     # Do a per-flavour comparison plot
        #     for fdict in entry_dicts:
        #         entries = []
        #         chi2entries = []
        #         for ind, (input_filename, label) in enumerate(zip(args.input, args.label)):
        #             entry = deepcopy(fdict)
        #             entry["graph"] = cu.grab_obj_from_file(input_filename, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta"), pt_bin))
        #             entry['label'] += " [%s]" % label
        #             entry["line_color"] = fdict['colour']
        #             entry["marker_color"] = fdict['colour']
        #             if ind == 1:
        #                 entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
        #             if ind == 2:
        #                 entry["line_style"] += 1
        #             if ind == 3:
        #                 entry["line_style"] += 1
        #                 entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
        #             entries.append(entry)
        #             if args.chi2:
        #                 chi2entry = deepcopy(entry)
        #                 chi2entry["graph"] = cu.grab_obj_from_file(input_filename, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta").replace("corrVs", "Chi2NDoFVs"), pt_bin))
        #                 chi2entries.append(chi2entry)

        #         title = pt_bin.replace("to", " < p_{T} < ").replace("RefPt", "")
        #         cu.do_comparison_graph(entries, title=title + " GeV", sample_title=sample_str,
        #                             xtitle="|#eta|", ytitle="Correction",
        #                             xlimits=(0, 5.2), y_limit_protection=(Y_MIN, Y_MAX),
        #                             other_elements=other_elements, ylimits=ylimits,
        #                             output_filename=os.path.join(plot_dir, "compare_corr_vs_eta_%s_%s.pdf" % (pt_bin, fdict['label'])))
        #         if args.chi2:
        #             cu.do_comparison_graph(entries, title=title, sample_title=sample_str,
        #                                 xtitle="|#eta|", ytitle="#chi^{2}/N_{DoF}",
        #                                 xlimits=(0, 5.2),
        #                                 other_elements=other_elements,
        #                                 output_filename=os.path.join(plot_dir, "compare_corr_vs_eta_%s_%s_chi2.pdf" % (pt_bin, fdict['label'])))

        #     # Do a plot with all flavours
        #     entries = []
        #     for fdict in entry_dicts:
        #         for ind, (input_filename, label) in enumerate(zip(args.input, args.label)):
        #             entry = deepcopy(fdict)
        #             entry["graph"] = cu.grab_obj_from_file(input_filename, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta"), pt_bin))
        #             entry['label'] += " [%s]" % label
        #             entry["line_color"] = fdict['colour']
        #             entry["marker_color"] = fdict['colour']
        #             if ind == 1:
        #                 entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
        #             if ind == 2:
        #                 entry["line_style"] += 1
        #             if ind == 3:
        #                 entry["line_style"] += 1
        #                 entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
        #             entries.append(entry)
        #     title = pt_bin.replace("to", " < p_{T} < ").replace("RefPt", "")
        #     cu.do_comparison_graph(entries, title=title + " GeV", sample_title=sample_str,
        #                         xtitle="|#eta|", ytitle="Correction",
        #                         xlimits=(0, 5.2), y_limit_protection=(Y_MIN, Y_MAX),
        #                         other_elements=other_elements, ylimits=ylimits,
        #                         output_filename=os.path.join(plot_dir, "compare_corr_vs_eta_%s_allFlavs.pdf" % (pt_bin)))

    if do_slides:
        print("Writing JSON to", args.slides)
        with open(args.slides, "w") as fout:
            fout.write(",\n".join(slides_contents))
    return 0
Exemple #22
0
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--input",
        help=
        "Input ROOT file with response & resolution graphs (from jet_response_and_resolution_x)",
        action='append')
    parser.add_argument("--label",
                        help="Label for input file",
                        action='append')
    parser.add_argument("--outputDir",
                        help="Output directory for plots",
                        default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots")
    parser.add_argument("--chi2",
                        help="Do Chi2 comparison plot",
                        action='store_true')
    parser.add_argument("--ylim", help="Set explicit y limits", nargs=2)
    args = parser.parse_args(in_args)

    cu.check_dir_exists_create(args.outputDir)

    if len(args.input) != len(args.label):
        raise RuntimeError("Need a --label for each --input")

    if args.input:

        lw = 2
        entry_dicts = [
            {
                "flav": "RelRspVsRefPt",
                "label": "All",
                "colour": ROOT.kBlack,
                "marker_style": ROOT.kFullCircle,
                "line_style": 2,
                "line_width": lw,
                "marker_size": 1.2
            },
            {
                "flav": "ud_RspVsRefPt_RelRsp",
                "label": "ud",
                "colour": ROOT.kRed,
                "marker_style": ROOT.kFullSquare,
                "line_style": 1,
                "line_width": lw,
                "marker_size": 1.2
            },
            {
                "flav": "s_RRspVsRefPt_RelRsp",
                "label": "s",
                "colour": ROOT.kBlue,
                "marker_style": ROOT.kFullTriangleUp,
                "line_style": 1,
                "line_width": lw,
                "marker_size": 1.4
            },
            {
                "flav": "c_RRspVsRefPt_RelRsp",
                "label": "c",
                "colour": ROOT.kGreen + 2,
                "marker_style": ROOT.kFullTriangleDown,
                "line_style": 1,
                "line_width": lw,
                "marker_size": 1.4
            },
            {
                "flav": "b_RRspVsRefPt_RelRsp",
                "label": "b",
                "colour": ROOT.kOrange - 3,
                "marker_style": ROOT.kFullDiamond,
                "line_style": 1,
                "line_width": lw,
                "marker_size": 1.6
            },
            {
                "flav": "g_RRspVsRefPt_RelRsp",
                "label": "g",
                "colour": ROOT.kAzure + 1,
                "marker_style": 29,
                "line_style": 1,
                "line_width": lw,
                "marker_size": 1.8
            },
        ]

        all_dirs = [
            set(cu.get_list_of_element_names(cu.open_root_file(infile)))
            for infile in args.input
        ]
        dirs = all_dirs[0]
        for d in all_dirs[1:]:
            dirs = dirs & d
        dirs = sorted(list(dirs))[:1]
        print("Doing: ", dirs)
        # Loop through all different ak4pfchs, etc
        for mydir in dirs:
            jec_text = ROOT.TPaveText(0.17, 0.91, 0.2, 0.92, "NDC")
            jec_label = "Without JEC"
            # jec_label = "With JEC"
            # jec_label = "Summer16_23Sep2016V4"
            # jec_label = "Summer16_03Feb2017_V8"
            jec_text.AddText(args.title)
            jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
            jec_text.SetTextFont(42)
            jec_text.SetTextSize(FONT_SIZE)
            jec_text.SetBorderSize(0)
            jec_text.SetFillStyle(0)

            dir_text = ROOT.TPaveText(0.17, 0.76, 0.2, 0.77, "NDC")
            dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace(
                "PUPPI", " PUPPI").replace("L1L2L3", " + L1L2L3")
            dir_text.AddText(dir_label)
            dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
            dir_text.SetTextFont(42)
            dir_text.SetTextSize(FONT_SIZE)
            dir_text.SetBorderSize(0)
            dir_text.SetFillStyle(0)

            other_elements = [jec_text, dir_text]

            plot_dir = os.path.join(args.outputDir, mydir)
            cu.check_dir_exists_create(plot_dir)

            obj_list = cu.get_list_of_objects_in_dir(args.input[0], mydir)

            ylimits = (float(args.ylim[0]),
                       float(args.ylim[1])) if args.ylim else None

            # Do all flavs rsp vs pt for given eta bin
            common_eta_bins = cu.get_common_eta_bins(obj_list)
            for eta_bin in common_eta_bins:
                # Do a per-flavour comparison plot
                for fdict in entry_dicts:
                    entries = []
                    chi2entries = []
                    for ind, (input_filename,
                              label) in enumerate(zip(args.input, args.label)):
                        entry = deepcopy(fdict)
                        entry["graph"] = cu.grab_obj_from_file(
                            input_filename,
                            "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                        entry['label'] += " [%s]" % label
                        entry["line_color"] = fdict['colour']
                        entry["marker_color"] = fdict['colour']
                        if ind == 1:
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        if ind == 2:
                            entry["line_style"] += 1
                        if ind == 3:
                            entry["line_style"] += 1
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        entries.append(entry)

                        if args.chi2:
                            chi2entry = deepcopy(entry)
                            chi2entry["graph"] = cu.grab_obj_from_file(
                                input_filename,
                                "%s/%s_%s" % (mydir, fdict['flav'].replace(
                                    "RspVs", "Chi2NDoFVs"), eta_bin))
                            chi2entries.append(chi2entry)

                    title = eta_bin.replace("to", " < |#eta| < ").replace(
                        "JetEta", "")
                    do_comparison_graph(entries,
                                        title=title,
                                        xtitle="p_{T}^{Gen} [GeV]",
                                        ytitle="Response",
                                        logx=True,
                                        xlimits=(10, 3000),
                                        y_limit_protection=(0.7, 1.4),
                                        ylimits=ylimits,
                                        other_elements=other_elements,
                                        output_filename=os.path.join(
                                            plot_dir,
                                            "compare_rsp_vs_pt_%s_%s.pdf" %
                                            (eta_bin, fdict['label'])))
                    if args.chi2:
                        do_comparison_graph(
                            chi2entries,
                            title=title,
                            xtitle="p_{T}^{Gen} [GeV]",
                            ytitle="#chi^{2}/N_{DoF}",
                            logx=True,
                            xlimits=(10, 3000),
                            other_elements=other_elements,
                            output_filename=os.path.join(
                                plot_dir, "compare_rsp_vs_pt_%s_%s_chi2.pdf" %
                                (eta_bin, fdict['label'])))

                # Do a plot with all flavours
                entries = []
                ud_entries, g_entries = [], []
                for fdict in entry_dicts:
                    for ind, (input_filename,
                              label) in enumerate(zip(args.input, args.label)):
                        entry = deepcopy(fdict)
                        entry["graph"] = cu.grab_obj_from_file(
                            input_filename,
                            "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                        entry['label'] += " [%s]" % label
                        entry["line_color"] = fdict['colour']
                        entry["marker_color"] = fdict['colour']
                        if ind == 1:
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        if ind == 2:
                            entry["line_style"] += 1
                        if ind == 3:
                            entry["line_style"] += 1
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        entries.append(entry)
                        if fdict['label'] == "ud":
                            ud_entries.append(entry)
                        elif fdict['label'] == "g":
                            g_entries.append(entry)

                title = eta_bin.replace("to",
                                        " < |#eta| < ").replace("JetEta", "")
                do_comparison_graph(
                    entries,
                    title=title,
                    xtitle="p_{T}^{Gen} [GeV]",
                    ytitle="Response",
                    logx=True,
                    xlimits=(10, 3000),
                    y_limit_protection=(0.7, 1.4),
                    other_elements=other_elements,
                    output_filename=os.path.join(
                        plot_dir,
                        "compare_rsp_vs_pt_%s_allFlavs.pdf" % (eta_bin)))
                # diff_entries = []
                # for ind, (ud, g, label) in enumerate(zip(ud_entries, g_entries, args.label)):
                #     diff_graph = construct_difference_graph(ud['graph'], g['graph'])
                #     diff = deepcopy(ud)
                #     diff['graph'] = diff_graph
                #     diff['label'] = label
                #     diff_entries.append(diff)
                # do_comparison_graph(diff_entries, title=title,
                #                     xtitle="p_{T}^{Gen} [GeV]", ytitle="Response (ud) - response (g)", logx=True,
                #                     xlimits=(10, 3000), ylimits=(0, 0.08),
                #                     other_elements=other_elements,
                #                     output_filename=os.path.join(plot_dir, "compare_rsp_vs_pt_%s_ud_g_diff.pdf" % (eta_bin)))
            return

            # Do all flavs rsp vs eta for given pt bin
            common_pt_bins = cu.get_common_pt_bins(obj_list)
            for pt_bin in common_pt_bins:
                # Do a per-flavour comparison plot
                for fdict in entry_dicts:
                    entries = []
                    chi2entries = []
                    for ind, (input_filename,
                              label) in enumerate(zip(args.input, args.label)):
                        entry = deepcopy(fdict)
                        entry["graph"] = cu.grab_obj_from_file(
                            input_filename,
                            "%s/%s_%s" % (mydir, fdict['flav'].replace(
                                "RefPt", "JetEta"), pt_bin))
                        entry['label'] += " [%s]" % label
                        entry["line_color"] = fdict['colour']
                        entry["marker_color"] = fdict['colour']
                        if ind == 1:
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        if ind == 2:
                            entry["line_style"] += 1
                        if ind == 3:
                            entry["line_style"] += 1
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        entries.append(entry)
                        if args.chi2:
                            chi2entry = deepcopy(entry)
                            chi2entry["graph"] = cu.grab_obj_from_file(
                                input_filename,
                                "%s/%s_%s" % (mydir, fdict['flav'].replace(
                                    "RefPt", "JetEta").replace(
                                        "RspVs", "Chi2NDoFVs"), pt_bin))
                            chi2entries.append(chi2entry)

                    title = pt_bin.replace("to",
                                           " < p_{T} < ").replace("RefPt", "")
                    do_comparison_graph(entries,
                                        title=title + " GeV",
                                        xtitle="|#eta|",
                                        ytitle="Response",
                                        xlimits=(0, 5.2),
                                        y_limit_protection=(0.8, 1.4),
                                        other_elements=other_elements,
                                        ylimits=ylimits,
                                        output_filename=os.path.join(
                                            plot_dir,
                                            "compare_rsp_vs_eta_%s_%s.pdf" %
                                            (pt_bin, fdict['label'])))
                    if args.chi2:
                        do_comparison_graph(
                            entries,
                            title=title,
                            xtitle="|#eta|",
                            ytitle="#chi^{2}/N_{DoF}",
                            xlimits=(0, 5.2),
                            other_elements=other_elements,
                            output_filename=os.path.join(
                                plot_dir, "compare_rsp_vs_eta_%s_%s_chi2.pdf" %
                                (pt_bin, fdict['label'])))

                # Do a plot with all flavours
                entries = []
                for fdict in entry_dicts:
                    for ind, (input_filename,
                              label) in enumerate(zip(args.input, args.label)):
                        entry = deepcopy(fdict)
                        entry["graph"] = cu.grab_obj_from_file(
                            input_filename,
                            "%s/%s_%s" % (mydir, fdict['flav'].replace(
                                "RefPt", "JetEta"), pt_bin))
                        entry['label'] += " [%s]" % label
                        entry["line_color"] = fdict['colour']
                        entry["marker_color"] = fdict['colour']
                        if ind == 1:
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        if ind == 2:
                            entry["line_style"] += 1
                        if ind == 3:
                            entry["line_style"] += 1
                            entry["marker_style"] = get_open_marker(
                                entry['marker_style'])
                        entries.append(entry)
                title = pt_bin.replace("to",
                                       " < p_{T} < ").replace("RefPt", "")
                do_comparison_graph(
                    entries,
                    title=title + " GeV",
                    xtitle="|#eta|",
                    ytitle="Response",
                    xlimits=(0, 5.2),
                    y_limit_protection=(0.8, 1.4),
                    other_elements=other_elements,
                    ylimits=ylimits,
                    output_filename=os.path.join(
                        plot_dir,
                        "compare_rsp_vs_eta_%s_allFlavs.pdf" % (pt_bin)))

    return 0
        nargs='+',
        help='Input ROOT files to process. '
        'Several dirs can be specified here, separated by a space.')
    parser.add_argument("-o",
                        "--output",
                        help="Directory to put output plot dirs into",
                        default=None)
    args = parser.parse_args()
    print(args)

    for in_file in args.input:
        default_plot_dir = os.path.join(
            os.path.dirname(in_file),
            "response_" + os.path.splitext(os.path.basename(in_file))[0])
        plot_dir = args.output if args.output else default_plot_dir
        cu.check_dir_exists_create(plot_dir)
        do_these = None

        if "QCD" in in_file:
            do_these = [
                ("Dijet_QG_tighter/jet_puppiMultiplicity",
                 "Multiplicity (#lambda_{0}^{0})", False, 5),
                ("Dijet_QG_tighter/jet_LHA", "LHA (#lambda_{0.5}^{1})", False,
                 1),
                ("Dijet_QG_tighter/jet_pTD",
                 "(p_{T}^{D})^{2} (#lambda_{0}^{2})", False, 2),
                ("Dijet_QG_tighter/jet_width", "Width (#lambda_{1}^{1})",
                 False, 2),
                ("Dijet_QG_tighter/jet_thrust", "Thrust (#lambda_{2}^{1})",
                 False, 2),
                ("Dijet_QG_tighter/jet_puppiMultiplicity_charged",
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", help="Input ROOT file with response & resolution graphs (from jet_response_and_resolution_x)", required=True)
    parser.add_argument("--outputDir", help="Output directory for plots", default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots", default="")
    parser.add_argument("--sampleName", help="Sample name string for plots", default="")
    args = parser.parse_args(in_args)

    cu.check_dir_exists_create(args.outputDir)

    lw = 2
    entry_dicts = [
        {"flav": "RelRspVsRefPt", "label": "All", "colour": ROOT.kBlack, "marker_style": ROOT.kFullCircle, "line_style": 2, "line_width": lw, "marker_size": 1.2},
        {"flav": "ud_RspVsRefPt_RelRsp", "label": "ud", "colour": ROOT.kRed, "marker_style": ROOT.kFullSquare, "line_style": 1, "line_width": lw, "marker_size": 1.2},
        {"flav": "s_RRspVsRefPt_RelRsp", "label": "s", "colour": ROOT.kBlue, "marker_style": ROOT.kFullTriangleUp, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "c_RRspVsRefPt_RelRsp", "label": "c", "colour": ROOT.kGreen+2, "marker_style": ROOT.kFullTriangleDown, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "b_RRspVsRefPt_RelRsp", "label": "b", "colour": ROOT.kOrange-3, "marker_style": ROOT.kFullDiamond, "line_style": 1, "line_width": lw, "marker_size": 1.6},
        {"flav": "g_RRspVsRefPt_RelRsp", "label": "g", "colour": ROOT.kAzure+1, "marker_style": 29, "line_style": 1, "line_width": lw, "marker_size": 1.8},
    ]

    # no JEC
    eta_bin_limits = {
        'JetEta0to0.783': (0.9, 1.15),
        'JetEta0.783to1.305': None,
        'JetEta1.305to1.93': (0.85, 1.05),
        'JetEta1.93to2.5': None,
        'JetEta2.5to2.964': None,
        'JetEta2.964to3.139': None,
        'JetEta3.139to5.191': (0.98, 1.8),
    }
    eta_bin_ratio_limits = {
        'JetEta0to0.783': (0.96, 1.07),
        'JetEta0.783to1.305': None,
        'JetEta1.305to1.93': (0.95, 1.07),
        'JetEta1.93to2.5': None,
        'JetEta2.5to2.964': None,
        'JetEta2.964to3.139': None,
        'JetEta3.139to5.191': (0.93, 1.1),
    }
    
    # with L1 JEC
    # eta_bin_limits = {
    #     'JetEta0to0.783': (0.76, 1.05),
    #     'JetEta0.783to1.305': (0.77, 1),
    #     'JetEta1.305to1.93': (0.7, 1.),
    #     'JetEta1.93to2.5': (0.68, 1.1),
    #     'JetEta2.5to2.964': (0.55, 1.1),
    #     'JetEta2.964to3.139': (0.6, 1.1),
    #     'JetEta3.139to5.191': (0.75, 1.1),
    # }
    # eta_bin_ratio_limits = {
    #     'JetEta0to0.783': (0.96, 1.08),
    #     'JetEta0.783to1.305': (0.96, 1.08),
    #     'JetEta1.305to1.93': (0.95, 1.09),
    #     'JetEta1.93to2.5': (0.95, 1.13),
    #     'JetEta2.5to2.964': (0.93, 1.15),
    #     'JetEta2.964to3.139': (0.9, 1.12),
    #     'JetEta3.139to5.191': (0.93, 1.1),
    # }

    # default
    # eta_bin_limits = {
    #     'JetEta0to0.783': None,
    #     'JetEta0.783to1.305': None,
    #     'JetEta1.305to1.93': None,
    #     'JetEta1.93to2.5': None,
    #     'JetEta2.5to2.964': None,
    #     'JetEta2.964to3.139': None,
    #     'JetEta3.139to5.191': None,
    # }
    # eta_bin_ratio_limits = {
    #     'JetEta0to0.783': None,
    #     'JetEta0.783to1.305': None,
    #     'JetEta1.305to1.93': None,
    #     'JetEta1.93to2.5': None,
    #     'JetEta2.5to2.964': None,
    #     'JetEta2.964to3.139': None,
    #     'JetEta3.139to5.191': None,
    # }


    # Loop through all different ak4pfchs, etc
    dirs = cu.get_list_of_element_names(cu.open_root_file(args.input))
    for mydir in dirs[:]:
        jec_text = ROOT.TPaveText(0.14, 0.93, 0.2, 0.96, "NDC")
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.75, 0.2, 0.77, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace("PUPPI", " PUPPI").replace("L1L2L3", " + L1L2L3")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        sample_text = ROOT.TPaveText(0.94, 0.93, 0.95, 0.96, "NDC")
        # sample_text.AddText("Flat QCD 13 TeV")
        sample_text.AddText(args.sampleName) # + " 13 TeV")
        sample_text.SetTextFont(42)
        sample_text.SetTextSize(FONT_SIZE)
        sample_text.SetTextAlign(ROOT.kHAlignRight + ROOT.kVAlignBottom)
        sample_text.SetBorderSize(0)
        sample_text.SetFillStyle(0)
        sample_text.Draw()

        other_elements = [jec_text, dir_text, sample_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input, mydir)

        # Do all flavs rsp vs pt for given eta bin
        common_eta_bins = cu.sort_human(cu.get_common_eta_bins(obj_list))
        for eta_bin in common_eta_bins[:]:
            entries = []
            contributions = []
            for fdict in entry_dicts:
                entry = deepcopy(fdict)
                # entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                entry["obj"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                entry["line_color"] = fdict['colour']
                entry["marker_color"] = fdict['colour']
                # entries.append(entry)

                del entry['flav']
                del entry['colour']
                this_contrib = Contribution(**entry)
                contributions.append(this_contrib)

            bin_title = eta_bin.replace("to", " < |#eta| < ").replace("JetEta", "")
            do_comparison_graph(contributions, bin_title=bin_title,
                                xtitle="p_{T}^{Gen} [GeV]", ytitle="Response", logx=True,
                                xlimits=(10, 5000), 
                                ylimits=eta_bin_limits.get(eta_bin, None),
                                y_limit_protection=(0.5, 1.7),
                                other_elements=other_elements,
                                output_filename=os.path.join(plot_dir, "rsp_vs_pt_%s.pdf" % (eta_bin)),
                                ratio_limits=eta_bin_ratio_limits.get(eta_bin, None)
                                )

            # Inverse response ie ~ correction
            # entries = []
            # for fdict in entry_dicts:
            #     entry = deepcopy(fdict)
            #     entry["graph"] = construct_inverse_graph(cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin)))
            #     entry["line_color"] = fdict['colour']
            #     entry["marker_color"] = fdict['colour']
            #     entries.append(entry)
            # bin_title = eta_bin.replace("to", " < |#eta| < ").replace("JetEta", "")
            # do_comparison_graph(entries, bin_title=bin_title,
            #                     xtitle="p_{T}^{Gen} [GeV]", ytitle="1/Response", logx=True,
            #                     y_limit_protection=(0.8, 1.2),
            #                     other_elements=other_elements,
            #                     output_filename=os.path.join(plot_dir, "inv_rsp_vs_pt_%s.pdf" % (eta_bin)))

        # Do all flavs rsp vs eta for given pt bin
        # common_pt_bins = cu.get_common_pt_bins(obj_list)
        # for pt_bin in common_pt_bins:
        #     entries = []
        #     contributions = []
        #     for fdict in entry_dicts:
        #         entry = deepcopy(fdict)
        #         # entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta"), pt_bin))
        #         entry["obj"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta"), pt_bin))
        #         entry["line_color"] = fdict['colour']
        #         entry["marker_color"] = fdict['colour']
        #         # entries.append(entry)

        #         del entry['flav']
        #         del entry['colour']
        #         this_contrib = Contribution(**entry)
        #         contributions.append(this_contrib)
            
        #     bin_title = pt_bin.replace("to", " < p_{T} < ").replace("RefPt", "")
        #     do_comparison_graph(contributions, bin_title=bin_title + " GeV",
        #                         xtitle="|#eta|", ytitle="Response",
        #                         xlimits=(0, 5.2), y_limit_protection=(0.5, 1.5),
        #                         other_elements=other_elements,
        #                         output_filename=os.path.join(plot_dir, "rsp_vs_eta_%s.pdf" % (pt_bin)))

            # Inverse response ie ~ correction
            # entries = []
            # for fdict in entry_dicts:
            #     entry = deepcopy(fdict)
            #     entry["graph"] = construct_inverse_graph(cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'].replace("RefPt", "JetEta"), pt_bin)))
            #     entry["line_color"] = fdict['colour']
            #     entry["marker_color"] = fdict['colour']
            #     entries.append(entry)
            # bin_title = pt_bin.replace("to", " < p_{T} < ").replace("RefPt", "")
            # do_comparison_graph(entries, bin_title=bin_title + " GeV",
            #                     xtitle="|#eta|", ytitle="1/Response",
            #                     y_limit_protection=(0.8, 1.6),
            #                     other_elements=other_elements,
            #                     output_filename=os.path.join(plot_dir, "inv_rsp_vs_eta_%s.pdf" % (pt_bin)))


        # Do all flavs resolution vs pt for given eta bin
        # for eta_bin in common_eta_bins:
        #     entries = []
        #     for fdict in entry_dicts:
        #         entry = deepcopy(fdict)
        #         entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'].replace("Rsp", "Res", 1), eta_bin))
        #         entry["line_color"] = fdict['colour']
        #         entry["marker_color"] = fdict['colour']
        #         entries.append(entry)
        #     bin_title = eta_bin.replace("to", " < |#eta| < ").replace("JetEta", "")
        #     do_comparison_graph(entries, bin_title=bin_title,
        #                         xtitle="p_{T}^{Gen} [GeV]", ytitle="Relative resolution", logx=True,
        #                         y_limit_protection=(0, 0.5), draw_fits=False,
        #                         ylimits=(0, 0.5),
        #                         xlimits=(10, 5000), other_elements=other_elements,
        #                         output_filename=os.path.join(plot_dir, "res_vs_pt_%s.pdf" % (eta_bin)))

        # Do all flavs resolution plots vs eta for given pt bin
        # for pt_bin in common_pt_bins:
        #     entries = []
        #     for fdict in entry_dicts:
        #         entry = deepcopy(fdict)
        #         entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'].replace("Rsp", "Res", 1).replace("RefPt", "JetEta"), pt_bin))
        #         entry["line_color"] = fdict['colour']
        #         entry["marker_color"] = fdict['colour']
        #         entries.append(entry)
        #     bin_title = pt_bin.replace("to", " < p_{T} < ").replace("RefPt", "")
        #     do_comparison_graph(entries, bin_title=bin_title + " GeV",
        #                         xtitle="|#eta|", ytitle="Relative resolution", other_elements=other_elements,
        #                         y_limit_protection=(0, 0.5), draw_fits=True, xlimits=(0, 5.2),
        #                         output_filename=os.path.join(plot_dir, "res_vs_eta_%s.pdf" % (pt_bin)))

    return 0
Exemple #25
0
def main(in_args=sys.argv[1:]):
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=cu.CustomFormatter)
    parser.add_argument("input",
                        help="input ROOT/txt filename")
    parser.add_argument("lut",
                        help="output LUT filename",
                        default="my_lut.txt")
    parser.add_argument("--text",
                        help="Read correction functions from text file instead of ROOT file",
                        action='store_true')
    parser.add_argument("--gct",
                        help="Make LUT for GCT",
                        action='store_true')
    parser.add_argument("--stage1",
                        help="Make LUT for Stage 1",
                        action='store_true')
    parser.add_argument("--stage2",
                        help="Make LUT for Stage 2",
                        action='store_true')
    parser.add_argument("--stage2Func",
                        help="Make function params file for Stage 2",
                        action='store_true')
    parser.add_argument("--lowPtPlateau",
                        help="This checks for low pT turnover and caps the correction "
                        "value below that to a constant factor.",
                        action='store_true')
    parser.add_argument("--constantHF",
                        help="This calculates a constant correciton factor for HF bins.",
                        action='store_true')
    parser.add_argument("--plots",
                        help="Make plots to check sensibility of correction functions.",
                        action='store_true')
    parser.add_argument("--ptCompressionFile",
                        help="Human-readable pT compression LUT to use instead of deriving one  (Stage 2 only)",
                        default=None)
    args = parser.parse_args(args=in_args)

    print args

    if not any([args.gct, args.stage1, args.stage2, args.stage2Func]):
        print "You didn't pick which trigger version for the corrections - not making a corrections file unless you choose!"
        exit()

    if args.text and args.lowPtPlateau:
        print "You have selected both a text file correction input format"
        print "and the option of using lowPtPlateau"
        print "but the latter only works for ROOT file inputs!"
        print "ReThink yo options...Exiting..."
        exit()

    out_dir = os.path.join(os.path.dirname(args.input),
                           os.path.splitext(os.path.basename(args.lut))[0])
    cu.check_dir_exists_create(out_dir)

    all_fit_params = []
    all_fits = []
    all_graphs = []

    if args.text:
        all_fits, all_fit_params = get_functions_params_textfile(args.input)
    else:
        all_fits, all_fit_params, all_graphs = get_functions_graphs_params_rootfile(args.input)

    # Check we have the correct number
    etaBins = binning.eta_bins
    if len(all_fits) + 1 != len(etaBins):
        raise Exception("Incorrect number of fit functions "
                        "for corresponding number of eta bins")
    if len(all_fit_params) + 1 != len(etaBins):
        raise Exception("Incorrect number of fit params "
                        "for corresponding number of eta bins")

    # Plot all functions on one canvas, zommed in on low pt & whole pt range
    plot_file = os.path.join(out_dir, "all_raw_fits_ptZoomed.pdf")
    plot_all_functions(all_fits, plot_file, etaBins, et_min=0, et_max=30)
    plot_file = os.path.join(out_dir, "all_raw_fits.pdf")
    plot_all_functions(all_fits, plot_file, etaBins, et_min=0, et_max=1024)

    # Make LUTs
    if args.gct:
        print_GCT_lut_file(all_fit_params, etaBins, args.lut)

    elif args.stage1:
        fits = do_low_pt_plateau_fits(all_fits, all_graphs, ignore_hf=False, condition=0.05, look_ahead=0) if args.lowPtPlateau else all_fits

        if args.plots:
            # plot the fancy fits
            for i, (total_fit, gr) in enumerate(izip(fits, all_graphs)):
                plot_file = os.path.join(out_dir, "fancyfit_%d.pdf" % i)
                plot_graph_function(i, gr, total_fit, plot_file)
        print_Stage1_lut_file(fits, args.lut, args.plots)

    elif args.stage2 or args.stage2Func:
        # do fancy fits: low Pt cap, and/or constant HF
        fits = all_fits
        if args.lowPtPlateau:
            fits = do_low_pt_plateau_fits(fits, all_graphs, ignore_hf=False, condition=0.075, look_ahead=5)
        if args.constantHF:
            fits = do_constant_hf_fits(fits, all_graphs, plot_dir=out_dir)
        if args.plots:
            # plot the fancy fits
            if not args.text:
                for i, (total_fit, gr) in enumerate(izip(fits, all_graphs)):
                    plot_file = os.path.join(out_dir, "fancyfit_%d.pdf" % i)
                    plot_graph_function(i, gr, total_fit, plot_file)
                plot_all_graph_functions(all_graphs, fits, os.path.join(out_dir, "fancyfit_all.pdf"))
                plot_all_graph_functions(all_graphs, None, os.path.join(out_dir, "fancyfit_all_gr.pdf"))
                plot_all_graph_functions(None, fits, os.path.join(out_dir, "fancyfit_all_fn.pdf"))

        if args.stage2:
            lut_base, ext = os.path.splitext(os.path.basename(args.lut))
            eta_lut_filename = os.path.join(out_dir, lut_base + '_eta' + ext)
            pt_lut_filename = os.path.join(out_dir, lut_base + '_pt' + ext)
            mult_lut_filename = os.path.join(out_dir, lut_base + "_mult" + ext)
            add_lut_filename = os.path.join(out_dir, lut_base + "_add" + ext)
            add_mult_lut_filename = os.path.join(out_dir, lut_base + "_add_mult" + ext)
            print_Stage2_lut_files(fit_functions=fits,
                                   eta_lut_filename=eta_lut_filename,
                                   pt_lut_filename=pt_lut_filename,
                                   mult_lut_filename=mult_lut_filename,
                                   add_lut_filename=add_lut_filename,
                                   add_mult_lut_filename=add_mult_lut_filename,
                                   right_shift=9,
                                   num_corr_bits=10,
                                   num_add_bits=8,
                                   plot_dir=out_dir,
                                   # read_pt_compression='lut_pt_compress.txt'
                                   read_pt_compression=args.ptCompressionFile,
                                   target_num_pt_bins=2**4,
                                   merge_criterion=1.05,
                                   merge_algorithm='greedy')  # greedy or kmeans
        else:
            print_Stage2_func_file(fits, args.lut)
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", help="Input ROOT file with correction graphs", required=True)
    parser.add_argument("--outputDir", help="Output directory for plots", default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots", default="")
    parser.add_argument("--sampleName", help="Sample name string for plots", default="")
    args = parser.parse_args(in_args)

    cu.check_dir_exists_create(args.outputDir)

    lw = 1
    entry_dicts = [
        {"flav": "AbsCorVsJetPt", "label": "All", "colour": ROOT.kBlack, "marker_style": ROOT.kFullCircle, "line_style": 2, "line_width": lw, "marker_size": 1.2},
        {"flav": "ud_AbsCorVsJetPt", "label": "ud", "colour": ROOT.kRed, "marker_style": ROOT.kFullSquare, "line_style": 1, "line_width": lw, "marker_size": 1.2},
        {"flav": "s_AbsCorVsJetPt", "label": "s", "colour": ROOT.kBlue, "marker_style": ROOT.kFullTriangleUp, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "c_AbsCorVsJetPt", "label": "c", "colour": ROOT.kGreen+2, "marker_style": ROOT.kFullTriangleDown, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "b_AbsCorVsJetPt", "label": "b", "colour": ROOT.kOrange-3, "marker_style": ROOT.kFullDiamond, "line_style": 1, "line_width": lw, "marker_size": 1.6},
        {"flav": "g_AbsCorVsJetPt", "label": "g", "colour": ROOT.kAzure+1, "marker_style": 29, "line_style": 1, "line_width": lw, "marker_size": 1.8},
    ]


    all_dirs = cu.get_list_of_element_names(cu.open_root_file(args.input))
    dirs = sorted(list(all_dirs))[:1]
    print("Doing: ", dirs)
    # Loop through all different ak4pfchs, etc
    for mydir in dirs:
        jec_text = ROOT.TPaveText(0.15, 0.91, 0.2, 0.92, "NDC")
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.76, 0.2, 0.77, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace("PUPPI", " PUPPI").replace("L1L2L3", " + L1L2L3")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        sample_text = ROOT.TPaveText(0.93, 0.91, 0.94, 0.92, "NDC")
        # sample_text.AddText("Flat QCD 13 TeV")
        sample_text.AddText(args.sampleName + " 13 TeV")
        sample_text.SetTextFont(42)
        sample_text.SetTextSize(FONT_SIZE)
        sample_text.SetTextAlign(ROOT.kHAlignRight + ROOT.kVAlignBottom)
        sample_text.SetBorderSize(0)
        sample_text.SetFillStyle(0)
        sample_text.Draw()

        other_elements = [jec_text, dir_text, sample_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input, mydir)

        # ylimits = (float(args.ylim[0]), float(args.ylim[1])) if args.ylim else None
        ylimits = None

        X_MIN, X_MAX = 8, 5000
        # For limit protection:
        Y_MIN, Y_MAX = 0.8, 1.6

        # Do all flavs corr vs pt for given eta bin
        common_eta_bins = cu.sort_human(cu.get_common_eta_bins(obj_list))
        # Find the matching + and - eta bins
        eta_bin_pairs = make_pos_neg_eta_pairs(common_eta_bins)
        print(eta_bin_pairs)

        for eta_bin_pair in eta_bin_pairs:
            all_entries = []
            
            title = eta_bin_pair[0].replace("to", " < |#eta| < ").replace("JetEta", "")
            
            # Do a per-flavour comparison plot
            for fdict in entry_dicts:
                entries = []
                for ind, (eta_bin, label) in enumerate(zip(eta_bin_pair, ['+#eta', '-#eta'])):
                    entry = deepcopy(fdict)
                    entry["graph"] = cu.grab_obj_from_file(args.input, "%s/%s_%s" % (mydir, fdict['flav'], eta_bin))
                    entry['label'] += " [%s]" % label
                    entry["line_color"] = fdict['colour']+ind
                    entry["marker_color"] = fdict['colour']+ind
                    entry["fill_color"] = fdict['colour']+ind
                    entry["fill_style"] = 1001
                    entry["fill_alpha"] = 0.7
                    if ind == 1:
                        entry["marker_style"] = get_open_marker(entry['marker_style'])
                        entry["line_style"] += 1
                    if ind == 2:
                        entry["line_style"] += 1
                    if ind == 3:
                        entry["line_style"] += 1
                        entry["marker_style"] = get_open_marker(entry['marker_style'])
                    entries.append(entry)
                    all_entries.append(entry)

                do_comparison_graph(entries, title=title,
                                    xtitle="p_{T}^{Reco} [GeV]", ytitle="Correction", logx=True,
                                    xlimits=(X_MIN, X_MAX), y_limit_protection=(Y_MIN, Y_MAX), 
                                    ylimits=ylimits,
                                    other_elements=other_elements,
                                    output_filename=os.path.join(plot_dir, "compare_corr_vs_pt_%s_pos_neg_%s.pdf" % (eta_bin_pair[0], fdict['label'])))

            # Do a plot with all flavours
            do_comparison_graph(all_entries, title=title,
                                xtitle="p_{T}^{Reco} [GeV]", ytitle="Correction", logx=True,
                                xlimits=(X_MIN, X_MAX), y_limit_protection=(Y_MIN, Y_MAX),
                                other_elements=other_elements,
                                output_filename=os.path.join(plot_dir, "compare_corr_vs_pt_%s_pos_neg_allFlavs.pdf" % (eta_bin_pair[0])))
            
    return 0
    for workdir in workdirs:
        print(".Doing", workdir)
        # for filename in dy_filenames:
        for filename in qcd_filenames:
        # for filename in chain(qcd_filenames, dy_filenames):

            ifile = os.path.join(MAINDIR, workdir, filename)
            if not os.path.isfile(ifile):
                continue

            for hist_dir in hist_dirs:
                print("...Doing", hist_dir)

                dir_append = hist_dir.lower().replace("weight_", "")
                odir = os.path.join(MAINDIR, workdir, "var_jet_pt_weights_%s_%s" % (dir_append, filename.replace("uhh2.AnalysisModuleRunner.MC.MC_", "").replace(".root", "")))
                cu.check_dir_exists_create(odir)

                # do_weight_vs_pt_plot(input_filename=ifile,
                #                      output_filename=os.path.join(odir, "weight_vs_pt.pdf"))

                # do_weight_vs_genjet_pt_plot(input_filename=ifile,
                #                             output_filename=os.path.join(odir, "weight_vs_genjet_pt.pdf"))

                for ind, base_hname in enumerate(histnames):
                    hname = os.path.join(hist_dir, base_hname)
                    
                    tf = cu.open_root_file(ifile)
                    if not cu.exists_in_file(tf, hname):
                        continue

                    do_var_vs_pt_plot(histname=hname,
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--input",
        help=
        "Input ROOT file with response & resolution hists (from jet_response_fitter_x)",
        required=True)
    parser.add_argument("--outputDir",
                        help="Output directory for plots",
                        default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots", default="")
    parser.add_argument("--sampleName",
                        help="Sample name string for plots",
                        default="")
    parser.add_argument("--plotN",
                        help="Plot grpah of N vs pT that goes into the median",
                        action='store_true')
    parser.add_argument(
        "--plotRMS",
        help="Plot graph of raw RMS vs pT that goes into memdian",
        action='store_true')
    args = parser.parse_args(in_args)

    cu.check_dir_exists_create(args.outputDir)

    lw = 2
    entry_dicts = [
        {
            "flav": "RelRsp",
            "label": "All",
            "colour": ROOT.kBlack,
            "marker_style": ROOT.kFullCircle,
            "line_style": 2,
            "line_width": lw,
            "marker_size": 1.2
        },
        {
            "flav": "ud_RelRsp",
            "label": "ud",
            "colour": ROOT.kRed,
            "marker_style": ROOT.kFullSquare,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.2
        },
        {
            "flav": "s_RelRsp",
            "label": "s",
            "colour": ROOT.kBlue,
            "marker_style": ROOT.kFullTriangleUp,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.4
        },
        {
            "flav": "c_RelRsp",
            "label": "c",
            "colour": ROOT.kGreen + 2,
            "marker_style": ROOT.kFullTriangleDown,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.4
        },
        {
            "flav": "b_RelRsp",
            "label": "b",
            "colour": ROOT.kOrange - 3,
            "marker_style": ROOT.kFullDiamond,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.6
        },
        {
            "flav": "g_RelRsp",
            "label": "g",
            "colour": ROOT.kAzure + 1,
            "marker_style": 29,
            "line_style": 1,
            "line_width": lw,
            "marker_size": 1.8
        },
    ]

    # Loop through all different ak4pfchs, etc
    input_tfile = cu.open_root_file(args.input)
    dirs = cu.get_list_of_element_names(input_tfile)
    for mydir in dirs[:1]:
        jec_text = ROOT.TPaveText(0.14, 0.91, 0.2, 0.92, "NDC")
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.72, 0.2, 0.73, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace(
            "PUPPI", " PUPPI").replace("L1L2L3",
                                       " + L1L2L3").replace("L1", " + L1")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        sample_text = ROOT.TPaveText(0.91, 0.91, 0.97, 0.92, "NDC")
        sample_text.AddText(args.sampleName + " 13 TeV")
        sample_text.SetTextFont(42)
        sample_text.SetTextSize(FONT_SIZE)
        sample_text.SetTextAlign(ROOT.kHAlignRight + ROOT.kVAlignBottom)
        sample_text.SetBorderSize(0)
        sample_text.SetFillStyle(0)
        sample_text.Draw()

        other_elements = [jec_text, dir_text, sample_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input, mydir)

        # Do separate dir for each eta bin, then separate plot for each pt bin
        common_eta_bins = cu.sort_human(cu.get_common_eta_bins(obj_list))
        common_pt_bins = cu.sort_human(cu.get_common_pt_bins(obj_list))
        print("Doing eta bins", common_eta_bins)
        print("Doing pt bins", common_pt_bins)

        for eta_bin in common_eta_bins[:]:
            this_plot_dir = os.path.join(plot_dir, eta_bin)
            cu.check_dir_exists_create(this_plot_dir)

            all_pt_entries = []
            for pt_bin in common_pt_bins:
                entries = []
                if not cu.exists_in_file(
                        input_tfile, "%s/%s_%s_%s" %
                    (mydir, entry_dicts[0]['flav'], eta_bin, pt_bin)):
                    continue
                for fdict in entry_dicts:
                    entry = deepcopy(fdict)
                    # entry["hist"] = cu.grab_obj_from_file(args.input, "%s/%s_%s_%s" % (mydir, fdict['flav'], eta_bin, pt_bin))
                    entry["hist"] = cu.get_from_tfile(
                        input_tfile, "%s/%s_%s_%s" %
                        (mydir, fdict['flav'], eta_bin, pt_bin))
                    entry["hist"].Rebin(int(entry["hist"].GetNbinsX() / 200))
                    entry["line_color"] = fdict['colour']
                    entry["marker_color"] = fdict['colour']
                    entries.append(entry)
                bin_title = eta_bin.replace("to", " < |#eta| < ").replace(
                    "JetEta", "")
                bin_title += "\n"
                bin_title += pt_bin.replace("to", " < p^{Gen}_{T} < ").replace(
                    "RefPt", "")
                bin_title += " GeV"
                norm_entries = deepcopy(entries)
                do_comparison_hist(
                    entries,
                    bin_title=bin_title,
                    xlimits=(0, 2),
                    xtitle="Response (p_{T}^{Reco} / p_{T}^{Gen})",
                    ytitle="N",
                    other_elements=other_elements,
                    normalise=False,
                    output_filename=os.path.join(
                        this_plot_dir, "rsp_vs_pt_%s.pdf" % (pt_bin)))

                all_pt_entries.append(deepcopy(entries))
                do_comparison_hist(
                    norm_entries,
                    bin_title=bin_title,
                    xlimits=(0, 2),
                    xtitle="Response (p_{T}^{Reco} / p_{T}^{Gen})",
                    ytitle="p.d.f",
                    other_elements=other_elements,
                    normalise=True,
                    draw_fits=False,
                    output_filename=os.path.join(
                        this_plot_dir, "rsp_vs_pt_%s_normed.pdf" % (pt_bin)))

            this_dir_text = dir_text.Clone()
            this_dir_text.SetY1(0.76)
            this_dir_text.SetY2(0.77)
            bin_title = eta_bin.replace("to",
                                        " < |#eta| < ").replace("JetEta", "")
            do_flavour_fraction_graph(
                all_pt_entries,
                common_pt_bins,
                title=bin_title,
                xtitle="p^{Gen}_{T} [GeV]",
                ytitle="Flavour fraction",
                other_elements=[jec_text, this_dir_text, sample_text],
                add_unknown=False,
                logx=True,
                logy=True,
                output_filename=os.path.join(
                    plot_dir, "flav_frac_vs_pt_%s.pdf" % (eta_bin)))

            if args.plotN:
                do_plot_N_graph(
                    all_pt_entries,
                    common_pt_bins,
                    title=bin_title,
                    which="GetEffectiveEntries",
                    xtitle="p^{Gen}_{T} [GeV]",
                    other_elements=[jec_text, this_dir_text, sample_text],
                    logx=True,
                    logy=True,
                    output_filename=os.path.join(
                        plot_dir, "Neff_vs_pt_%s.pdf" % (eta_bin)))

            if args.plotRMS:
                do_plot_RMS_graph(
                    all_pt_entries,
                    common_pt_bins,
                    title=bin_title,
                    xtitle="p^{Gen}_{T} [GeV]",
                    other_elements=[jec_text, this_dir_text, sample_text],
                    logx=True,
                    logy=True,
                    output_filename=os.path.join(
                        plot_dir, "RMS_vs_pt_%s.pdf" % (eta_bin)))

    return 0
def do_response_plot(tdir,
                     plot_dir,
                     var_name,
                     xlabel,
                     log_var=False,
                     rebinx=1,
                     rebiny=1,
                     do_migration_summary_plots=True,
                     do_resolution_plots=True,
                     save_response_hists=False):
    """Do 2D plots of genjet pt vs recojet pt"""
    h2d_orig = cu.get_from_tfile(tdir, var_name)
    h2d = h2d_orig.Clone(cu.get_unique_str())
    h2d.RebinX(rebinx)
    h2d.RebinY(rebiny)

    pt_regions = [
        {
            "append": "_lowPt",
            "title": "30 < p_{T}^{Reco} < 100 GeV",
        },
        {
            "append": "_midPt",
            "title": "100 < p_{T}^{Reco} < 250 GeV",
        },
        {
            "append": "_highPt",
            "title": "p_{T}^{Reco} > 250 GeV",
        },
    ]

    pt_bin_name = ""
    for region in pt_regions:
        if region['append'] in var_name:
            pt_bin_name = region['title']

    title = "%s;%s (GEN);%s (RECO)" % (pt_bin_name, xlabel, xlabel)
    # title = pt_bin_name

    canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
    draw_opt = "COLZ TEXT"
    draw_opt = "COLZ"
    pad = ROOT.gPad
    pad.SetBottomMargin(0.12)
    pad.SetLeftMargin(0.13)
    pad.SetRightMargin(0.12)
    canv.SetTicks(1, 1)
    if log_var:
        canv.SetLogx()
        canv.SetLogy()

    # un normalised
    h2d.SetTitle(title)
    h2d.Draw(draw_opt)
    xax = h2d.GetXaxis()
    upper_lim = xax.GetBinUpEdge(xax.GetLast())
    # print(upper_lim)
    # upper_lim = 5000
    title_offset = 1.5
    h2d.SetTitleOffset(title_offset, 'X')
    xax.SetMoreLogLabels()

    yax = h2d.GetYaxis()
    h2d.SetTitleOffset(title_offset * 1.15, 'Y')
    yax.SetMoreLogLabels()
    canv.Update()

    plot_dir = os.path.join(plot_dir, tdir.GetName())
    cu.check_dir_exists_create(plot_dir)
    canv.SaveAs(os.path.join(plot_dir, "%s_linZ.%s" % (var_name, OUTPUT_FMT)))
    canv.SetLogz()
    canv.SaveAs(os.path.join(plot_dir, "%s_logZ.%s" % (var_name, OUTPUT_FMT)))

    #  renorm by row (reco bins)
    canv.SetLogz(0)
    h2d_renorm_y = cu.make_normalised_TH2(h2d,
                                          'Y',
                                          recolour=True,
                                          do_errors=True)
    h2d_renorm_y.SetMarkerSize(0.5)
    h2d_renorm_y.SetMaximum(1)
    h2d_renorm_y.Draw(draw_opt)
    xax = h2d_renorm_y.GetXaxis()
    upper_lim = xax.GetBinUpEdge(xax.GetLast())
    # print(upper_lim)
    # upper_lim = 5000
    title_offset = 1.5
    h2d_renorm_y.SetTitleOffset(title_offset, 'X')
    # xax.SetRangeUser(0, upper_lim)
    xax.SetMoreLogLabels()

    yax = h2d_renorm_y.GetYaxis()
    h2d_renorm_y.SetTitleOffset(title_offset * 1.15, 'Y')
    # yax.SetRangeUser(0, upper_lim)
    yax.SetMoreLogLabels()
    canv.Update()

    canv.SaveAs(
        os.path.join(plot_dir, "%s_renormY_linZ.%s" % (var_name, OUTPUT_FMT)))
    canv.SetLogz()
    h2d_renorm_y.SetMaximum(1)
    h2d_renorm_y.SetMinimum(1E-3)
    canv.SaveAs(
        os.path.join(plot_dir, "%s_renormY_logZ.%s" % (var_name, OUTPUT_FMT)))

    # renorm by column (gen bins)
    canv.Clear()
    canv.SetLogz(0)
    h2d_renorm_x = cu.make_normalised_TH2(h2d,
                                          'X',
                                          recolour=True,
                                          do_errors=True)
    h2d_renorm_x.SetMarkerSize(0.5)
    h2d_renorm_x.SetMaximum(1)
    h2d_renorm_x.Draw(draw_opt)

    xax = h2d_renorm_x.GetXaxis()
    upper_lim = xax.GetBinUpEdge(xax.GetLast())
    # upper_lim = 5000
    title_offset = 1.5
    h2d_renorm_x.SetTitleOffset(title_offset, 'X')
    # xax.SetRangeUser(0, upper_lim)
    xax.SetMoreLogLabels()

    yax = h2d_renorm_x.GetYaxis()
    h2d_renorm_x.SetTitleOffset(title_offset * 1.15, 'Y')
    # yax.SetRangeUser(0, upper_lim)
    yax.SetMoreLogLabels()
    canv.Update()
    canv.SaveAs(
        os.path.join(plot_dir, "%s_renormX_linZ.%s" % (var_name, OUTPUT_FMT)))
    canv.SetLogz()
    h2d_renorm_x.SetMaximum(1)
    h2d_renorm_x.SetMinimum(1E-3)
    canv.SaveAs(
        os.path.join(plot_dir, "%s_renormX_logZ.%s" % (var_name, OUTPUT_FMT)))

    # Now do plot of purity, etc
    if do_migration_summary_plots:
        qgg.make_migration_summary_plot(
            h2d_renorm_x,
            h2d_renorm_y,
            xlabel=xlabel,
            output_filename=os.path.join(
                plot_dir, '%s_migration_summary.%s' % (var_name, OUTPUT_FMT)),
            log_var=log_var)

    # Do resolution plots
    if do_resolution_plots:
        res_rms, rel_res_rms = make_resolution_plots(
            h2d_orig,
            xlabel=xlabel,
            output_filename=os.path.join(
                plot_dir,
                '%s_resolution_summary_rms.%s' % (var_name, OUTPUT_FMT)),
            do_fit=False,
            do_rms=True,
            log_var=log_var,
            save_response_hists=False)

        res_quantiles, rel_res_quantiles = make_resolution_plots(
            h2d_orig,
            xlabel=xlabel,
            output_filename=os.path.join(
                plot_dir,
                '%s_resolution_summary_quantiles.%s' % (var_name, OUTPUT_FMT)),
            do_fit=False,
            do_rms=False,
            quantiles=None,  # auto determine
            log_var=log_var,
            save_response_hists=save_response_hists)

        # compare RMS and quantile results
        conts = [
            Contribution(
                res_rms,
                label="#sqrt{RMS} #pm #frac{#sqrt{#delta RMS}}{#LT %s #GT}" %
                (xlabel),
                line_color=ROOT.kRed,
                marker_color=ROOT.kRed),
            Contribution(res_quantiles,
                         label="68% quantile",
                         line_color=ROOT.kBlue,
                         marker_color=ROOT.kBlue)
        ]
        ylabel = "#frac{#sigma(RECO/GEN)}{GEN}" if "_rel_" in var_name else "#frac{#sigma(RECO)}{GEN}"
        res_plot = Plot(conts,
                        what='graph',
                        xtitle=xlabel,
                        ytitle=ylabel,
                        legend=True,
                        ylim=[0, 3])
        res_plot.legend.SetX1(0.5)
        res_plot.legend.SetX2(0.9)
        res_plot.legend.SetY1(0.7)
        res_plot.legend.SetY2(0.85)
        res_plot.plot('ALP')
        res_plot.save(
            os.path.join(
                plot_dir,
                '%s_resolution_rms_vs_quantiles.%s' % (var_name, OUTPUT_FMT)))
def main(in_args):
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", help="Input ROOT file with response hists", action='append')
    parser.add_argument("--label", help="Label for input file", action='append')
    parser.add_argument("--outputDir", help="Output directory for plots", default=os.getcwd())
    parser.add_argument("--title", help="Title string for plots")
    parser.add_argument("--sampleName", help="Sample name string for plots", default="")
    parser.add_argument("--slides", help="Dump JSON snippet to file for use with beamer-plot-slides", default=None)
    parser.add_argument("--plotResponseHists", help="Plot individual response hists", action='store_true')
    parser.add_argument("--plotN", help="Plot graph of N vs pT that goes into the median", action='store_true')
    parser.add_argument("--plotRMS", help="Plot graph of raw RMS vs pT that goes into memdian", action='store_true')
    args = parser.parse_args(in_args)

    if not args.input or len(args.input) == 0:
        return 1
    
    cu.check_dir_exists_create(args.outputDir)

    if len(args.input) != len(args.label):
        raise RuntimeError("Need a --label for each --input")

    lw = 2
    entry_dicts = [
        {"flav": "RelRsp", "label": "All", "colour": ROOT.kBlack, "marker_style": ROOT.kFullCircle, "line_style": 1, "line_width": lw, "marker_size": 1.2},
        {"flav": "ud_RelRsp", "label": "ud", "colour": ROOT.kRed, "marker_style": ROOT.kFullSquare, "line_style": 1, "line_width": lw, "marker_size": 1.2},
        {"flav": "g_RelRsp", "label": "g", "colour": ROOT.kAzure+1, "marker_style": 29, "line_style": 1, "line_width": lw, "marker_size": 1.8},
        {"flav": "s_RelRsp", "label": "s", "colour": ROOT.kBlue, "marker_style": ROOT.kFullTriangleUp, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "c_RelRsp", "label": "c", "colour": ROOT.kGreen+2, "marker_style": ROOT.kFullTriangleDown, "line_style": 1, "line_width": lw, "marker_size": 1.4},
        {"flav": "b_RelRsp", "label": "b", "colour": ROOT.kOrange-3, "marker_style": ROOT.kFullDiamond, "line_style": 1, "line_width": lw, "marker_size": 1.6},
    ]

    # Loop through all different ak4pfchs, etc
    all_dirs = [set(cu.get_list_of_element_names(cu.open_root_file(infile))) for infile in args.input]
    dirs = all_dirs[0]
    for d in all_dirs[1:]:
        dirs = dirs & d
    dirs = sorted(list(dirs))[:1]
    print("Doing: ", dirs)
    for mydir in dirs[:]:
        jec_text = ROOT.TPaveText(0.15, 0.93, 0.2, 0.94, "NDC")
        # jec_label = "Without JEC"
        # jec_label = "With JEC"
        # jec_label = "Summer16_23Sep2016V4"
        # jec_label = "Summer16_03Feb2017_V8"
        jec_text.AddText(args.title)
        jec_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        jec_text.SetTextFont(42)
        jec_text.SetTextSize(FONT_SIZE)
        jec_text.SetBorderSize(0)
        jec_text.SetFillStyle(0)

        dir_text = ROOT.TPaveText(0.17, 0.78, 0.2, 0.79, "NDC")
        dir_label = mydir.upper().replace("PFCHS", " PF CHS").replace("PUPPI", " PUPPI").replace("L1L2L3", " + L1L2L3").replace("L1", " + L1")
        dir_text.AddText(dir_label)
        dir_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        dir_text.SetTextFont(42)
        dir_text.SetTextSize(FONT_SIZE)
        dir_text.SetBorderSize(0)
        dir_text.SetFillStyle(0)

        other_elements = [jec_text, dir_text]

        plot_dir = os.path.join(args.outputDir, mydir)
        cu.check_dir_exists_create(plot_dir)

        obj_list = cu.get_list_of_objects_in_dir(args.input[0], mydir)

        # Do separate dir for each eta bin, then separate plot for each pt bin
        common_eta_bins = cu.sort_human(cu.get_common_eta_bins(obj_list))
        common_pt_bins = cu.sort_human(cu.get_common_pt_bins(obj_list))
        print("Doing eta bins", common_eta_bins)
        print("Doing pt bins", common_pt_bins)

        open_tfiles = []
        for input_filename in args.input:
            open_tfiles.append(cu.open_root_file(input_filename))

        for eta_bin in common_eta_bins[:]:
            this_plot_dir = os.path.join(plot_dir, eta_bin)
            cu.check_dir_exists_create(this_plot_dir)

            # Dict of all entries
            # key is input label
            # value is list of list of dicts
            all_entries = {}
            for label in args.label:
                all_entries[label] = []

            for pt_bin in common_pt_bins[:]:
                entries = []
                for ind, label in enumerate(args.label):
                    this_input_entries = []
                    for find, fdict in enumerate(entry_dicts):
                        entry = deepcopy(fdict)
                        try:
                            entry["hist"] = cu.get_from_tfile(open_tfiles[ind], "%s/%s_%s_%s" % (mydir, fdict['flav'], eta_bin, pt_bin))
                            entry["hist"].Rebin(int(entry["hist"].GetNbinsX()/200))
                            entry['label'] += " [%s]" % label
                            new_colour = cu.get_alternate_colour(fdict['colour'], ind)
                            entry["line_color"] = new_colour
                            entry["marker_color"] = new_colour
                            entry["fill_color"] = new_colour
                            entry["fill_style"] = 1001
                            entry["fill_alpha"] = 0.7
                            entry['ratio'] = None
                            if ind == 1:
                                entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
                                entry["line_style"] += 1
                            if ind == 2:
                                entry["line_style"] += 1
                            if ind == 3:
                                entry["line_style"] += 1
                                entry["marker_style"] = cu.get_open_marker(entry['marker_style'])
                            entries.append(entry)
                            this_input_entries.append(entry)
                        # if ind > 0:
                        #     entries[-1]['ratio'] = entries[-2]['hist']
                            # all_entries[label].append(deepcopy(entry))
                        except IOError:
                            pass
                    all_entries[label].append(this_input_entries)

                if len(entries) == 0:
                    continue

                bin_title = eta_bin.replace("to", " < #eta < ").replace("JetEta", "")
                bin_title += "\n"
                bin_title += pt_bin.replace("to", " < p^{Gen}_{T} < ").replace("RefPt", "")
                bin_title += " GeV"
                norm_entries = deepcopy(entries)
                rsp_str = "Response (p_{T}^{Reco} / p_{T}^{Gen})"
                if args.plotResponseHists:
                    do_comparison_hist(entries,
                                       bin_title=bin_title,
                                       xlimits=(0, 2),
                                       xtitle=rsp_str,
                                       ytitle="N",
                                       other_elements=other_elements,
                                       normalise=False,
                                       output_filename=os.path.join(this_plot_dir, "rsp_vs_pt_%s.pdf" % (pt_bin)))

                    do_comparison_hist(norm_entries,
                                       bin_title=bin_title,
                                       xlimits=(0, 2),
                                       xtitle=rsp_str,
                                       ytitle="p.d.f",
                                       other_elements=other_elements,
                                       normalise=True,
                                       draw_fits=False,
                                       output_filename=os.path.join(this_plot_dir, "rsp_vs_pt_%s_normed.pdf" % (pt_bin)))

            this_dir_text = dir_text.Clone()
            # this_dir_text.SetY1(0.76)
            # this_dir_text.SetY2(0.77)
            bin_title = eta_bin.replace("to", " < #eta < ").replace("JetEta", "")
            do_flavour_fraction_graph(all_entries, common_pt_bins, title=bin_title,
                                      xtitle="p^{Gen}_{T} [GeV]", ytitle="Flavour fraction",
                                      other_elements=other_elements,
                                      add_unknown=True, logx=True, logy=True,
                                      output_filename=os.path.join(plot_dir, "flav_frac_vs_pt_%s.pdf" % (eta_bin)))

            # if args.plotN:
            #     do_plot_N_graph(all_pt_entries, common_pt_bins, title=bin_title,
            #                     which="GetEffectiveEntries",
            #                     xtitle="p^{Gen}_{T} [GeV]",
            #                     other_elements=[jec_text, this_dir_text],
            #                     logx=True, logy=True,
            #                     output_filename=os.path.join(plot_dir, "Neff_vs_pt_%s.pdf" % (eta_bin)))

            # if args.plotRMS:
            #     do_plot_RMS_graph(all_pt_entries, common_pt_bins, title=bin_title,
            #                       xtitle="p^{Gen}_{T} [GeV]",
            #                       other_elements=[jec_text, this_dir_text],
            #                       logx=True, logy=True,
            #                       output_filename=os.path.join(plot_dir, "RMS_vs_pt_%s.pdf" % (eta_bin)))


    return 0