def do_all_1D_projection_plots_in_dir(directories,
                                      components_styles_dicts,
                                      output_dir,
                                      region_str=None,
                                      do_ratio=True,
                                      normalise_hists=True,
                                      jet_config_str="",
                                      title=None,
                                      bin_by=None):
    """
    Given a set of TDirs, loop over all 2D hists, do projection hists for chosen bins, and plot all TDir contributions on a canvas for comparison.

    components_styles_dicts should be a list of style dicts, one for each directory/contribution to a plot.
    This should include label for this component.

    """
    if len(directories) != len(components_styles_dicts):
        raise IndexError("Need same number of style dicts and directories")

    list_of_obj = [get_list_of_obj(d) for d in directories]

    # check all have same list of plots
    if not all(x == list_of_obj[0] for x in list_of_obj):
        print("Different number of object in the TDirectorys")

    common_list_of_obj = set(list_of_obj[0])
    for l in list_of_obj[1:]:
        common_list_of_obj = common_list_of_obj & set(l)
    common_list_of_obj = sorted(list(common_list_of_obj))

    pt_bins = qgc.PT_BINS

    lumi = cu.get_lumi_str(do_dijet=False, do_zpj=True)
    if "dijet" in region_str.lower():
        lumi = cu.get_lumi_str(do_dijet=True, do_zpj=False)

    show_integrals = not normalise_hists

    for obj_name in common_list_of_obj:

        if "flav" in obj_name:
            continue
        if obj_name in [
                'eta_jet1_vs_eta_jet2',
                'phi_jet1_vs_pt_jet1',
                'phi_jet2_vs_pt_jet1',
                # 'reliso_mu1_vs_pt_jet1', 'reliso_mu2_vs_pt_jet1',
                # 'dphi_mumu_jet1_vs_pt_jet1',
                # 'dphi_mumu_vs_pt_jet1',
                'pt_jet1_z_pt_jet2_z_ratio',
                # 'met_sig_vs_pt_jet1'
                'weight_vs_puHat_genHT_ratio',
                'eta_jet_response',
        ]:
            continue

        if "genjet_ind_recojet_ind" in obj_name:
            continue

        print("Doing:", obj_name)

        objs = [
            d.Get(obj_name).Clone(obj_name + str(uuid1())) for d in directories
        ]

        # Do TH1s separately
        if not isinstance(objs[0], (ROOT.TH2F, ROOT.TH2D, ROOT.TH2I)):
            logx = obj_name in [
                "pt_jet", "pt_jet1", "pt_jet2", "pt_mumu", 'gen_ht',
                'pt_jet_response_binning', 'pt_genjet_response_binning',
                'pt_jet1_unweighted', 'pt_jet_unweighted'
            ]

            this_title = (("{jet_algo}\n"
                           "{region_label}\n").format(jet_algo=jet_config_str,
                                                      region_label=region_str))
            if title is not None:
                this_title += "\n%s" % (title)

            # if obj_name in ['pt_jet', 'pt_jet1', 'pt_jet2', 'pt_mumu']:
            #     # small rebinned version
            #     for obj in objs:
            #         obj.Rebin(1)

            # if normalise_hists:
            do_1D_plot(objs,
                       components_styles_dicts=components_styles_dicts,
                       do_ratio=do_ratio,
                       normalise_hists=normalise_hists,
                       logx=logx,
                       logy=True,
                       title=this_title,
                       mean_rel_error=-1,
                       lumi=lumi,
                       show_integrals=show_integrals,
                       output_filename=os.path.join(
                           output_dir, obj_name + ".%s" % (OUTPUT_FMT)))

            # do a rebinned version for some variables
            if obj_name in [
                    'pt_jet', 'pt_jet1', 'pt_jet2', 'pt_mumu',
                    'pt_jet_response_binning'
            ]:
                for obj in objs:
                    if obj_name == 'pt_jet_response_binning':
                        obj.Rebin(2)  # to get gen level pt binning
                    else:
                        obj.Rebin(
                            20)  # this is multiplied by the previous rebin

                this_title = (("{jet_algo}\n"
                               "{region_label}\n").format(
                                   jet_algo=jet_config_str,
                                   region_label=region_str))
                if title is not None:
                    this_title += "\n%s" % (title)

                do_1D_plot(objs,
                           components_styles_dicts=components_styles_dicts,
                           do_ratio=do_ratio,
                           normalise_hists=normalise_hists,
                           logx=logx,
                           logy=True,
                           title=this_title,
                           lumi=lumi,
                           show_integrals=show_integrals,
                           output_filename=os.path.join(
                               output_dir,
                               obj_name + "_rebin.%s" % (OUTPUT_FMT)))

        else:

            for pt_min, pt_max in pt_bins:
                # print(pt_min, pt_max)
                rebin = 1
                # exceptions...why didn't I pick the same number of bins...
                do_not_rebin = any([
                    "n_jets" in obj_name,
                    "n_mu" in obj_name,
                    "met_sig" in obj_name,
                    # obj_name.startswith('dphi_mumu'),
                    obj_name.startswith('pt_jet3_frac'),
                    obj_name.startswith('pt_jet1_jet2_ratio'),
                    obj_name.startswith('pt_jet1_z_ratio'),
                    obj_name.startswith('pt_jet2_z_ratio'),
                    obj_name.startswith('dphi_jet1_z_vs_pt_jet1'),
                    # obj_name.startswith('m_jj'),
                ])
                if not do_not_rebin:
                    # if objs[0].GetNbinsX() % 5 == 0 and objs[0].GetNbinsX() >= 100:
                    #     rebin = 5
                    if objs[0].GetNbinsX() % 4 == 0 and objs[0].GetNbinsX(
                    ) >= 80:
                        rebin = 2
                    elif objs[0].GetNbinsX() % 3 == 0 and objs[0].GetNbinsX(
                    ) >= 60:
                        rebin = 3

                if obj_name.startswith("m_jj"):
                    rebin = 2
                if "reliso" in obj_name:
                    rebin = 1

                if "pt_jet1_vs_pt_z" in obj_name:
                    rebin = 20

                if "pt_mu1_vs_pt_z" in obj_name:
                    rebin = 10
                    if pt_min > 250:
                        rebin = 20

                if "pt_mu2_vs_pt_z" in obj_name:
                    rebin = 10
                    if pt_min > 250:
                        rebin = 25

                hists = [
                    qgp.get_projection_plot(ob, pt_min, pt_max) for ob in objs
                ]
                for h in hists:
                    h.Rebin(rebin)

                def _title(region_str, start_val, end_val):
                    pt_var_str = "p_{T}^{jet}"
                    if bin_by == "ave":
                        pt_var_str = "#LT p_{T}^{jet} #GT"
                    elif bin_by == "Z" and "_vs_pt_jet" not in obj_name:
                        pt_var_str = "p_{T}^{Z}"
                    s = (("{jet_algo}\n"
                          "{region_label}\n"
                          "{bin_edge_low:g} < {pt_str} < {bin_edge_high:g} GeV"
                          ).format(jet_algo=jet_config_str,
                                   region_label=region_str,
                                   pt_str=pt_var_str,
                                   bin_edge_low=start_val,
                                   bin_edge_high=end_val))
                    if title is not None:
                        s = "%s\n%s" % (s, title)
                    return s

                xtitle = None
                if "eta_jet1_vs_pt" in obj_name and "eta_ordered" in directories[
                        0].GetName().lower():
                    xtitle = "y^{forward jet}"
                elif "eta_jet2_vs_pt" in obj_name and "eta_ordered" in directories[
                        0].GetName().lower():
                    xtitle = "y^{central jet}"

                logx = any([
                    x in obj_name
                    for x in ['pt_jet_response', 'pt_jet1_vs_pt_z']
                ])

                logy = any([
                    x in obj_name
                    for x in ['pt_jet_response', 'pt_jet1_vs_pt_z']
                ])

                do_1D_plot(hists,
                           components_styles_dicts=components_styles_dicts,
                           do_ratio=do_ratio,
                           normalise_hists=normalise_hists,
                           logx=logx,
                           logy=logy,
                           title=_title(region_str, pt_min, pt_max),
                           xtitle=xtitle,
                           mean_rel_error=-1,
                           lumi=lumi,
                           show_integrals=show_integrals,
                           output_filename=os.path.join(
                               output_dir, obj_name + "_pt%dto%d.%s" %
                               (pt_min, pt_max, OUTPUT_FMT)))
Beispiel #2
0
def do_all_1D_projection_plots_in_dir(directories,
                                      output_dir,
                                      components_styles_dicts=None,
                                      draw_opts="NOSTACK HISTE",
                                      do_ratio=True,
                                      normalise_hists=True,
                                      filter_noisy=True,
                                      find_best_purity=False,
                                      signal_mask=None):
    """
    Given a set of TDirs, loop over all 2D hists, do projection hists for chosen bins, and plot all TDir contributions on a canvas for comparison.

    components_styles_dicts should be a list of style dicts, one for each directory/contribution to a plot.
    This should include label for this component.

    filter_noisy aims to remove low stats/large error components that muddle things up

    find_best_purity aism to find cut for best purity.
    signal_mask should be a list of bools to specify which directories are signal
    """
    if len(directories) != len(components_styles_dicts):
        raise IndexError("Need same number of style dicts and directories")

    list_of_obj = [get_list_of_obj(d) for d in directories]
    print(list_of_obj[0])

    # check all have same list of plots
    if not all(x == list_of_obj[0] for x in list_of_obj):
        print("Different number of object in the TDirectorys")

    common_list_of_obj = set(list_of_obj[0])
    for l in list_of_obj[1:]:
        common_list_of_obj = common_list_of_obj & set(l)

    pt_bins = [(20, 40), (40, 60), (60, 80), (100, 120), (160, 200),
               (260, 300), (500, 600), (1000, 2000)]

    for obj_name in common_list_of_obj:
        objs = [d.Get(obj_name) for d in directories]
        # Ignore TH1s
        if not isinstance(objs[0], (ROOT.TH2F, ROOT.TH2D, ROOT.TH2I)):
            print(obj_name, "is not a TH2")
            continue

        if "flav" in obj_name:
            continue

        if obj_name in [
                # 'eta_jet1_vs_eta_jet2',
                'phi_jet1_vs_pt_jet1',
                'phi_jet2_vs_pt_jet1',
                'reliso_mu1_vs_pt_jet1',
                'reliso_mu2_vs_pt_jet1',
                'dphi_mumu_jet1_vs_pt_jet1',
                'dphi_mumu_vs_pt_jet1',
                'pt_jet1_z_pt_jet2_z_ratio'
        ]:
            continue

        for pt_min, pt_max in pt_bins:
            # print(pt_min, pt_max)
            rebin = 1
            # exceptions...why didn't i pick the same number of bins...
            do_not_rebin = any([
                "n_jets" in obj_name,
                "n_mu" in obj_name,
                "met_sig" in obj_name,
                obj_name.startswith('dphi_mumu'),
                obj_name.startswith('pt_jet3_frac'),
                obj_name.startswith('pt_jet1_jet2_ratio'),
                obj_name.startswith('pt_jet1_z_ratio'),
                obj_name.startswith('pt_jet2_z_ratio'),
                obj_name.startswith('dphi_jet1_z_vs_pt_jet1'),
                # obj_name.startswith('m_jj'),
            ])
            if not do_not_rebin:
                if objs[0].GetNbinsX() % 5 == 0 and objs[0].GetNbinsX() >= 100:
                    rebin = 5
                elif objs[0].GetNbinsX() % 4 == 0 and objs[0].GetNbinsX(
                ) >= 80:
                    rebin = 2
                elif objs[0].GetNbinsX() % 3 == 0 and objs[0].GetNbinsX(
                ) >= 60:
                    rebin = 3
            if obj_name.startswith("m_jj"):
                rebin = 2
            hists = [
                qgg.get_projection_plot(ob, pt_min, pt_max) for ob in objs
            ]
            # need the clone in here as unnormalised hists are used for purity/eff scans
            contributions = [
                Contribution(hist.Clone(hist.GetName() + "Clone"),
                             normalise_hist=normalise_hists,
                             rebin_hist=rebin,
                             **csd)
                for hist, csd in zip(hists, components_styles_dicts)
            ]

            if len(contributions) == 0:
                continue
            # Ignore if all empty objs
            total_entries = sum(c.obj.GetEntries() for c in contributions)
            if total_entries == 0:
                continue

            if filter_noisy:
                # filter contributions to ensure odd low stat ones don't dominate the scale
                # combination of factors to remove noisy samples
                mean_errs = []
                max_over_mean_errs = []
                rel_err_vars = []
                for cont in contributions:
                    obj = cont.obj
                    errs = [
                        obj.GetBinError(i) for i in range(obj.GetNbinsX() + 1)
                    ]
                    if obj.GetEntries() > 0:
                        mean_errs.append(np.mean(errs))
                        max_over_mean_errs.append(np.max(errs) / np.mean(errs))
                        rel_err_vars.append(np.std(errs) / np.mean(errs))
                        # print("obj", cont.label)
                        # print('mean errs', np.mean(errs))
                        # print('rel max err', np.max(errs) / np.mean(errs))
                        # print('stddev err', np.std(errs))
                        # print('rel std dev err', np.std(errs) / np.mean(errs))
                    else:
                        # Dud values if 0 entries
                        mean_errs.append(9999999)
                        max_over_mean_errs.append(9999999)
                        rel_err_vars.append(9999999)

                ref_mean_err = np.median(mean_errs)
                ref_rel_err_var = np.median(rel_err_vars)
                # print('-'*20)
                # print('mean mean err', ref_mean_err)
                # print('mean var', ref_rel_err_var)
                contributions = [
                    cont for cont, merr, rev, mom in zip(
                        contributions, mean_errs, rel_err_vars,
                        max_over_mean_errs)
                    if (merr < 2.5 * ref_mean_err) and (
                        rev < 5 * ref_rel_err_var or mom < 5)
                ]

            purity_text = ROOT.TPaveText(0.6, 0.4, 0.95, 0.6, "NDC")
            purity_text.SetFillColor(ROOT.kWhite)
            purity_text.SetFillStyle(0)
            purity_text.SetLineWidth(0)
            purity_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignTop)

            if find_best_purity:
                if not signal_mask:
                    raise RuntimeError("Need signal_mask to find purity")
                if len(signal_mask) != len(directories):
                    raise RuntimeError(
                        "signal_mask must be same length as directories")

                signal_hists = [
                    h for h, mask in zip(hists, signal_mask) if mask
                ]
                bkg_hists = [
                    h for h, mask in zip(hists, signal_mask) if not mask
                ]

                signal_hist = signal_hists[0].Clone("Signal")
                if len(signal_hists) > 1:
                    for h in signal_hists[1:]:
                        signal_hist.Add(h)

                bkg_hist = bkg_hists[0].Clone("Background")
                if len(bkg_hists) > 1:
                    for h in bkg_hists[1:]:
                        bkg_hist.Add(h)

                signal = signal_hist.Integral()
                bkg = bkg_hist.Integral()
                starting_purity = 1. * signal / (signal + bkg)
                starting_purity_x_eff = starting_purity

                signal_cumul = signal_hist.GetCumulative()
                bkg_cumul = bkg_hist.GetCumulative()

                best_purity = starting_purity
                best_purity_x_eff = 1 * starting_purity
                best_purity_x_eff = 0
                purity_cut_value, purity_cut_type, purity_bin_ind = None, None, None
                purity_x_eff_cut_value, purity_x_eff_cut_type, purity_x_eff_bin_ind = None, None, None

                purity_x_effs_1, cut_vals_1 = [], []
                purity_x_effs_2, cut_vals_2 = [], []

                puritys_1, effs_1 = [], []
                puritys_2, effs_2 = [], []

                total_s = signal_hist.Integral()
                # try cut lower than X, see if any cut improves upon starting purity
                for i in range(1, signal_cumul.GetNbinsX() + 1):
                    s = signal_cumul.GetBinContent(i)
                    b = bkg_cumul.GetBinContent(i)
                    if s == 0 and b == 0:
                        this_purity = 0
                        this_purity_x_eff = 0
                    else:
                        this_purity = s / (s + b)
                        if s > total_s * 1.00001:
                            raise RuntimeError(
                                "s = %f, total_s = %f, something terribly wrong"
                                % (s, total_s))
                        this_eff = s / total_s
                        this_purity_x_eff = this_eff * this_purity
                        cut_vals_1.append(signal_cumul.GetBinLowEdge(i + 1))
                        purity_x_effs_1.append(this_purity_x_eff)
                        effs_1.append(this_eff)
                        puritys_1.append(this_purity)

                    # print("this_purity =", this_purity)
                    if this_purity > best_purity:
                        purity_cut_type = "<"
                        purity_bin_ind = i
                        purity_cut_value = signal_cumul.GetBinLowEdge(i + 1)
                        best_purity = this_purity
                    if this_purity_x_eff > best_purity_x_eff:
                        best_purity_x_eff = this_purity_x_eff
                        purity_x_eff_cut_type = "<"
                        purity_x_eff_bin_ind = i
                        purity_x_eff_cut_value = signal_cumul.GetBinLowEdge(i +
                                                                            1)

                # try cut below, see if any cut improves upon starting purity
                signal_cumul_rev = signal_hist.GetCumulative(False)
                bkg_cumul_rev = bkg_hist.GetCumulative(False)
                for i in range(1, signal_cumul_rev.GetNbinsX() + 1):
                    s = signal_cumul_rev.GetBinContent(i)
                    b = bkg_cumul_rev.GetBinContent(i)
                    if s == 0 and b == 0:
                        this_purity = 0
                        this_eff = 0
                    else:
                        this_purity = s / (s + b)
                        if s > total_s * 1.00001:
                            raise RuntimeError(
                                "s = %f, total_s = %f, something terribly wrong"
                                % (s, total_s))
                        this_eff = (s / total_s)
                        this_purity_x_eff = this_eff * this_purity
                        cut_vals_2.append(signal_cumul_rev.GetBinLowEdge(i +
                                                                         1))
                        purity_x_effs_2.append(this_purity_x_eff)
                        effs_2.append(this_eff)
                        puritys_2.append(this_purity)

                    # print("this_purity =", this_purity)
                    if this_purity > best_purity:
                        purity_cut_type = ">"
                        purity_bin_ind = i
                        purity_cut_value = signal_cumul_rev.GetBinLowEdge(i)
                        best_purity = this_purity
                    if this_purity_x_eff > best_purity_x_eff:
                        best_purity_x_eff = this_purity_x_eff
                        purity_x_eff_cut_type = ">"
                        purity_x_eff_bin_ind = i
                        purity_x_eff_cut_value = signal_cumul_rev.GetBinLowEdge(
                            i + 1)

                c = ROOT.TCanvas("ctmp", "", 600, 600)
                c.SetTicks(1, 1)
                gr = ROOT.TGraph(len(purity_x_effs_1), array('d', cut_vals_1),
                                 array('d', purity_x_effs_1))
                gr.SetMarkerStyle(22)
                gr2 = ROOT.TGraph(len(purity_x_effs_2), array('d', cut_vals_2),
                                  array('d', purity_x_effs_2))
                gr2.SetMarkerStyle(23)
                gr2.SetMarkerColor(ROOT.kBlue)
                mg = ROOT.TMultiGraph("mg",
                                      ";Cut value;Purity #times Efficiency")
                mg.Add(gr)
                mg.Add(gr2)
                mg.Draw("AP")
                c.SaveAs(
                    os.path.join(
                        output_dir, obj_name + "pt%dto%d_purity_x_eff.%s" %
                        (pt_min, pt_max, OUTPUT_FMT)))

                gr = ROOT.TGraph(len(puritys_1), array('d', effs_1),
                                 array('d', puritys_1))
                gr.SetMarkerStyle(22)
                gr2 = ROOT.TGraph(len(puritys_2), array('d', effs_2),
                                  array('d', puritys_2))
                gr2.SetMarkerStyle(23)
                gr2.SetMarkerColor(ROOT.kBlue)
                mg = ROOT.TMultiGraph("mg2", ";efficiency;purity")
                mg.Add(gr)
                mg.Add(gr2)
                mg.Draw("ALP")
                c.SaveAs(
                    os.path.join(
                        output_dir, obj_name + "pt%dto%d_purity_vs_eff.%s" %
                        (pt_min, pt_max, OUTPUT_FMT)))

                if best_purity == starting_purity:
                    purity_text.AddText("Best purity (%.3f) with no cut" %
                                        best_purity)
                else:
                    purity_text.AddText("No cut purity = %.3f" %
                                        (starting_purity))
                    purity_text.AddText(
                        "Best purity (%.3f) with %s %.3g" %
                        (best_purity, purity_cut_type, purity_cut_value))
                if best_purity_x_eff == starting_purity_x_eff:
                    purity_text.AddText(
                        "Best purity * eff (%.3f) with no cut" %
                        best_purity_x_eff)
                else:
                    purity_text.AddText("No cut purity * eff = %.3f" %
                                        (starting_purity_x_eff))
                    purity_text.AddText(
                        "Best purity * eff (%.3f) with cut %s %.3g" %
                        (best_purity_x_eff, purity_x_eff_cut_type,
                         purity_x_eff_cut_value))

            ylim = None
            # if "pt_jet" in obj_name and "ratio" not in obj_name and "frac" not in obj_name:
            #     ylim = [1E-9, 1E-1]
            title = "%d < p_{T}^{jet 1} < %d GeV" % (pt_min, pt_max)
            p = Plot(contributions,
                     what='hist',
                     ytitle="p.d.f." if normalise_hists else "N",
                     title=title,
                     subplot_type="ratio" if do_ratio else None,
                     subplot_title="#splitline{Ratio wrt}{%s}" %
                     contributions[0].label,
                     subplot=contributions[0],
                     ylim=ylim)
            p.legend.SetX1(0.7)
            p.legend.SetX2(0.9)
            p.plot(draw_opts)
            p.main_pad.cd()
            if find_best_purity:
                purity_text.Draw("SAME")
            p.save(
                os.path.join(
                    output_dir,
                    obj_name + "_pt%dto%d.%s" % (pt_min, pt_max, OUTPUT_FMT)))
Beispiel #3
0
def do_plots(root_dir):
    # QG variable plots
    pt_bins = qgc.PT_BINS[:]
    var_list = qgc.COMMON_VARS

    radius, pus = cu.get_jet_config_from_dirname(root_dir)
    jet_str = "AK%s" % (radius.upper())

    dy_tfile, qcd_tfile = None, None

    if os.path.isfile(os.path.join(root_dir, qgc.DY_FILENAME)):
        dy_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.DY_FILENAME))

    if os.path.isfile(os.path.join(root_dir, qgc.QCD_FILENAME)):
        qcd_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.QCD_FILENAME))

    for gr_append in ["", "_groomed"]:
        if gr_append == "_groomed":
            print("Doing groomed plots...")
        else:
            print("Doing ungroomed plots...")

        # GEnJets matched to recojet, reco selection
        zpj_dirname = "ZPlusJets_QG%s" % (gr_append)
        dj_cen_dirname = "Dijet_QG_central_tighter%s" % (gr_append)
        dj_fwd_dirname = "Dijet_QG_forward_tighter%s" % (gr_append)

        # Gen Jets from gen selection
        zpj_dirname = "ZPlusJets_QG_gen%s" % (gr_append)
        dj_cen_dirname = "Dijet_QG_gen_central%s" % (gr_append)
        dj_fwd_dirname = "Dijet_QG_gen_forward%s" % (gr_append)

        for ang in var_list[:]:
            print("...Doing", ang.name)
            var_template = "{prefix}%s_vs_pt" % (ang.var
                                                 )  # {prefix} is for flavour

            for pt_ind, (start_val, end_val) in enumerate(pt_bins):
                zpj_entries = []
                dijet_cen_entries = []
                dijet_fwd_entries = []

                # Get all plots
                lw = 2
                msize = 1.1
                mc_msize = 1E-3  # small enough to not be seen but not 0 - otherwise the horizontal lines on error bars don't get drawn
                mc_msize = msize  # small enough to not be seen but not 0 - otherwise the horizontal lines on error bars don't get drawn

                flavours_dicts = [
                    {
                        "prefix": "q",
                        "label": "u/d/s"
                    },
                    {
                        "prefix": "g",
                        "label": "g"
                    },
                    {
                        "prefix": "bc",
                        "label": "b/c"
                    },
                ]

                if dy_tfile:
                    # Z+JETS REGION
                    marker = cu.Marker(qgc.DY_MARKER)
                    for flav_dict, color, mark in zip(flavours_dicts,
                                                      qgc.DY_COLOURS,
                                                      marker.cycle()):
                        h2d_dyj_mc = dy_tfile.get(
                            "%s/%s" %
                            (zpj_dirname, var_template.format(**flav_dict)))
                        dy_kwargs_mc = dict(line_color=color,
                                            line_width=lw,
                                            fill_color=color,
                                            marker_color=color,
                                            marker_style=mark,
                                            marker_size=mc_msize,
                                            label="%s flavour" %
                                            (flav_dict['label']),
                                            subplot=None)
                        zpj_entries.append(
                            (qgp.get_projection_plot(h2d_dyj_mc, start_val,
                                                     end_val), dy_kwargs_mc))

                if qcd_tfile:
                    # DIJET CENTRAL REGION
                    marker = cu.Marker(qgc.QCD_MARKER)
                    for flav_dict, color, mark in zip(flavours_dicts,
                                                      qgc.QCD_COLOURS,
                                                      marker.cycle()):
                        h2d_qcd_cen_mc = qcd_tfile.get(
                            "%s/%s" %
                            (dj_cen_dirname, var_template.format(**flav_dict)))
                        qcd_cen_kwargs_mc = dict(line_color=color,
                                                 line_width=lw,
                                                 fill_color=color,
                                                 marker_color=color,
                                                 marker_style=mark,
                                                 marker_size=mc_msize,
                                                 label="%s flavour" %
                                                 (flav_dict['label']),
                                                 subplot=None)
                        dijet_mgpy_hist = qgp.get_projection_plot(
                            h2d_qcd_cen_mc, start_val, end_val)
                        dijet_cen_entries.append(
                            (dijet_mgpy_hist, qcd_cen_kwargs_mc))

                    # DIJET FORWARD REGION
                    marker = cu.Marker(qgc.QCD_MARKER)
                    for flav_dict, color, mark in zip(flavours_dicts,
                                                      qgc.QCD_COLOURS,
                                                      marker.cycle()):
                        h2d_qcd_fwd_mc = qcd_tfile.get(
                            "%s/%s" %
                            (dj_fwd_dirname, var_template.format(**flav_dict)))
                        qcd_fwd_kwargs_mc = dict(line_color=color,
                                                 line_width=lw,
                                                 fill_color=color,
                                                 marker_color=color,
                                                 marker_style=mark,
                                                 marker_size=mc_msize,
                                                 label="%s flavour" %
                                                 (flav_dict['label']),
                                                 subplot=None)
                        dijet_mgpy_hist = qgp.get_projection_plot(
                            h2d_qcd_fwd_mc, start_val, end_val)
                        dijet_fwd_entries.append(
                            (dijet_mgpy_hist, qcd_fwd_kwargs_mc))

                #################
                # SETUP PLOTTING
                #################
                rebin = 2
                v_lower = var_template.lower()
                if "multiplicity" in v_lower:
                    rebin = 1
                # elif "flavour" in v_lower or "thrust" in v_lower:
                #     rebin = 1
                # elif 'ptd' in v_lower:
                #     rebin = 4
                # elif 'lha_charged' in v_lower:
                #     rebin = 4
                # rebin = 1

                xlim = None
                if "width" in v_lower or "ptd" in v_lower:
                    xlim = (0, 1)
                elif "thrust" in v_lower:
                    xlim = (0, 0.5)
                # elif "multiplicity" in v_lower and "ak4" in root_dir.lower():
                #     if end_val <= 150:
                #         xlim = (0, 50)
                #     else:
                #         xlim = (0, 80)

                auto_xlim = False
                if "multiplicity" in v_lower or "thrust" in v_lower:
                    auto_xlim = True

                ylim = [0, None]
                if "flavour" in v_lower:
                    ylim = (0, 1)
                # elif "lha" in v_lower:
                # ylim = (0, 5)

                plot_dir = os.path.join(
                    root_dir,
                    "plots_gen_lambda_flav_comparison%s" % (gr_append))

                subplot_title = "Simulation / Data"
                subplot_limits = (0, 2)

                xlabel = ang.name + " (" + ang.lambda_str + ")"
                if gr_append is not "":
                    xlabel = "Groomed " + ang.name + " (" + ang.lambda_str + ")"

                def _title(region_str, start_val, end_val):
                    pt_var_str = "p_{T}^{jet}"
                    s = (("{jet_algo}\n"
                          "{region_label}\n"
                          "{mc_sample}\n"
                          "{bin_edge_low:g} < {pt_str} < {bin_edge_high:g} GeV"
                          ).format(jet_algo=jet_str,
                                   region_label=region_str,
                                   mc_sample="MG5+Pythia8",
                                   pt_str=pt_var_str,
                                   bin_edge_low=start_val,
                                   bin_edge_high=end_val))
                    return s

                has_data = False
                draw_opt = "NOSTACK HIST E1"
                # dj central only
                # dont' try to do multiple signal regions per plot, it looks rubbish
                if len(dijet_cen_entries) > 0:
                    qgp.do_comparison_plot(
                        dijet_cen_entries,
                        "%s/ptBinned/%s_pt%dto%d_dijet_central.%s" %
                        (plot_dir, ang.var, start_val, end_val, OUTPUT_FMT),
                        rebin=rebin,
                        draw_opt=draw_opt,
                        title=_title(qgc.Dijet_CEN_LABEL, start_val, end_val),
                        xtitle=xlabel,
                        xlim='auto' if auto_xlim else
                        xlim,  # don't use calc_auto_xlim, since do_comparison_plot will rebin it anyway
                        ylim=ylim,
                        data_first=has_data,
                        mean_rel_error=0.4,
                        subplot_type=None,
                        lumi=cu.get_lumi_str(
                            do_dijet=False,
                            do_zpj=True))  # full lumi as just MC

                # dj forward only
                if len(dijet_fwd_entries) > 0:
                    qgp.do_comparison_plot(
                        dijet_fwd_entries,
                        "%s/ptBinned/%s_pt%dto%d_dijet_forward.%s" %
                        (plot_dir, ang.var, start_val, end_val, OUTPUT_FMT),
                        rebin=rebin,
                        draw_opt=draw_opt,
                        title=_title(qgc.Dijet_FWD_LABEL, start_val, end_val),
                        xtitle=xlabel,
                        xlim='auto' if auto_xlim else xlim,
                        ylim=ylim,
                        data_first=has_data,
                        mean_rel_error=0.4,
                        subplot_type=None,
                        lumi=cu.get_lumi_str(
                            do_dijet=False,
                            do_zpj=True))  # full lumi as just MC

                # zpj only
                if len(zpj_entries) > 0:
                    if start_val > 149:
                        # rebin *= 2
                        rebin += 1
                        # find nearest divisor
                        while (zpj_entries[0][0].GetNbinsX() % rebin != 0):
                            rebin += 1
                    if "multiplicity" in v_lower:
                        if start_val > 300:
                            rebin += 1
                            # find nearest divisor
                            while (zpj_entries[0][0].GetNbinsX() % rebin != 0):
                                rebin += 1
                    qgp.do_comparison_plot(
                        zpj_entries,
                        "%s/ptBinned/%s_pt%dto%d_zpj.%s" %
                        (plot_dir, ang.var, start_val, end_val, OUTPUT_FMT),
                        rebin=rebin,
                        draw_opt=draw_opt,
                        title=_title(qgc.ZpJ_LABEL, start_val, end_val),
                        xtitle=xlabel,
                        xlim=qgp.calc_auto_xlim([d[0] for d in zpj_entries])
                        if auto_xlim else xlim,
                        ylim=ylim,
                        data_first=has_data,
                        mean_rel_error=0.4,
                        subplot_type=None,
                        lumi=cu.get_lumi_str(do_dijet=False, do_zpj=True))
Beispiel #4
0
def make_1D_rebin_hists(input_filename, plot_dirname, output_filename):

    # QG variable plots

    in_f = cu.open_root_file(input_filename)
    out_f = ROOT.TFile(output_filename, "RECREATE")

    plot_file = open(output_filename.replace(".root", ".plot"), "w")

    for ang_ind, ang in enumerate(qgc.COMMON_VARS[:5]):
        if ang.var not in qgc.ANGLE_REBIN_DICT:
            continue

        in_f.cd()

        var_prepend = ""
        obj_name = "%s%s_vs_pt" % (var_prepend, ang.var)
        if var_prepend == "gen" and "multiplicity" in ang.var.lower():
            obj_name = obj_name.replace("puppiMultiplicity", "multiplicity")
        h2d = cu.get_from_tfile(in_f, "%s/%s" % (plot_dirname, obj_name))

        for pt_ind, (start_val, end_val) in enumerate(qgc.PT_BINS):
            hist = qgp.get_projection_plot(h2d, start_val, end_val,
                                           'y')  # y cos lambda is on x axis
            this_rebins = qgc.ANGLE_REBIN_DICT[ang.var]
            # new_name = "%s_Pt%sto%d" % (ang.var, start_val, end_val)
            yoda_name = create_yoda_hist_name(plot_dirname, ang.var,
                                              (start_val, end_val))
            rebin_hist = hist.Rebin(
                len(this_rebins) - 1, yoda_name, array('d', this_rebins))
            # Normalise
            if rebin_hist.Integral() > 0:
                rebin_hist.Scale(1. / rebin_hist.Integral())
            # Divide bin contents by bin width
            for bin_ind in range(1, rebin_hist.GetNbinsX() + 1):
                val = rebin_hist.GetBinContent(bin_ind)
                width = rebin_hist.GetBinWidth(bin_ind)
                rebin_hist.SetBinContent(bin_ind, val / width)

            out_f.WriteTObject(rebin_hist)  # saves faffing with cd()

            # create yoda plot info
            xlabel = "%s $(%s)$" % (ang.name, ang.lambda_str.replace(
                "#", "\\"))
            title_str = "$%d < p_{T}^{jet} < %d$ GeV" % (start_val, end_val)
            xmax = 1
            if "multiplicity" in ang.var.lower():
                xmax = 50
            this_plot_info = YODA_PLOT_TEMPLATE.format(plotname=yoda_name,
                                                       xlabel=xlabel,
                                                       title=title_str,
                                                       ylabel="p.d.f",
                                                       logx=0,
                                                       logy=0,
                                                       xmax=xmax,
                                                       xmin=0)
            plot_file.write(this_plot_info)

    # Add in pt hist
    h_pt = cu.get_from_tfile(in_f, "Dijet_tighter/pt_jet_response_binning")
    pt_name = "d01-x20-y01"
    h_pt.SetName(pt_name)
    this_plot_info = YODA_PLOT_TEMPLATE.format(
        plotname=pt_name,
        xlabel="$\langle p_{T}^{j}\\rangle$ GeV",
        title="",
        ylabel="N",
        logy=1,
        logx=1,
        xmin=10,
        xmax=1000)
    plot_file.write(this_plot_info)
    out_f.WriteTObject(h_pt)

    out_f.Close()
    plot_file.close()
Beispiel #5
0
                dijet_cen_nominal_vs_syst_sf_entries = []
                dijet_fwd_no_vs_nominal_sf_entries = []
                dijet_fwd_nominal_vs_syst_sf_entries = []

                # Get all plots
                lw = 2
                msize = 1.1
                data_line_width = lw

                ####################
                # Z+JETS REGION
                ####################
                zpj_obj_name = "%s/%s" % (zpj_dirname, v)

                # NO SF
                zpj_no_sf_hist = qgp.get_projection_plot(
                    DY_NO_SF_TFILE[zpj_obj_name], start_val, end_val)
                dy_kwargs_no_sf = dict(line_color=qgc.SINGLE_MU_COLOUR,
                                       line_width=data_line_width,
                                       fill_color=qgc.SINGLE_MU_COLOUR,
                                       marker_color=qgc.SINGLE_MU_COLOUR,
                                       marker_style=cu.Marker.get(
                                           qgc.DY_MARKER),
                                       marker_size=0,
                                       label="No TRK SF")
                zpj_no_vs_nominal_sf_entries.append(
                    (zpj_no_sf_hist, dy_kwargs_no_sf))

                # NOMINAL TK SF
                zpj_nominal_sf_hist = qgp.get_projection_plot(
                    DY_NOMINAL_SF_TFILE[zpj_obj_name], start_val, end_val)
                dy_kwargs_nominal_sf = dict(line_color=qgc.DY_COLOUR,
def do_wrong_plots(root_dir,
                   var_prepend="",
                   plot_dir="wrong_flavs",
                   zpj_dirname="ZPlusJets_QG",
                   dj_dirname="Dijet_QG",
                   pt_bins=None,
                   title=""):
    """Plot all the sample/selection/flavour combinations to check distributions indep of sample"""
    pt_bins = pt_bins or qgc.THEORY_PT_BINS
    plot_vars = [
        'jet_LHA', 'jet_pTD', 'jet_width', 'jet_thrust', 'jet_multiplicity'
    ]
    if "puppi" in root_dir.lower():
        plot_vars.append('jet_puppiMultiplicity')
    for v in plot_vars:
        v = "%s%s_vs_pt" % (var_prepend, v)

        h2d_dyj_chs = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                               "%s/q%s" % (zpj_dirname, v))
        h2d_dyj_wrong_chs = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                                     "%s/g%s" % (zpj_dirname, v))
        h2d_dyj_qcd_chs = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                                   "%s/q%s" % (dj_dirname, v))
        h2d_dyj_qcd_wrong_chs = grab_obj(
            os.path.join(root_dir, qgc.DY_FILENAME),
            "%s/g%s" % (dj_dirname, v))
        h2d_qcd_chs = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                               "%s/g%s" % (dj_dirname, v))
        h2d_qcd_wrong_chs = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                                     "%s/q%s" % (dj_dirname, v))

        lw = 1
        dy_kwargs_chs = dict(line_color=qgc.DY_COLOUR,
                             fill_color=qgc.DY_COLOUR,
                             label=qgc.DY_ZpJ_QFLAV_LABEL,
                             line_width=lw,
                             marker_style=20,
                             marker_color=qgc.DY_COLOUR)
        dy_kwargs_wrong_chs = dict(line_color=qgc.DY_COLOUR + 4,
                                   fill_color=qgc.DY_COLOUR + 4,
                                   label=qgc.DY_ZpJ_GFLAV_LABEL,
                                   line_width=lw,
                                   line_style=1,
                                   marker_style=21,
                                   marker_color=qgc.DY_COLOUR + 4)
        dy_kwargs_qcd_chs = dict(line_color=ROOT.kGreen + 2,
                                 fill_color=ROOT.kGreen + 2,
                                 label=qgc.DY_Dijet_QFLAV_LABEL,
                                 line_width=lw,
                                 line_style=1,
                                 marker_style=22,
                                 marker_color=ROOT.kGreen + 2)
        dy_kwargs_qcd_wrong_chs = dict(line_color=ROOT.kOrange - 1,
                                       fill_color=ROOT.kOrange - 1,
                                       label=qgc.DY_Dijet_GFLAV_LABEL,
                                       line_width=lw,
                                       line_style=1,
                                       marker_style=23,
                                       marker_color=ROOT.kOrange - 1)
        qcd_kwargs_chs = dict(line_color=qgc.QCD_COLOUR,
                              fill_color=qgc.QCD_COLOUR,
                              label=qgc.QCD_Dijet_GFLAV_LABEL,
                              line_width=lw,
                              marker_style=25,
                              marker_color=qgc.QCD_COLOUR)
        qcd_kwargs_wrong_chs = dict(line_color=ROOT.kRed,
                                    fill_color=ROOT.kRed,
                                    label=qgc.QCD_Dijet_QFLAV_LABEL,
                                    line_width=lw,
                                    line_style=1,
                                    marker_style=24,
                                    marker_color=ROOT.kRed)

        rebin = 2
        xlim = None
        if "thrust" in v:
            rebin = 1
            xlim = (0, 0.5)
        if "multiplicity" in v.lower():
            rebin = 2
            xlim = (0, 100)

        for (start_val, end_val) in pt_bins:
            entries = [
                (qgg.get_projection_plot(h2d_dyj_chs, start_val,
                                         end_val), dy_kwargs_chs),
                (qgg.get_projection_plot(h2d_dyj_wrong_chs, start_val,
                                         end_val), dy_kwargs_wrong_chs),
                # (qgg.get_projection_plot(h2d_dyj_qcd_chs, start_val, end_val), dy_kwargs_qcd_chs),
                # (qgg.get_projection_plot(h2d_dyj_qcd_wrong_chs, start_val, end_val), dy_kwargs_qcd_wrong_chs),
                (qgg.get_projection_plot(h2d_qcd_wrong_chs, start_val,
                                         end_val), qcd_kwargs_wrong_chs),
                (qgg.get_projection_plot(h2d_qcd_chs, start_val,
                                         end_val), qcd_kwargs_chs),
            ]

            this_title = "%d < p_{T}^{jet} < %d GeV" % (start_val, end_val)
            if title != "":
                this_title += ", %s" % title
            qgg.do_comparison_plot(
                entries,
                "%s/%s/%s_pt%dto%d_flavMatched.%s" %
                (root_dir, plot_dir, v, start_val, end_val, OUTPUT_FMT),
                rebin=rebin,
                title=this_title,
                xlim=xlim)
def do_plots(root_dir, title):
    # QG variable plots
    pt_bins = qgc.PT_BINS[:]
    print(pt_bins)
    var_list = qgc.COMMON_VARS
    var_prepend = ""

    radius, pus = cu.get_jet_config_from_dirname(root_dir)
    jet_str = "AK%s PF %s" % (radius.upper(), pus.upper())

    if radius == "8":
        pt_bins = qgc.PT_BINS[2:]
        print(pt_bins)

    single_mu_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.SINGLE_MU_FILENAME))
    dy_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.DY_FILENAME))
    dy_hpp_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.DY_HERWIG_FILENAME))
    jetht_zb_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.JETHT_ZB_FILENAME))
    qcd_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.QCD_FILENAME))
    qcd_hpp_tfile = cu.TFileCacher(os.path.join(root_dir, qgc.QCD_HERWIG_FILENAME))

    for gr_append in ["", "_groomed"]:
        if gr_append == "_groomed":
            print("Doing groomed plots...")
        else:
            print("Doing ungroomed plots...")

        zpj_dirname = "ZPlusJets_QG%s" % (gr_append)
        dj_cen_dirname = "Dijet_QG_central_tighter%s" % (gr_append)
        dj_fwd_dirname = "Dijet_QG_forward_tighter%s" % (gr_append)

        for ang in var_list[:]:
            print("...Doing", ang.name)
            v = "%s%s_vs_pt" % (var_prepend, ang.var)
            zpj_2d_entries = []
            dijet_cen_2d_entries = []
            dijet_fwd_2d_entries = []

            zpj_1d_entries = []
            dijet_cen_1d_entries = []
            dijet_fwd_1d_entries = []

            for pt_ind, (start_val, end_val) in enumerate(pt_bins):
                entries = []
                zpj_entries = []
                dijet_cen_entries = []
                dijet_fwd_entries = []

                # Get all plots
                lw = 2
                msize = 1.1
                data_line_width = lw
                mc_msize = 1E-3  # small enough to not be seen but not 0 - otherwise the horizontal lines on error bars don't get drawn

                mgpy_label = "MG5+Pythia8"
                hpp_label = "Herwig++"

                ####################
                # Z+JETS REGION
                ####################

                # SINGLE MU DATA
                if single_mu_tfile:
                    h2d_dyj_data = single_mu_tfile.get("%s/%s" % (zpj_dirname, v))
                    dy_kwargs_data = dict(line_color=qgc.SINGLE_MU_COLOUR, line_width=data_line_width, fill_color=qgc.SINGLE_MU_COLOUR,
                                          marker_color=qgc.SINGLE_MU_COLOUR, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=msize*0.7,
                                          label="Data")
                    zpj_data_hist = qgp.get_projection_plot(h2d_dyj_data, start_val, end_val)
                    entries.append((zpj_data_hist, dy_kwargs_data))
                    zpj_entries.append((zpj_data_hist, dy_kwargs_data))
                    if pt_ind == 0:
                        zpj_2d_entries.append((h2d_dyj_data, dy_kwargs_data))

                # PYTHIA DY MC
                if dy_tfile:
                    h2d_dyj_mc = dy_tfile.get("%s/%s" % (zpj_dirname, v))
                    dy_kwargs_mc = dict(line_color=qgc.DY_COLOUR, line_width=lw, fill_color=qgc.DY_COLOUR,
                                        marker_color=qgc.DY_COLOUR, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=mc_msize,
                                        label=mgpy_label,
                                        subplot=zpj_data_hist)
                    entries.append((qgp.get_projection_plot(h2d_dyj_mc, start_val, end_val), dy_kwargs_mc))
                    zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc, start_val, end_val), dy_kwargs_mc))
                    if pt_ind == 0:
                        zpj_2d_entries.append((h2d_dyj_mc, dy_kwargs_mc))

                # HERWIG++ DY
                if dy_hpp_tfile:
                    h2d_dyj_mc_hpp = dy_hpp_tfile.get("%s/%s" % (zpj_dirname, v))
                    col_hpp = qgc.DY_COLOURS[2]
                    dy_kwargs_mc_hpp = dict(line_color=col_hpp, line_width=lw, fill_color=col_hpp,
                                            marker_color=col_hpp, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=mc_msize,
                                            label=hpp_label,
                                            subplot=zpj_data_hist)
                    entries.append((qgp.get_projection_plot(h2d_dyj_mc_hpp, start_val, end_val), dy_kwargs_mc_hpp))
                    zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc_hpp, start_val, end_val), dy_kwargs_mc_hpp))
                    if pt_ind == 0:
                        zpj_2d_entries.append((h2d_dyj_mc_hpp, dy_kwargs_mc_hpp))

                # MG+HERWIG++ DY
                # if end_val < 151:
                #     h2d_dyj_mc3 = get("%s/%s" % (zpj_dirname, v))
                #     col4 = qgc.DY_COLOURS[3]
                #     dy_kwargs_mc3 = dict(line_color=col4, line_width=lw, fill_color=col4,
                #                          marker_color=col4, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=0,
                #                          label="MG+Herwig++",
                #                          subplot=zpj_data_hist)
                #     entries.append((qgp.get_projection_plot(h2d_dyj_mc3, start_val, end_val), dy_kwargs_mc3))
                #     zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc3, start_val, end_val), dy_kwargs_mc3))
                #     if pt_ind == 0:
                #         zpj_2d_entries.append((h2d_dyj_mc3, dy_kwargs_mc3))
                # else:
                #     zpj_entries.append(None)

                ####################
                # DIJET CENTRAL REGION
                ####################

                # JETHT/ZEROBIAS DATA
                if jetht_zb_tfile:
                    h2d_qcd_cen_data = jetht_zb_tfile.get("%s/%s" % (dj_cen_dirname, v))  # use already merged jetht+zb
                    qcd_cen_kwargs_data = dict(line_color=qgc.JETHT_COLOUR, line_width=data_line_width, fill_color=qgc.JETHT_COLOUR,
                                               marker_color=qgc.JETHT_COLOUR, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=msize,
                                               label="Data")
                    dijet_cen_data_hist = qgp.get_projection_plot(h2d_qcd_cen_data, start_val, end_val)
                    entries.append((dijet_cen_data_hist, qcd_cen_kwargs_data))
                    dijet_cen_entries.append((dijet_cen_data_hist, qcd_cen_kwargs_data))
                    if pt_ind == 0:
                        dijet_cen_2d_entries.append((h2d_qcd_cen_data, qcd_cen_kwargs_data))

                # MG+PYTHIA QCD MC
                if qcd_tfile:
                    h2d_qcd_cen_mc = qcd_tfile.get("%s/%s" % (dj_cen_dirname, v))
                    qcd_cen_kwargs_mc = dict(line_color=qgc.QCD_COLOUR, line_width=lw, fill_color=qgc.QCD_COLOUR,
                                             marker_color=qgc.QCD_COLOUR, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                                             label=mgpy_label,
                                             subplot=dijet_cen_data_hist)
                    dijet_mgpy_hist = qgp.get_projection_plot(h2d_qcd_cen_mc, start_val, end_val)
                    entries.append((dijet_mgpy_hist, qcd_cen_kwargs_mc))
                    dijet_cen_entries.append((dijet_mgpy_hist, qcd_cen_kwargs_mc))
                    if pt_ind == 0:
                        dijet_cen_2d_entries.append((h2d_qcd_cen_mc, qcd_cen_kwargs_mc))

                # PYTHIA ONLY
                # if qcd_py_tfile:
                #     col = qgc.QCD_COLOURS[2]
                #     h2d_qcd_cen_mc2 = qcd_py_tfile.get("%s/%s" % (dj_cen_dirname, v))
                #     qcd_cen_kwargs_mc2 = dict(line_color=col, line_width=lw, fill_color=col,
                #                               marker_color=col, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                #                               label="Pythia8",
                #                               subplot=dijet_cen_data_hist)
                #     entries.append((qgp.get_projection_plot(h2d_qcd_cen_mc2, start_val, end_val), qcd_cen_kwargs_mc2))
                #     dijet_cen_entries.append((qgp.get_projection_plot(h2d_qcd_cen_mc2, start_val, end_val), qcd_cen_kwargs_mc2))
                #     if pt_ind == 0:
                #         dijet_cen_2d_entries.append((h2d_qcd_cen_mc2, qcd_cen_kwargs_mc2))

                # HERWIG++ QCD
                if qcd_hpp_tfile:
                    h2d_qcd_cen_mc_hpp = qcd_hpp_tfile.get("%s/%s" % (dj_cen_dirname, v))
                    qcd_cen_kwargs_mc_hpp = dict(line_color=qgc.HERWIGPP_QCD_COLOUR, line_width=lw, fill_color=qgc.HERWIGPP_QCD_COLOUR,
                                                 marker_color=qgc.HERWIGPP_QCD_COLOUR, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                                                 label=hpp_label,
                                                 subplot=dijet_cen_data_hist)
                    dijet_hpp_hist = qgp.get_projection_plot(h2d_qcd_cen_mc_hpp, start_val, end_val)
                    entries.append((dijet_hpp_hist, qcd_cen_kwargs_mc_hpp))
                    dijet_cen_entries.append((dijet_hpp_hist, qcd_cen_kwargs_mc_hpp))
                    if pt_ind == 0:
                        dijet_cen_2d_entries.append((h2d_qcd_cen_mc_hpp, qcd_cen_kwargs_mc_hpp))

                ####################
                # DIJET FORWARD REGION
                ####################

                # JETHT/ZEROBIAS DATA
                if jetht_zb_tfile:
                    h2d_qcd_fwd_data = jetht_zb_tfile.get("%s/%s" % (dj_fwd_dirname, v))  # use already merged jetht+zb
                    qcd_fwd_kwargs_data = dict(line_color=qgc.JETHT_COLOUR, line_width=data_line_width, fill_color=qgc.JETHT_COLOUR,
                                               marker_color=qgc.JETHT_COLOUR, marker_style=cu.Marker.get('triangleDown'), marker_size=msize,
                                               label="Data")
                    dijet_fwd_data_hist = qgp.get_projection_plot(h2d_qcd_fwd_data, start_val, end_val)
                    entries.append((dijet_fwd_data_hist, qcd_fwd_kwargs_data))
                    dijet_fwd_entries.append((dijet_fwd_data_hist, qcd_fwd_kwargs_data))
                    if pt_ind == 0:
                        dijet_fwd_2d_entries.append((h2d_qcd_fwd_data, qcd_fwd_kwargs_data))

                # MG+PYTHIA QCD MC
                if qcd_tfile:
                    h2d_qcd_fwd_mc = qcd_tfile.get("%s/%s" % (dj_fwd_dirname, v))
                    qcd_fwd_kwargs_mc = dict(line_color=qgc.QCD_COLOUR, line_width=lw, fill_color=qgc.QCD_COLOUR,
                                             marker_color=qgc.QCD_COLOUR, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                                             label=mgpy_label,
                                             subplot=dijet_fwd_data_hist)
                    dijet_mgpy_hist = qgp.get_projection_plot(h2d_qcd_fwd_mc, start_val, end_val)
                    entries.append((dijet_mgpy_hist, qcd_fwd_kwargs_mc))
                    dijet_fwd_entries.append((dijet_mgpy_hist, qcd_fwd_kwargs_mc))
                    if pt_ind == 0:
                        dijet_fwd_2d_entries.append((h2d_qcd_fwd_mc, qcd_fwd_kwargs_mc))

                # PYTHIA ONLY
                # if qcd_py_tfile:
                    # col = qgc.QCD_COLOURS[2]
                    # h2d_qcd_fwd_mc2 = qcd_py_tfile.get("%s/%s" % (dj_fwd_dirname, v))
                    # qcd_fwd_kwargs_mc2 = dict(line_color=col, line_width=lw, fill_color=col,
                    #                           marker_color=col, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                    #                           label="Pythia8",
                    #                           subplot=dijet_fwd_data_hist)
                    # entries.append((qgp.get_projection_plot(h2d_qcd_fwd_mc2, start_val, end_val), qcd_fwd_kwargs_mc2))
                    # dijet_fwd_entries.append((qgp.get_projection_plot(h2d_qcd_fwd_mc2, start_val, end_val), qcd_fwd_kwargs_mc2))
                    # if pt_ind == 0:
                    #     dijet_fwd_2d_entries.append((h2d_qcd_fwd_mc2, qcd_fwd_kwargs_mc2))

                # HERWIG++ QCD
                if qcd_hpp_tfile:
                    h2d_qcd_fwd_mc_hpp = qcd_hpp_tfile.get("%s/%s" % (dj_fwd_dirname, v))
                    qcd_fwd_kwargs_mc_hpp = dict(line_color=qgc.HERWIGPP_QCD_COLOUR, line_width=lw, fill_color=qgc.HERWIGPP_QCD_COLOUR,
                                                 marker_color=qgc.HERWIGPP_QCD_COLOUR, marker_style=cu.Marker.get(qgc.QCD_MARKER), marker_size=mc_msize,
                                                 label=hpp_label,
                                                 subplot=dijet_fwd_data_hist)
                    dijet_hpp_hist = qgp.get_projection_plot(h2d_qcd_fwd_mc_hpp, start_val, end_val)
                    entries.append((dijet_hpp_hist, qcd_fwd_kwargs_mc_hpp))
                    dijet_fwd_entries.append((dijet_hpp_hist, qcd_fwd_kwargs_mc_hpp))
                    if pt_ind == 0:
                        dijet_fwd_2d_entries.append((h2d_qcd_fwd_mc_hpp, qcd_fwd_kwargs_mc_hpp))

                zpj_1d_entries.append(zpj_entries)
                dijet_cen_1d_entries.append(dijet_cen_entries)
                dijet_fwd_1d_entries.append(dijet_fwd_entries)

                #################
                # SETUP PLOTTING
                #################
                rebin = 2
                v_lower = v.lower()
                if "multiplicity" in v_lower:
                    rebin = 1
                # elif "flavour" in v_lower or "thrust" in v_lower:
                #     rebin = 1
                # elif 'ptd' in v_lower:
                #     rebin = 4
                # elif 'lha_charged' in v_lower:
                #     rebin = 4
                # rebin = 1

                xlim = None
                if "width" in v_lower or "ptd" in v_lower:
                    xlim = (0, 1)
                elif "thrust" in v_lower:
                    xlim = (0, 0.5)
                # elif "multiplicity" in v_lower and "ak4" in root_dir.lower():
                #     if end_val <= 150:
                #         xlim = (0, 50)
                #     else:
                #         xlim = (0, 80)

                auto_xlim = False
                if "multiplicity" in v_lower or "thrust" in v_lower:
                    auto_xlim = True

                ylim = [0, None]
                if "flavour" in v_lower:
                    ylim = (0, 1)
                # elif "lha" in v_lower:
                    # ylim = (0, 5)

                plot_dir = os.path.join(root_dir, "plots_lambda_mc_vs_data%s" % (gr_append))

                subplot_title = "Simulation / Data"
                subplot_limits = (0, 2)

                xlabel = ang.name + " (" + ang.lambda_str + ")"
                if gr_append is not "":
                    xlabel = "Groomed " + ang.name + " (" + ang.lambda_str + ")"

                def _title(region_str, start_val, end_val):
                    pt_var_str = "p_{T}^{jet}"
                    s = (("{jet_algo}\n"
                          "{region_label}\n"
                          "{bin_edge_low:g} < {pt_str} < {bin_edge_high:g} GeV")
                          .format(
                            jet_algo=jet_str,
                            region_label=region_str,
                            pt_str=pt_var_str,
                            bin_edge_low=start_val,
                            bin_edge_high=end_val))
                    if title is not None:
                        s = "%s\n%s" % (s, title)
                    return s

                has_data = True
                draw_opt = "NOSTACK HIST E1"
                # dj central only
                # dont' try to do multiple signal regions per plot, it looks rubbish
                if len(dijet_cen_entries) > 0:
                    qgp.do_comparison_plot(dijet_cen_entries,
                                           "%s/ptBinned/%s_pt%dto%d_dijet_central.%s" % (plot_dir, v, start_val, end_val, OUTPUT_FMT),
                                           rebin=rebin,
                                           draw_opt=draw_opt,
                                           title=_title(qgc.Dijet_CEN_LABEL, start_val, end_val),
                                           xtitle=xlabel,
                                           xlim='auto' if auto_xlim else xlim, # don't use calc_auto_xlim, since do_comparison_plot will rebin it anyway
                                           ylim=ylim,
                                           data_first=has_data,
                                           mean_rel_error=0.4,
                                           subplot_type='ratio',
                                           subplot_title=subplot_title,
                                           subplot_limits=subplot_limits,
                                           lumi=cu.get_lumi_str(do_dijet=True, do_zpj=False))

                # dj forward only
                if len(dijet_fwd_entries) > 0:
                    qgp.do_comparison_plot(dijet_fwd_entries,
                                           "%s/ptBinned/%s_pt%dto%d_dijet_forward.%s" % (plot_dir, v, start_val, end_val, OUTPUT_FMT),
                                           rebin=rebin,
                                           draw_opt=draw_opt,
                                           title=_title(qgc.Dijet_FWD_LABEL, start_val, end_val),
                                           xtitle=xlabel,
                                           xlim='auto' if auto_xlim else xlim,
                                           ylim=ylim,
                                           data_first=has_data,
                                           mean_rel_error=0.4,
                                           subplot_type='ratio',
                                           subplot_title=subplot_title,
                                           subplot_limits=subplot_limits,
                                           lumi=cu.get_lumi_str(do_dijet=True, do_zpj=False))

                # zpj only
                if len(zpj_entries) > 0:
                    if start_val > 149:
                        # rebin *= 2
                        rebin += 1
                        # find nearest divisor
                        while (zpj_entries[0][0].GetNbinsX() % rebin != 0):
                            rebin += 1
                    if "multiplicity" in v_lower:
                        if start_val > 300:
                            rebin += 1
                            # find nearest divisor
                            while (zpj_entries[0][0].GetNbinsX() % rebin != 0):
                                rebin += 1
                    qgp.do_comparison_plot(zpj_entries,
                                           "%s/ptBinned/%s_pt%dto%d_zpj.%s" % (plot_dir, v, start_val, end_val, OUTPUT_FMT),
                                           rebin=rebin,
                                           draw_opt=draw_opt,
                                           title=_title(qgc.ZpJ_LABEL, start_val, end_val),
                                           xtitle=xlabel,
                                           xlim=qgp.calc_auto_xlim([d[0] for d in zpj_entries]) if auto_xlim else xlim,
                                           ylim=ylim,
                                           data_first=has_data,
                                           mean_rel_error=0.4,
                                           subplot_type='ratio',
                                           subplot_title=subplot_title,
                                           subplot_limits=subplot_limits,
                                           lumi=cu.get_lumi_str(do_dijet=False, do_zpj=True))


            # Do overall summary plots across all pt bins
            # ------------------------------------------------------------------
            ylim_mean = None
            if "width" in v_lower or "ptd" in v_lower:
                ylim_mean = (0, 0.4)
            elif"thrust" in v_lower:
                ylim_mean = (0, 0.5)
            elif "multiplicity" in v_lower and "ak4" in root_dir.lower():
                ylim_mean = (0, 100)
                ylim_mean = (0, 80)
                if end_val < 150:
                    ylim_mean = (0, 50)
            ylim_mean=None
            ylim_rms=None

            # Setup variable names for MPL
            marker = ""
            if "_" in ang.name or "^" in ang.name:
                marker = "$"
            var_label = marker + ang.name + marker + " ($%s$)" % ang.lambda_str
            if gr_append != "":
                var_label = "Groomed " + marker + ang.name + marker + " ($%s$)" % ang.lambda_str

            # construct a dataframe from the hists
            # df = construct_dataframe_from_hists(dijet_cen_entries=dijet_cen_1d_entries,
            #                                     dijet_fwd_entries=dijet_fwd_entries,
            #                                     zpj_entries=zpj_entries)

            # pt_low = 88 if "8" in radius else 50 
            pt_low = pt_bins[0][0]
            qgp.do_mean_rms_summary_plot(dijet_cen_1d_entries,
                                         pt_bins,
                                         "%s/ptBinned/%s_box_dijet_cen_mpl.%s" % (plot_dir, v, OUTPUT_FMT),
                                         var_label=var_label,
                                         xlim=(pt_low, 4000),
                                         ylim_mean=ylim_mean,
                                         ylim_rms=ylim_rms,
                                         region_title="%s jets in %s" % (jet_str, qgc.Dijet_CEN_LABEL.lower()))

            qgp.do_mean_rms_summary_plot(dijet_fwd_1d_entries,
                                         pt_bins,
                                         "%s/ptBinned/%s_box_dijet_fwd_mpl.%s" % (plot_dir, v, OUTPUT_FMT),
                                         var_label=var_label,
                                         xlim=(pt_low, 4000),
                                         ylim_mean=ylim_mean,
                                         ylim_rms=ylim_rms,
                                         region_title="%s jets in %s" % (jet_str, qgc.Dijet_FWD_LABEL.lower()))

            # zpj_1d_entries[i][j] is the jth sample in the ith pt bin
            qgp.do_mean_rms_summary_plot(zpj_1d_entries,
                                         pt_bins,
                                         "%s/ptBinned/%s_box_zpj_mpl.%s" % (plot_dir, v, OUTPUT_FMT),
                                         var_label=var_label,
                                         xlim=(pt_low, 800),
                                         ylim_mean=ylim_mean,
                                         ylim_rms=ylim_rms,
                                         region_title="%s jets in %s" % (jet_str, qgc.ZpJ_LABEL))
def do_plots(root_dir):
    # QG variable plots
    pt_bins = qgc.PT_BINS[:]
    var_list = qgc.COMMON_VARS
    var_prepend = ""

    radius, pus = cu.get_jet_config_from_dirname(root_dir)
    jet_str = "AK%s PF %s" % (radius.upper(), pus.upper())

    for gr_append in ["", "_groomed"]:
        if gr_append == "_groomed":
            print("Doing groomed plots...")
        else:
            print("Doing ungroomed plots...")

        # do a pt plot just for sanity
        if gr_append == "":
            make_1d_plot(root_dir, "ZPlusJets_gen/pt_jet1", jet_str, gen_only=True)
            make_1d_plot(root_dir, "ZPlusJets_gen/pt_mumu", jet_str, gen_only=True)
            make_1d_plot(root_dir, "ZPlusJets/pt_jet1", jet_str)
            make_1d_plot(root_dir, "ZPlusJets/pt_mumu", jet_str)

        continue

        zpj_dirname = "ZPlusJets_QG%s" % (gr_append)

        for ang in var_list[:]:
            print("...Doing", ang.name)
            v = "%s%s_vs_pt" % (var_prepend, ang.var)
            zpj_2d_entries = []

            zpj_1d_entries = []

            for pt_ind, (start_val, end_val) in enumerate(pt_bins):
                entries = []
                zpj_entries = []

                # Get all plots
                lw = 2
                msize = 1.1
                data_line_width = 0

                ####################
                # Z+JETS REGION
                ####################

                # SINGLE MU DATA
                h2d_dyj_data = grab_obj(os.path.join(root_dir, qgc.SINGLE_MU_FILENAME), "%s/%s" % (zpj_dirname, v))
                dy_kwargs_data = dict(line_color=qgc.SINGLE_MU_COLOUR, line_width=data_line_width, fill_color=qgc.SINGLE_MU_COLOUR,
                                      marker_color=qgc.SINGLE_MU_COLOUR, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=msize,
                                      label="Data")
                zpj_data_hist = qgp.get_projection_plot(h2d_dyj_data, start_val, end_val)
                entries.append((zpj_data_hist, dy_kwargs_data))
                zpj_entries.append((zpj_data_hist, dy_kwargs_data))
                if pt_ind == 0:
                    zpj_2d_entries.append((h2d_dyj_data, dy_kwargs_data))

                # PYTHIA DY MC WITH k FACTORS
                h2d_dyj_mc = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME), "%s/%s" % (zpj_dirname, v))
                dy_kwargs_mc = dict(line_color=qgc.DY_COLOUR, line_width=lw, fill_color=qgc.DY_COLOUR,
                                    marker_color=qgc.DY_COLOUR, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=0,
                                    label="MG+PY8 (w/ k-factor)",
                                    subplot=zpj_data_hist)
                entries.append((qgp.get_projection_plot(h2d_dyj_mc, start_val, end_val), dy_kwargs_mc))
                zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc, start_val, end_val), dy_kwargs_mc))
                if pt_ind == 0:
                    zpj_2d_entries.append((h2d_dyj_mc, dy_kwargs_mc))

                # WIHTOUT K FACTORS
                h2d_dyj_mc_noWeight = grab_obj(os.path.join(root_dir, "uhh2.AnalysisModuleRunner.MC.MC_DYJetsToLL_noZReweight.root"), "%s/%s" % (zpj_dirname, v))
                dy_kwargs_mc_noWeight = dict(line_color=qgc.DY_COLOURS[0], line_width=lw, fill_color=qgc.DY_COLOURS[0], line_style=2,
                                    marker_color=qgc.DY_COLOURS[0], marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=0,
                                    label="MG+PY8 (w/out k-factor)",
                                    subplot=zpj_data_hist)
                entries.append((qgp.get_projection_plot(h2d_dyj_mc_noWeight, start_val, end_val), dy_kwargs_mc_noWeight))
                zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc_noWeight, start_val, end_val), dy_kwargs_mc_noWeight))
                if pt_ind == 0:
                    zpj_2d_entries.append((h2d_dyj_mc_noWeight, dy_kwargs_mc_noWeight))

                # HERWIG++ DY
                # if end_val < 255:
                #     h2d_dyj_mc2 = grab_obj(os.path.join(root_dir, qgc.DY_HERWIG_FILENAME), "%s/%s" % (zpj_dirname, v))
                #     col3 = qgc.DY_COLOURS[2]
                #     dy_kwargs_mc2 = dict(line_color=col3, line_width=lw, fill_color=col3,
                #                          marker_color=col3, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=0,
                #                          label="H++",
                #                          subplot=zpj_data_hist)
                #     entries.append((qgp.get_projection_plot(h2d_dyj_mc2, start_val, end_val), dy_kwargs_mc2))
                #     zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc2, start_val, end_val), dy_kwargs_mc2))
                #     if pt_ind == 0:
                #         zpj_2d_entries.append((h2d_dyj_mc2, dy_kwargs_mc2))
                # else:
                #     zpj_entries.append(None)

                # MG+HERWIG++ DY
                # if end_val < 151:
                #     h2d_dyj_mc3 = grab_obj(os.path.join(root_dir, qgc.DY_MG_HERWIG_FILENAME), "%s/%s" % (zpj_dirname, v))
                #     col4 = qgc.DY_COLOURS[3]
                #     dy_kwargs_mc3 = dict(line_color=col4, line_width=lw, fill_color=col4,
                #                          marker_color=col4, marker_style=cu.Marker.get(qgc.DY_MARKER), marker_size=0,
                #                          label="MG+H++",
                #                          subplot=zpj_data_hist)
                #     entries.append((qgp.get_projection_plot(h2d_dyj_mc3, start_val, end_val), dy_kwargs_mc3))
                #     zpj_entries.append((qgp.get_projection_plot(h2d_dyj_mc3, start_val, end_val), dy_kwargs_mc3))
                #     if pt_ind == 0:
                #         zpj_2d_entries.append((h2d_dyj_mc3, dy_kwargs_mc3))
                # else:
                #     zpj_entries.append(None)

                zpj_1d_entries.append(zpj_entries)

                #################
                # SETUP PLOTTING
                #################
                rebin = 2
                v_lower = v.lower()
                if "multiplicity" in v_lower:
                    rebin = 2
                elif "flavour" in v_lower or "thrust" in v_lower:
                    rebin = 1
                elif 'ptd' in v_lower:
                    rebin = 2

                xlim = None
                if "width" in v_lower or "ptd" in v_lower:
                    xlim = (0, 1)
                elif"thrust" in v_lower:
                    xlim = (0, 0.5)
                elif "multiplicity" in v_lower and "ak4" in root_dir.lower():
                    if end_val <= 150:
                        xlim = (0, 50)
                    else:
                        xlim = (0, 80)

                ylim = None
                if "flavour" in v_lower:
                    ylim = (0, 1)
                # elif "lha" in v_lower:
                    # ylim = (0, 5)

                plot_dir = os.path.join(root_dir, "plots_dy_vs_qcd_mc_vs_data%s_z_reweight" % (gr_append))

                subplot_title = "MC / Data"
                subplot_limits = (0.5, 1.5)

                xlabel = ang.name + " (" + ang.lambda_str + ")"
                if gr_append is not "":
                    xlabel = "Groomed " + ang.name + " (" + ang.lambda_str + ")"

                # zpj only
                qgp.do_comparison_plot(zpj_entries,
                                       "%s/ptBinned/%s_pt%dto%d_zpj.%s" % (plot_dir, v, start_val, end_val, OUTPUT_FMT),
                                       rebin=rebin,
                                       title="%d < p_{T}^{jet} < %d GeV\n%s\n%s" % (start_val, end_val, jet_str, qgc.ZpJ_LABEL),
                                       xtitle=xlabel,
                                       xlim=xlim,
                                       ylim=ylim,
                                       subplot_type='ratio',
                                       subplot_title=subplot_title,
                                       subplot_limits=subplot_limits)


            # Do overall summary plots across all pt bins
            # ------------------------------------------------------------------
            ylim_mean = None
            if "width" in v_lower or "ptd" in v_lower:
                ylim_mean = (0, 0.4)
            elif"thrust" in v_lower:
                ylim_mean = (0, 0.5)
            elif "multiplicity" in v_lower and "ak4" in root_dir.lower():
                ylim_mean = (0, 100)
                ylim_mean = (0, 80)
                if end_val < 150:
                    ylim_mean = (0, 50)
            ylim_mean=None
            ylim_rms=None

            # Setup variable names for MPL
            marker = ""
            if "_" in ang.name or "^" in ang.name:
                marker = "$"
            var_label = marker + ang.name + marker + " ($%s$)" % ang.lambda_str
            if gr_append != "":
                var_label = "Groomed " + marker + ang.name + marker + " ($%s$)" % ang.lambda_str


            # zpj_1d_entries[i][j] is the jth sample in the ith pt bin
            qgp.do_mean_rms_summary_plot(zpj_1d_entries[:],
                                         pt_bins[:],
                                         "%s/ptBinned/%s_box_zpj_mpl.%s" % (plot_dir, v, OUTPUT_FMT),
                                         var_label=var_label,
                                         xlim=(50, 614),
                                         ylim_mean=ylim_mean,
                                         ylim_rms=ylim_rms,
                                         region_title="%s jets in %s" % (jet_str, qgc.ZpJ_LABEL))
def do_gen_reco_comparison_plots(root_dir,
                                 var_list=None,
                                 gen_var_prepend="gen",
                                 reco_var_prepend="",
                                 plot_dir="plot_reco_gen",
                                 zpj_reco_dirname=qgc.ZPJ_RECOJET_RDIR,
                                 dj_reco_dirname=qgc.DJ_RECOJET_RDIR,
                                 zpj_gen_dirname=qgc.ZPJ_GENJET_RDIR,
                                 dj_gen_dirname=qgc.DJ_GENJET_RDIR,
                                 pt_bins=qgc.THEORY_PT_BINS,
                                 subplot_type=None):
    var_list = var_list or qgc.COMMON_VARS
    for ang in var_list:
        v_reco = "%s%s_vs_pt" % (reco_var_prepend, ang.var)
        v_gen = "%s%s_vs_pt" % (gen_var_prepend, ang.var)

        h2d_dyj_reco = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                                "%s/%s" % (zpj_reco_dirname, v_reco))
        h2d_qcd_reco = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                                "%s/%s" % (dj_reco_dirname, v_reco))
        h2d_dyj_gen = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                               "%s/%s" % (zpj_gen_dirname, v_gen))
        h2d_qcd_gen = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                               "%s/%s" % (dj_gen_dirname, v_gen))

        if "flavour" not in v_reco:
            h2d_dyj_reco_q = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                                      "%s/q%s" % (zpj_reco_dirname, v_reco))
            h2d_qcd_reco_g = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                                      "%s/g%s" % (dj_reco_dirname, v_reco))
            h2d_dyj_gen_q = grab_obj(os.path.join(root_dir, qgc.DY_FILENAME),
                                     "%s/q%s" % (zpj_gen_dirname, v_gen))
            h2d_qcd_gen_g = grab_obj(os.path.join(root_dir, qgc.QCD_FILENAME),
                                     "%s/g%s" % (dj_gen_dirname, v_gen))

        for (start_val, end_val) in pt_bins:
            lw = 2

            dy_reco_kwargs = dict(line_color=qgc.DY_COLOUR,
                                  fill_color=qgc.DY_COLOUR,
                                  label=qgc.DY_ZpJ_LABEL + " [RecoJet]",
                                  line_width=lw)
            qcd_reco_kwargs = dict(line_color=qgc.QCD_COLOUR,
                                   fill_color=qgc.QCD_COLOUR,
                                   label=qgc.QCD_Dijet_LABEL + " [RecoJet]",
                                   line_width=lw)

            dy_gen_kwargs = dict(line_color=qgc.DY_COLOUR,
                                 fill_color=qgc.DY_COLOUR,
                                 label=qgc.DY_ZpJ_LABEL + " [GenJet]",
                                 line_width=lw,
                                 line_style=2)
            qcd_gen_kwargs = dict(line_color=qgc.QCD_COLOUR,
                                  fill_color=qgc.QCD_COLOUR,
                                  label=qgc.QCD_Dijet_LABEL + " [GenJet]",
                                  line_width=lw,
                                  line_style=2)

            entries = [(qgg.get_projection_plot(h2d_dyj_reco, start_val,
                                                end_val), dy_reco_kwargs),
                       (qgg.get_projection_plot(h2d_qcd_reco, start_val,
                                                end_val), qcd_reco_kwargs),
                       (qgg.get_projection_plot(h2d_dyj_gen, start_val,
                                                end_val), dy_gen_kwargs),
                       (qgg.get_projection_plot(h2d_qcd_gen, start_val,
                                                end_val), qcd_gen_kwargs)]

            rebin = 2
            xlim = None
            ylim = None
            if "flavour" in v_reco:
                rebin = 1
                ylim = (0, 1)
            if "thrust" in v_reco:
                xlim = (0, 0.5)

            qgg.do_comparison_plot(
                entries,
                "%s/%s/%s_pt%dto%d.%s" %
                (root_dir, plot_dir, ang.var, start_val, end_val, OUTPUT_FMT),
                rebin=rebin,
                title="%d < p_{T}^{jet} < %d GeV" % (start_val, end_val),
                xtitle=ang.name + " (" + ang.lambda_str + ")",
                xlim=xlim,
                ylim=ylim,
                subplot_type=subplot_type)

            # Do flavour-tagged comparison
            if "flavour" in v_reco:
                continue

            dy_reco_kwargs['label'] = qgc.DY_ZpJ_QFLAV_LABEL + " [RecoJet]"
            qcd_reco_kwargs['label'] = qgc.QCD_Dijet_GFLAV_LABEL + " [RecoJet]"
            dy_gen_kwargs['label'] = qgc.DY_ZpJ_QFLAV_LABEL + " [GenJet]"
            qcd_gen_kwargs['label'] = qgc.QCD_Dijet_GFLAV_LABEL + " [GenJet]"

            entries = [(qgg.get_projection_plot(h2d_dyj_reco_q, start_val,
                                                end_val), dy_reco_kwargs),
                       (qgg.get_projection_plot(h2d_qcd_reco_g, start_val,
                                                end_val), qcd_reco_kwargs),
                       (qgg.get_projection_plot(h2d_dyj_gen_q, start_val,
                                                end_val), dy_gen_kwargs),
                       (qgg.get_projection_plot(h2d_qcd_gen_g, start_val,
                                                end_val), qcd_gen_kwargs)]

            qgg.do_comparison_plot(
                entries,
                "%s/%s/%s_flavMatched_pt%dto%d.%s" %
                (root_dir, plot_dir, ang.var, start_val, end_val, OUTPUT_FMT),
                rebin=rebin,
                title="%d < p_{T}^{jet} < %d GeV" % (start_val, end_val),
                xtitle=ang.name + " (" + ang.lambda_str + ")",
                xlim=xlim,
                ylim=ylim,
                subplot_type=subplot_type)