def do_dijet_distributions(root_dir, title):
    """Do plots comparing different different inputs in dijet region"""
    # root_files = [qgc.JETHT_ZB_FILENAME, qgc.QCD_FILENAME, qgc.QCD_PYTHIA_ONLY_FILENAME, qgc.QCD_HERWIG_FILENAME]
    # root_files = [qgc.JETHT_ZB_FILENAME, qgc.QCD_FILENAME, qgc.QCD_PYTHIA_ONLY_FILENAME]
    root_files = [
        qgc.JETHT_ZB_FILENAME, qgc.QCD_FILENAME, qgc.QCD_HERWIG_FILENAME
    ][:]
    # root_files = [qgc.JETHT_ZB_FILENAME, qgc.QCD_FILENAME]
    # root_files = [qgc.JETHT_ZB_FILENAME, qgc.QCD_PYTHIA_ONLY_FILENAME]
    # root_files = [qgc.JETHT_ZB_FILENAME, qgc.QCD_HERWIG_FILENAME]

    if not all(os.path.isfile(os.path.join(root_dir, r)) for r in root_files):
        print("Cannot find ROOT files, skipping dijet kinematic plots")
        return

    root_files = [
        cu.TFileCacher(os.path.join(root_dir, r)) for r in root_files
    ]

    # herwig_dir = "workdir_ak4chs_herwig_newFlav_withPUreweight_withMuSF"
    # herwig_dir = "workdir_ak4chs_herwig_newFlav_withPUreweight_withMuSF_noExtraJetCuts"
    # root_files.append(cu.TFileCacher(os.path.join(herwig_dir, qgc.QCD_FILENAME)))

    # directories = [rf.get("Dijet") for rf in root_files]
    directories = [rf.get("Dijet_tighter") for rf in root_files[:]]
    # directories.extend([rf.get("Dijet_tighter") for rf in root_files[1:]])
    mc_col = qgc.QCD_COLOUR
    mc_col2 = qgc.QCD_COLOURS[2]
    # mc_col3 = qgc.QCD_COLOURS[3]
    data_col = qgc.JETHT_COLOUR
    zb_col = ROOT.kGreen + 2
    msize = 0.75
    csd = [
        {
            "label": "Data",
            "line_color": data_col,
            "fill_color": data_col,
            "marker_color": data_col,
            "marker_style": 20,
            "fill_style": 0,
            "marker_size": msize,
            'line_width': 2
        },
        {
            "label": "QCD MC [MG+PY8]",
            "line_color": mc_col,
            "fill_color": mc_col,
            "marker_color": mc_col,
            "marker_style": 22,
            "fill_style": 0,
            "marker_size": msize
        },
        # {"label": "QCD MC [PY8]", "line_color": mc_col2, "fill_color": mc_col2, "marker_color": mc_col2, "marker_style": 21, "fill_style": 0, "marker_size": msize},
        {
            "label": "QCD MC [H++]",
            "line_color": qgc.HERWIGPP_QCD_COLOUR,
            "fill_color": qgc.HERWIGPP_QCD_COLOUR,
            "marker_color": qgc.HERWIGPP_QCD_COLOUR,
            "marker_style": 23,
            "fill_style": 0,
            "marker_size": msize
        },
    ]
    jet_config_str = qgc.extract_jet_config(root_dir)

    # Compare yields
    do_all_1D_projection_plots_in_dir(
        directories=directories,
        output_dir=os.path.join(root_dir,
                                "Dijet_data_mc_kin_comparison_absolute2"),
        #                                   # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_absolute_pythiaOnly"),
        # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_absolute_both"),
        # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_absolute_everything"),
        #                                   # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_absolute_all"),
        components_styles_dicts=csd,
        region_str=qgc.Dijet_LABEL,
        jet_config_str=jet_config_str,
        normalise_hists=False,
        bin_by='ave')

    # Compare shapes
    do_all_1D_projection_plots_in_dir(
        directories=directories,
        output_dir=os.path.join(root_dir,
                                "Dijet_data_mc_kin_comparison_normalised2"),
        # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_normalised_pythiaOnly"),
        # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_normalised_both"),
        # output_dir=os.path.join(root_dir, "Dijet_data_mc_kin_comparison_normalised_all"),
        components_styles_dicts=csd,
        region_str=qgc.Dijet_LABEL,
        jet_config_str=jet_config_str,
        title=title,
        bin_by='ave')

    # Do eta-ordered
    directories = [rf.get("Dijet_eta_ordered") for rf in root_files[:]]
    do_all_1D_projection_plots_in_dir(
        directories=directories,
        output_dir=os.path.join(
            root_dir, "Dijet_data_mc_kin_comparison_eta_ordered_normalised2"),
        components_styles_dicts=csd,
        region_str=qgc.Dijet_LABEL,
        jet_config_str=jet_config_str,
        title=title,
        bin_by='ave')
def do_zpj_distributions(root_dir, title):
    """Do plots comparing different different inputs in Z+jet region"""
    # root_files = [qgc.SINGLE_MU_FILENAME, qgc.DY_FILENAME, qgc.DY_HERWIG_FILENAME, qgc.DY_MG_HERWIG_FILENAME]
    root_files = [
        qgc.SINGLE_MU_FILENAME, qgc.DY_FILENAME, qgc.DY_HERWIG_FILENAME
    ]

    if not all([os.path.isfile(os.path.join(root_dir, r))
                for r in root_files]):
        print("Cannot find ROOT files, skipping Z+J kinematic plots")
        return

    root_files = [
        cu.TFileCacher(os.path.join(root_dir, r)) for r in root_files
    ]

    directories = [rf.get("ZPlusJets") for rf in root_files]
    data_col = qgc.SINGLE_MU_COLOUR
    mc_col = qgc.DY_COLOUR
    mc_col2 = qgc.HERWIGPP_DY_COLOUR
    mc_col3 = qgc.DY_COLOURS[3]
    msize = 0.75
    csd = [
        {
            "label": "Data",
            "line_color": data_col,
            "fill_color": data_col,
            "marker_color": data_col,
            "marker_style": 20,
            "fill_style": 0,
            "marker_size": msize
        },
        {
            "label": "DY+Jets MC [MG+PY8]",
            "line_color": mc_col,
            "fill_color": mc_col,
            "marker_color": mc_col,
            "marker_style": 21,
            "fill_style": 0,
            "marker_size": msize
        },
        {
            "label": "DY+Jets MC [H++]",
            "line_color": mc_col2,
            "fill_color": mc_col2,
            "marker_color": mc_col2,
            "marker_style": 23,
            "fill_style": 0,
            "marker_size": msize
        },
        # {"label": "DY+Jets MC [MG+H++]", "line_color": mc_col3, "fill_color": mc_col3, "marker_color": mc_col3, "marker_style": 22, "fill_style": 0, "marker_size": msize},
    ]
    jet_config_str = qgc.extract_jet_config(root_dir)

    # Compare yields
    do_all_1D_projection_plots_in_dir(
        directories=directories,
        output_dir=os.path.join(root_dir,
                                "ZPlusJets_data_mc_kin_comparison_absolute2"),
        # output_dir=os.path.join(root_dir, "ZPlusJets_data_mc_kin_comparison_absolute_compareKFactor"),
        # output_dir=os.path.join(root_dir, "ZPlusJets_data_mc_kin_comparison_absolute_all"),
        components_styles_dicts=csd,
        jet_config_str=jet_config_str,
        normalise_hists=False,
        region_str=qgc.ZpJ_LABEL,
        bin_by='Z')

    # Compare shapes
    do_all_1D_projection_plots_in_dir(
        directories=directories,
        output_dir=os.path.join(
            root_dir, "ZPlusJets_data_mc_kin_comparison_normalised_compare2"),
        # output_dir=os.path.join(root_dir, "ZPlusJets_data_mc_kin_comparison_normalised_compare_KFactor"),
        # output_dir=os.path.join(root_dir, "ZPlusJets_data_mc_kin_comparison_normalised_all"),
        jet_config_str=jet_config_str,
        title=title,
        components_styles_dicts=csd,
        normalise_hists=True,
        region_str=qgc.ZpJ_LABEL,
        bin_by='Z')
Пример #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))
Пример #4
0
ROOT.gROOT.SetBatch(1)
ROOT.TH1.SetDefaultSumw2()
ROOT.gStyle.SetOptStat(0)
ROOT.gErrorIgnoreLevel = ROOT.kWarning

# Control plot output format
OUTPUT_FMT = "pdf"

if __name__ == "__main__":

    NO_SF_DIR = "workdir_ak4puppi_data_trigBinningBetter2_jetAsymCut_pt1RecoConstituents_V11JEC_JER_tUnfoldBetter_target0p5_wta_groomed_fwdcenDijet_Zreweight_noZjet2Cut_newBinningFixed"
    NOMINAL_SF_DIR = "workdir_ak4puppi_data_trigBinningBetter2_jetAsymCut_pt1RecoConstituents_V11JEC_JER_tUnfoldBetter_target0p5_wta_groomed_fwdcenDijet_Zreweight_noZjet2Cut_newBinningFixed_trkSFMyFormula"
    SF_UP_DIR = "workdir_ak4puppi_data_trigBinningBetter2_jetAsymCut_pt1RecoConstituents_V11JEC_JER_tUnfoldBetter_target0p5_wta_groomed_fwdcenDijet_Zreweight_noZjet2Cut_newBinningFixed_trkSFMyFormula/systematics_files/track_directionUp"
    SF_DOWN_DIR = "workdir_ak4puppi_data_trigBinningBetter2_jetAsymCut_pt1RecoConstituents_V11JEC_JER_tUnfoldBetter_target0p5_wta_groomed_fwdcenDijet_Zreweight_noZjet2Cut_newBinningFixed_trkSFMyFormula/systematics_files/track_directionDown"

    QCD_NO_SF_TFILE = cu.TFileCacher(os.path.join(NO_SF_DIR, qgc.QCD_FILENAME))
    QCD_NOMINAL_SF_TFILE = cu.TFileCacher(
        os.path.join(NOMINAL_SF_DIR, qgc.QCD_FILENAME))
    QCD_SF_UP_TFILE = cu.TFileCacher(os.path.join(SF_UP_DIR, qgc.QCD_FILENAME))
    QCD_SF_DOWN_TFILE = cu.TFileCacher(
        os.path.join(SF_DOWN_DIR, qgc.QCD_FILENAME))

    DY_NO_SF_TFILE = cu.TFileCacher(os.path.join(NO_SF_DIR, qgc.DY_FILENAME))
    DY_NOMINAL_SF_TFILE = cu.TFileCacher(
        os.path.join(NOMINAL_SF_DIR, qgc.DY_FILENAME))
    DY_SF_UP_TFILE = cu.TFileCacher(os.path.join(SF_UP_DIR, qgc.DY_FILENAME))
    DY_SF_DOWN_TFILE = cu.TFileCacher(
        os.path.join(SF_DOWN_DIR, qgc.DY_FILENAME))

    # QG variable plots
    pt_bins = qgc.PT_BINS[:]
        if not first_drawing:
            draw_opt += " SAME"
        merged_hist.Draw(draw_opt)
        first_drawing = False
        leg_entries.append([merged_hist, 'Combined inclusive + high pT'])

    leg = create_legend(leg_entries)
    leg.Draw()

    c.SaveAs(output_filename)
    return c


if __name__ == "__main__":
    workdir = "workdir_ak4puppi_data_target0p5_ZReweight_wta_groomed_fwdcenDijet_betterLargeWeightVeto_noPtHatCut_noPtReweight_noZjet2Cut_zPt30_trkSF_wtaAK_fixPrescales_sameGenCuts"
    tfile_incl = cu.TFileCacher(os.path.join(workdir, qgc.DY_HERWIG_INCL_FILENAME))
    tfile_low_pt = cu.TFileCacher(os.path.join(workdir, qgc.DY_HERWIG_LOW_PT_FILENAME))
    tfile_high_pt = cu.TFileCacher(os.path.join(workdir, qgc.DY_HERWIG_HIGH_PT_FILENAME))
    # tfile_merged = cu.TFileCacher(os.path.join(workdir, qgc.DY_HERWIG_LOW_HIGH_PT_FILENAME))

    plot_dir = os.path.join(workdir, "PartonKtMin300")
    if not os.path.isdir(plot_dir):
        os.makedirs(plot_dir)

    # q scale plot
    qscale_name = "ZPlusJets_gen/q_scale"
    h_qscale_incl = tfile_incl.Get(qscale_name)
    style_incl_hist(h_qscale_incl)
    h_qscale_low_pt = tfile_low_pt.Get(qscale_name)
    style_low_pt_hist(h_qscale_low_pt)
    h_qscale_high_pt = tfile_high_pt.Get(qscale_name)
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))
    plot.set_logy(do_more_labels=False)
    plot.save(output_filename)
    ROOT.gStyle.SetPalette(ROOT.kViridis)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("source", help="Source file")
    parser.add_argument("--outputDir",
                        help="Output dir (default is source dir)")
    args = parser.parse_args()

    if not os.path.isfile(args.source):
        raise IOError("source file doesn't exist")

    in_tfile = cu.TFileCacher(args.source)
    is_data = '.DATA.' in os.path.basename(args.source)
    if is_data:
        print("This script is only useful for MC files, exiting")
        exit()

    is_dijet = '_QCD.root' in os.path.basename(args.source)

    if not args.outputDir:
        in_dir = os.path.dirname(args.source)
        args.outputDir = os.path.join(in_dir, 'pf_matching_plots')
        if is_dijet:
            args.outputDir += "_dijet"
        else:
            args.outputDir += "_zpj"