示例#1
0
def do_mc_pt_comparison_plot(dirname_label_pairs, output_filename,
                             qcd_filename, **plot_kwargs):
    # qcd_files = [cu.open_root_file(os.path.join(dl[0], qgc.QCD_FILENAME)) for dl in dirname_label_pairs]
    qcd_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.QCD_PYTHIA_ONLY_FILENAME))
        for dl in dirname_label_pairs
    ]
    histname = "Dijet_tighter/pt_jet1"
    qcd_hists = [cu.get_from_tfile(qf, histname) for qf in qcd_files]
    N = len(dirname_label_pairs)
    conts = [
        Contribution(qcd_hists[i],
                     label=lab,
                     marker_color=cu.get_colour_seq(i, N),
                     line_color=cu.get_colour_seq(i, N),
                     line_style=(i % 3) + 1,
                     line_width=2,
                     rebin_hist=1,
                     subplot=qcd_hists[0] if i != 0 else None)
        for i, (d, lab) in enumerate(dirname_label_pairs)
    ]
    plot = Plot(conts,
                what='hist',
                ytitle="N",
                subplot_limits=(0.5, 1.5),
                subplot_type="ratio",
                subplot_title="* / %s" % (dirname_label_pairs[0][1]),
                **plot_kwargs)
    plot.y_padding_max_log = 500
    plot.legend.SetY1(0.7)
    plot.plot("NOSTACK HIST E")
    plot.set_logx(do_more_labels=False)
    plot.set_logy(do_more_labels=False)

    plot.save(output_filename)
def do_jet_pt_rel_error_with_var_cuts(histname, cuts, input_filename, output_filename):
    ROOT.gStyle.SetPalette(palette_1D)
    tf = cu.open_root_file(input_filename)
    h3d = cu.get_from_tfile(tf, histname)
    if h3d.GetEntries() == 0:
        return
    pt_hists = []
    for cut in cuts:
        max_bin = h3d.GetZaxis().FindFixBin(cut)
        # print("cut:", cut, "bin:", max_bin)
        h = h3d.ProjectionY("pt_var_lt_%g" % cut, 0, -1, 0, max_bin, "e")
        h2 = h.Clone()
        h2.Rebin(2)
        if h.GetEntries() > 0:
            h3 = qgp.hist_divide_bin_width(h2)
        # convert bin contents to bin error/bin contents
        for ibin in range(1, h2.GetNbinsX()+1):
            if h3.GetBinContent(ibin) == 0:
                continue
            h3.SetBinContent(ibin, h3.GetBinError(ibin) / h3.GetBinContent(ibin))
            h3.SetBinError(ibin, 0)
        pt_hists.append(h3)

    line_styles = [1, 2, 3]
    n_line_styles = len(line_styles)
    conts = [Contribution(h, label=" < %g" % cut,
                          line_color=cu.get_colour_seq(ind, len(cuts)),
                          line_style=line_styles[ind % n_line_styles],
                          line_width=2,
                          marker_color=cu.get_colour_seq(ind, len(cuts)),
                          subplot=pt_hists[-1])
             for ind, (h, cut) in enumerate(zip(pt_hists, cuts))]

    jet_str = pt_genjet_str if "_vs_pt_genjet_vs_" in histname else pt_str
    weight_str = "(unweighted)" if "unweighted" in histname else "(weighted)"
    ratio_lims = (0.98, 1.02) if "unweighted" in histname else None
    plot = Plot(conts, what='hist',
                title='%s for cuts on %s %s' % (jet_str, get_var_str(histname), weight_str),
                xtitle=None,
                ytitle='Relative error',
                # xlim=None, ylim=None,
                legend=True,
                subplot_type='ratio',
                subplot_title='* / var < %g' % cuts[-1],
                subplot_limits=ratio_lims,
                has_data=False)
    plot.y_padding_max_log = 200
    plot.subplot_maximum_ceil = 2
    plot.subplot_maximum_floor = 1.02
    plot.subplot_minimum_ceil = 0.98
    plot.legend.SetY1(0.7)
    plot.legend.SetY2(0.89)
    plot.legend.SetX1(0.78)
    plot.legend.SetX2(0.88)
    plot.plot("NOSTACK HISTE", "NOSTACK HIST")
    plot.set_logx(True, do_more_labels=True)
    plot.set_logy(True, do_more_labels=False)
    plot.save(output_filename)
示例#3
0
def do_data_mc_plot(dirname, histname, output_filename, **plot_kwargs):
    data_file = cu.open_root_file(os.path.join(dirname, qgc.JETHT_ZB_FILENAME))
    qcd_file = cu.open_root_file(os.path.join(dirname, qgc.QCD_FILENAME))
    qcd_py_file = cu.open_root_file(
        os.path.join(dirname, qgc.QCD_PYTHIA_ONLY_FILENAME))
    qcd_hpp_file = cu.open_root_file(
        os.path.join(dirname, qgc.QCD_HERWIG_FILENAME))

    data_hist = cu.get_from_tfile(data_file, histname)
    qcd_hist = cu.get_from_tfile(qcd_file, histname)
    qcd_py_hist = cu.get_from_tfile(qcd_py_file, histname)
    qcd_hpp_hist = cu.get_from_tfile(qcd_hpp_file, histname)
    conts = [
        Contribution(data_hist,
                     label="Data",
                     line_color=ROOT.kBlack,
                     marker_size=0,
                     marker_color=ROOT.kBlack),
        Contribution(qcd_hist,
                     label="QCD MG+PYTHIA8 MC",
                     line_color=qgc.QCD_COLOUR,
                     subplot=data_hist,
                     marker_size=0,
                     marker_color=qgc.QCD_COLOUR),
        Contribution(qcd_py_hist,
                     label="QCD PYTHIA8 MC",
                     line_color=qgc.QCD_COLOURS[2],
                     subplot=data_hist,
                     marker_size=0,
                     marker_color=qgc.QCD_COLOURS[2]),
        # Contribution(qcd_hpp_hist, label="QCD HERWIG++ MC", line_color=qgc.HERWIGPP_QCD_COLOUR, subplot=data_hist, marker_size=0, marker_color=qgc.HERWIGPP_QCD_COLOUR),
    ]
    plot = Plot(conts,
                what='hist',
                ytitle="N",
                xtitle="p_{T}^{Leading jet} [GeV]",
                subplot_type="ratio",
                subplot_title="Simulation / data",
                ylim=[1E3, None],
                lumi=cu.get_lumi_str(do_dijet=True, do_zpj=False),
                **plot_kwargs)
    plot.y_padding_max_log = 500

    plot.legend.SetX1(0.55)
    plot.legend.SetX2(0.98)
    plot.legend.SetY1(0.7)
    # plot.legend.SetY2(0.88)
    plot.plot("NOSTACK HIST E")
    plot.set_logx(do_more_labels=True, do_exponent=False)
    plot.set_logy(do_more_labels=False)

    plot.save(output_filename)
示例#4
0
def do_genht_plot(dirname, output_filename, **plot_kwargs):
    qcd_file = cu.open_root_file(os.path.join(dirname, qgc.QCD_FILENAME))
    histname = "Dijet_gen/gen_ht"
    qcd_hist = cu.get_from_tfile(qcd_file, histname)
    conts = [Contribution(qcd_hist, label="QCD MC", line_color=ROOT.kRed)]
    plot = Plot(conts, what='hist', ytitle="N", **plot_kwargs)
    plot.y_padding_max_log = 500
    plot.legend.SetY1(0.7)
    plot.plot("NOSTACK HIST E")
    plot.set_logx(do_more_labels=False)
    plot.set_logy(do_more_labels=False)

    plot.save(output_filename)
示例#5
0
def do_pthat_comparison_plot(dirname_label_pairs, output_filename,
                             **plot_kwargs):
    qcd_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.QCD_PYTHIA_ONLY_FILENAME))
        for dl in dirname_label_pairs
    ]
    histname = "Dijet_gen/ptHat"
    qcd_hists = [cu.get_from_tfile(qf, histname) for qf in qcd_files]
    N = len(dirname_label_pairs)
    pthat_rebin = array('d', [
        15, 30, 50, 80, 120, 170, 300, 470, 600, 800, 1000, 1400, 1800, 2400,
        3200, 5000
    ])
    nbins = len(pthat_rebin) - 1
    qcd_hists = [
        h.Rebin(nbins, cu.get_unique_str(), pthat_rebin) for h in qcd_hists
    ]
    conts = [
        Contribution(qcd_hists[i],
                     label=lab,
                     marker_color=cu.get_colour_seq(i, N),
                     line_color=cu.get_colour_seq(i, N),
                     line_style=i + 1,
                     line_width=2,
                     subplot=qcd_hists[0] if i != 0 else None)
        for i, (d, lab) in enumerate(dirname_label_pairs)
    ]
    plot = Plot(conts,
                what='hist',
                ytitle="N",
                subplot_limits=(0.75, 1.25),
                subplot_type="ratio",
                subplot_title="* / %s" % (dirname_label_pairs[0][1]),
                **plot_kwargs)
    plot.y_padding_max_log = 500
    plot.legend.SetY1(0.7)
    plot.plot("NOSTACK HIST E")
    plot.set_logx(do_more_labels=False)
    plot.set_logy(do_more_labels=False)

    plot.save(output_filename)
示例#6
0
def do_genht_comparison_plot(dirname_label_pairs, output_filename,
                             **plot_kwargs):
    """Like do_genht but for multiple samples"""
    qcd_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.QCD_FILENAME))
        for dl in dirname_label_pairs
    ]
    histname = "Dijet_gen/gen_ht"
    qcd_hists = [cu.get_from_tfile(qf, histname) for qf in qcd_files]
    N = len(dirname_label_pairs)
    conts = [
        Contribution(qcd_hists[i],
                     label=lab,
                     marker_color=cu.get_colour_seq(i, N),
                     line_color=cu.get_colour_seq(i, N),
                     line_style=i + 1,
                     line_width=2,
                     subplot=qcd_hists[0] if i != 0 else None)
        for i, (d, lab) in enumerate(dirname_label_pairs)
    ]
    plot = Plot(
        conts,
        what='hist',
        ytitle="N",
        # subplot_limits=(0.75, 1.25),
        subplot_type="ratio",
        subplot_title="* / %s" % (dirname_label_pairs[0][1]),
        ylim=[1E6, None],
        **plot_kwargs)
    plot.y_padding_max_log = 500
    plot.legend.SetY1(0.7)
    plot.subplot_maximum_ceil = 5
    plot.plot("NOSTACK HIST E")
    plot.set_logx(do_more_labels=False)
    plot.set_logy(do_more_labels=False)

    plot.save(output_filename)
def do_jet_pt_with_var_cuts(histname, cuts, input_filename, output_filename):
    ROOT.gStyle.SetPalette(palette_1D)
    total = len(cuts) - 1 + .1 # slight offset to not hit the maximum or minimum
    # if len(cuts) <= 3:
        # ROOT.gStyle.SetPalette(ROOT.kCool)
        # num_colours = ROOT.TColor.GetPalette().fN - 1
        # print('num_colours:', num_colours)
        # for index in range(len(cuts)):
        #     print(num_colours, index, len(cuts), index / len(cuts), num_colours * index / total)
        #     print(index, ROOT.TColor.GetColorPalette(int(num_colours * 1. * index / total)))
    tf = cu.open_root_file(input_filename)
    h3d = cu.get_from_tfile(tf, histname)
    if h3d.GetEntries() == 0:
        return
    pt_hists = []
    for cut in cuts:
        max_bin = h3d.GetZaxis().FindFixBin(cut)
        # print("cut:", cut, "bin:", max_bin)
        h = h3d.ProjectionY("pt_var_lt_%g" % cut, 0, -1, 0, max_bin, "e")
        h2 = h.Clone()
        h2.Rebin(2)
        if h.GetEntries() > 0:
            h3 = qgp.hist_divide_bin_width(h2)
        pt_hists.append(h3)

    line_styles = [1, 2, 3]
    if len(cuts) <= 3:
        line_styles = [1]
    n_line_styles = len(line_styles)
    ref_ind = 0
    conts = [Contribution(h, label=" < %g" % cut,
                          line_color=cu.get_colour_seq(ind, total),
                          line_style=line_styles[ind % n_line_styles],
                          line_width=2,
                          marker_color=cu.get_colour_seq(ind, total),
                          subplot=pt_hists[ref_ind] if ind != ref_ind else None)
             for ind, (h, cut) in enumerate(zip(pt_hists, cuts))]

    jet_str = pt_genjet_str if "_vs_pt_genjet_vs_" in histname else pt_str
    weight_str = "(unweighted)" if "unweighted" in histname else "(weighted)"
    ratio_lims = (0.5, 2.5)
    ratio_lims = (0.5, 1.1)
    plot = Plot(conts, what='hist',
                title='%s for cuts on %s %s' % (jet_str, get_var_str(histname), weight_str),
                xtitle=None,
                ytitle='N',
                # xlim=None, ylim=None,
                legend=True,
                subplot_type='ratio',
                subplot_title='* / var < %g' % cuts[ref_ind],
                subplot_limits=ratio_lims,
                has_data=False)
    plot.y_padding_max_log = 200
    plot.subplot_maximum_ceil = 4
    plot.subplot_maximum_floor = 1.02
    plot.subplot_minimum_ceil = 0.98
    plot.legend.SetY1(0.7)
    plot.legend.SetY2(0.89)
    plot.legend.SetX1(0.78)
    plot.legend.SetX2(0.88)
    plot.plot("NOSTACK HISTE", "NOSTACK HIST")
    plot.set_logx(True, do_more_labels=True)
    plot.set_logy(True, do_more_labels=False)
    plot.save(output_filename)
示例#8
0
def do_zerobias_per_run_comparison_plot(dirname_label_pairs,
                                        output_dir,
                                        append="",
                                        title="",
                                        **plot_kwargs):
    runs = [
        (qgc.ZEROBIAS_RUNB_FILENAME, 'B'),
        (qgc.ZEROBIAS_RUNC_FILENAME, 'C'),
        (qgc.ZEROBIAS_RUND_FILENAME, 'D'),
        (qgc.ZEROBIAS_RUNE_FILENAME, 'E'),
        (qgc.ZEROBIAS_RUNF_FILENAME, 'F'),
        (qgc.ZEROBIAS_RUNG_FILENAME, 'G'),
        (qgc.ZEROBIAS_RUNH_FILENAME, 'H'),
    ]
    zb_entry = {
        'label': 'HLT_ZeroBias',
        'color': ROOT.kMagenta - 9,
        # 'scale': 35918219492.947 / 29048.362
        'scale': 1
    }

    for filename, run_period in runs:
        zb_root_files = [
            cu.open_root_file(os.path.join(dl[0], filename))
            for dl in dirname_label_pairs
        ]

        # PT JET 1
        zb_hist_names = [
            "Dijet_jet_hist_0/pt_1", "Dijet_jet_hist_unweighted_0/pt_1"
        ][1:]
        N = len(dirname_label_pairs)
        rebin = 2
        for zb_name in zb_hist_names:
            # add zeero bias ones
            this_data_entries = [
                Contribution(
                    cu.get_from_tfile(zb_root_files[i], zb_name),
                    label=zb_entry['label'] + " Run %s: " % run_period + l,
                    marker_color=zb_entry['color'],
                    line_color=zb_entry['color'],
                    line_style=1 + i,
                    rebin_hist=rebin,
                ) for i, (d, l) in enumerate(dirname_label_pairs)
            ]
            for c in this_data_entries[1:]:
                c.subplot = this_data_entries[0].obj

            plot = Plot(
                this_data_entries,
                what='hist',
                title=title,
                xtitle="p_{T}^{jet 1} [GeV]",
                ytitle="N",
                xlim=[30, 1000],
                ylim=[1E3, None],
                # ylim=[10, 1E8] if 'unweighted' in ht_name else [1, 1E12],
                subplot_type='ratio',
                subplot_title='* / %s' % dirname_label_pairs[0][1],
                **plot_kwargs)
            plot.subplot_maximum_ceil = 10
            plot.default_canvas_size = (800, 600)
            plot.y_padding_max_log = 500
            plot.legend.SetY1(0.7)
            plot.legend.SetY2(0.88)
            plot.legend.SetX1(0.5)
            plot.legend.SetNColumns(2)
            plot.plot("NOSTACK HISTE")
            plot.set_logx(do_more_labels=False)
            plot.set_logy(do_more_labels=False)
            output_filename = "%s/DataJetHTZB-pt_jet1%s_Run%s%s.pdf" % (
                output_dir, "_unweighted" if 'unweighted' in zb_name else "",
                run_period, append)
            plot.save(output_filename)

        # ETA JET 1
        zb_hist_names = ["Dijet_jet_hist_unweighted_0/eta_1"]

        N = len(dirname_label_pairs)
        rebin = 2
        for zb_name in zb_hist_names:
            # add zero bias ones
            this_data_entries = [
                Contribution(
                    cu.get_from_tfile(zb_root_files[i], zb_name),
                    label=zb_entry['label'] + " Run %s: " % run_period + l,
                    marker_color=zb_entry['color'],
                    line_color=zb_entry['color'],
                    line_style=1 + i,
                    rebin_hist=rebin,
                ) for i, (d, l) in enumerate(dirname_label_pairs)
            ]
            for c in this_data_entries[1:]:
                c.subplot = this_data_entries[0].obj

            # plot zb
            plot = Plot(
                this_data_entries,
                what='hist',
                title=title,
                xtitle="y^{jet 1}",
                ytitle="N",
                subplot_type='ratio',
                subplot_title='* / %s' % dirname_label_pairs[0][1],
                # subplot_limits=(0, 5),
                **plot_kwargs)
            plot.subplot_maximum_ceil = 5
            plot.default_canvas_size = (800, 600)
            plot.y_padding_max_log = 500
            plot.legend.SetY1(0.7)
            plot.legend.SetY2(0.88)
            plot.legend.SetX1(0.5)
            plot.legend.SetNColumns(2)
            plot.plot("NOSTACK HISTE")
            output_filename = "%s/DataZB-eta_jet1%s_Run%s%s.pdf" % (
                output_dir, "_unweighted" if 'unweighted' in zb_name else "",
                run_period, append)
            plot.save(output_filename)
示例#9
0
def do_jetht_trigger_comparison_plot(dirname_label_pairs,
                                     output_dir,
                                     append="",
                                     title="",
                                     **plot_kwargs):
    # Unweighted pt, showing contributions from different triggers
    # Have to add in ZB manually
    zb_entry = {
        'label': 'HLT_ZeroBias',
        'color': ROOT.kMagenta - 9,
        # 'scale': 35918219492.947 / 29048.362
        'scale': 1
    }

    jet_ht_entries = [
        {
            'ind': '0',
            'label': "PFJet40",
            'color': ROOT.kRed,
        },
        {
            'ind': '1',
            'label': "PFJet60",
            'color': ROOT.kBlue,
        },
        {
            'ind': '2',
            'label': "PFJet80",
            'color': ROOT.kGreen + 2,
        },
        {
            'ind': '3',
            'label': "PFJet140",
            'color': ROOT.kViolet + 5,
        },
        {
            'ind': '4',
            'label': "PFJet200",
            'color': ROOT.kOrange,
        },
        {
            'ind': '5',
            'label': "PFJet260",
            'color': ROOT.kTeal,
        },
        {
            'ind': '6',
            'label': "PFJet320",
            'color': ROOT.kViolet,
        },
        {
            'ind': '7',
            'label': "PFJet400",
            'color': ROOT.kOrange - 6
        },
        {
            'ind': '8',
            'label': "PFJet450",
            'color': ROOT.kAzure + 1,
        },
    ]

    # PT JET 1
    zb_hist_names = [
        "Dijet_jet_hist_0/pt_1", "Dijet_jet_hist_unweighted_0/pt_1"
    ]
    jet_ht_hist_names = [
        "Dijet_jet_hist_{ind}/pt_1", "Dijet_jet_hist_unweighted_{ind}/pt_1"
    ]

    zb_root_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.ZB_FILENAME))
        for dl in dirname_label_pairs
    ]
    jetht_root_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.JETHT_FILENAME))
        for dl in dirname_label_pairs
    ]
    N = len(dirname_label_pairs)
    rebin = 2
    for zb_name, ht_name in zip(zb_hist_names, jet_ht_hist_names):
        # add zeero bias ones
        this_data_entries = [
            Contribution(
                cu.get_from_tfile(zb_root_files[i], zb_name),
                label=zb_entry['label'] + ": " + l,
                marker_color=zb_entry['color'],
                line_color=zb_entry['color'],
                line_style=1 + i,
                rebin_hist=rebin,
            ) for i, (d, l) in enumerate(dirname_label_pairs)
        ]
        for c in this_data_entries[1:]:
            c.subplot = this_data_entries[0].obj

        # # add jet ht ones
        for ent in jet_ht_entries:
            histname = ht_name.format(ind=ent['ind'])
            new_entries = [
                Contribution(
                    cu.get_from_tfile(jetht_root_files[i], histname),
                    label=ent['label'] + ": " + l,
                    marker_color=ent['color'],
                    line_color=ent['color'],
                    line_style=1 + i,
                    rebin_hist=rebin,
                ) for i, (d, l) in enumerate(dirname_label_pairs)
            ]
            for c in new_entries[1:]:
                c.subplot = new_entries[0].obj

            this_data_entries.extend(new_entries)

        plot = Plot(
            this_data_entries,
            what='hist',
            title=title,
            ytitle="N",
            xtitle="p_{T}^{jet 1} [GeV]",
            xlim=[30, 1000],
            ylim=[1E3, None],
            # ylim=[10, 1E8] if 'unweighted' in ht_name else [1, 1E12],
            subplot_type='ratio',
            subplot_title='* / %s' % dirname_label_pairs[0][1],
            **plot_kwargs)
        plot.default_canvas_size = (800, 600)
        plot.subplot_maximum_ceil = 10
        plot.y_padding_max_log = 500
        plot.legend.SetY1(0.7)
        plot.legend.SetY2(0.88)
        plot.legend.SetX1(0.5)
        plot.legend.SetNColumns(2)
        plot.plot("NOSTACK HISTE")
        plot.set_logx(do_more_labels=False)
        plot.set_logy(do_more_labels=False)
        output_filename = "%s/DataJetHTZB-pt_jet1%s%s.pdf" % (
            output_dir, "_unweighted" if 'unweighted' in zb_name else "",
            append)
        plot.save(output_filename)

    # ETA JET 1
    zb_hist_names = ["Dijet_jet_hist_unweighted_0/eta_1"]
    jet_ht_hist_names = ["Dijet_jet_hist_unweighted_{ind}/eta_1"]

    zb_root_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.ZB_FILENAME))
        for dl in dirname_label_pairs
    ]
    jetht_root_files = [
        cu.open_root_file(os.path.join(dl[0], qgc.JETHT_FILENAME))
        for dl in dirname_label_pairs
    ]
    N = len(dirname_label_pairs)
    rebin = 2
    for zb_name, ht_name in zip(zb_hist_names, jet_ht_hist_names):
        # add zero bias ones
        this_data_entries = [
            Contribution(
                cu.get_from_tfile(zb_root_files[i], zb_name),
                label=zb_entry['label'] + ": " + l,
                marker_color=zb_entry['color'],
                line_color=zb_entry['color'],
                line_style=1 + i,
                rebin_hist=rebin,
            ) for i, (d, l) in enumerate(dirname_label_pairs)
        ]
        for c in this_data_entries[1:]:
            c.subplot = this_data_entries[0].obj

        # plot zb
        plot = Plot(
            this_data_entries,
            what='hist',
            title=title,
            xtitle="y^{jet 1}",
            ytitle="N",
            subplot_type='ratio',
            subplot_title='* / %s' % dirname_label_pairs[0][1],
            # subplot_limits=(0, 5),
            **plot_kwargs)
        plot.subplot_maximum_ceil = 5
        plot.default_canvas_size = (800, 600)
        plot.y_padding_max_log = 500
        plot.legend.SetY1(0.7)
        plot.legend.SetY2(0.88)
        plot.legend.SetX1(0.5)
        plot.legend.SetNColumns(2)
        plot.plot("NOSTACK HISTE")
        output_filename = "%s/DataZB-eta_jet1%s%s.pdf" % (
            output_dir, "_unweighted" if 'unweighted' in zb_name else "",
            append)
        plot.save(output_filename)

        # add jet ht ones
        for ent in jet_ht_entries:
            histname = ht_name.format(ind=ent['ind'])
            this_data_entries = [
                Contribution(
                    cu.get_from_tfile(jetht_root_files[i], histname),
                    label=ent['label'] + ": " + l,
                    marker_color=ent['color'],
                    line_color=ent['color'],
                    line_style=1 + i,
                    rebin_hist=rebin,
                ) for i, (d, l) in enumerate(dirname_label_pairs)
            ]
            for c in this_data_entries[1:]:
                c.subplot = this_data_entries[0].obj

            plot = Plot(
                this_data_entries,
                what='hist',
                title=title,
                xtitle="y^{jet 1}",
                ytitle="N",
                # xlim=[30, 1000],
                # ylim=[10, 1E8] if 'unweighted' in ht_name else [1, 1E12],
                subplot_type='ratio',
                subplot_title='* / %s' % dirname_label_pairs[0][1],
                **plot_kwargs)
            plot.default_canvas_size = (800, 600)
            plot.y_padding_max_log = 500
            plot.legend.SetY1(0.7)
            plot.legend.SetY2(0.88)
            plot.legend.SetX1(0.5)
            plot.legend.SetNColumns(2)
            plot.plot("NOSTACK HISTE")
            output_filename = "%s/DataJetHTZB-%s_eta_jet1%s%s.pdf" % (
                output_dir, ent['label'],
                "_unweighted" if 'unweighted' in zb_name else "", append)
            plot.save(output_filename)
    def plot_unfolded_with_yoda_normalised(self,
                                           do_chi2=False,
                                           do_zoomed=True):
        data_total_errors_style = dict(
            label="Data (total unc.)",
            line_color=self.plot_styles['unfolded_total_colour'],
            line_width=self.line_width,
            line_style=1,
            marker_color=self.plot_styles['unfolded_total_colour'],
            marker_style=cu.Marker.get('circle'),
            marker_size=self.plot_styles['unfolded_marker_size'],
            leg_draw_opt="LEP")
        data_stat_errors_style = dict(
            label="Data (stat. unc.)",
            line_color=self.plot_styles['unfolded_stat_colour'],
            line_width=self.line_width,
            line_style=1,
            marker_color=self.plot_styles['unfolded_stat_colour'],
            marker_style=cu.Marker.get('circle'),
            marker_size=0.0001,
            leg_draw_opt="LEP"
        )  # you need a non-0 marker to get the horizontal bars at the end of errors

        mc_style = dict(label=self.region['mc_label'],
                        line_color=self.plot_styles['gen_colour'],
                        line_width=self.line_width,
                        marker_color=self.plot_styles['gen_colour'],
                        marker_size=self.plot_styles['gen_marker_size'],
                        marker_style=self.plot_styles['gen_marker'],
                        leg_draw_opt="LEP"
                        if self.plot_styles['gen_marker_size'] > 0 else "LE")

        rivet_path, rivet_region, rivet_radius, rivet_lambda, rivet_pt_bins = get_matching_rivet_setup(
            self.setup)

        for ibin, (bin_edge_low, bin_edge_high) in enumerate(
                zip(self.bins[:-1], self.bins[1:])):
            hbc_args = dict(ind=ibin, binning_scheme='generator')
            mc_gen_hist_bin = self.hist_bin_chopper.get_pt_bin_normed_div_bin_width(
                'hist_truth', **hbc_args)
            unfolded_hist_bin_stat_errors = self.hist_bin_chopper.get_pt_bin_normed_div_bin_width(
                'unfolded_stat_err', **hbc_args)
            unfolded_hist_bin_total_errors = self.hist_bin_chopper.get_pt_bin_normed_div_bin_width(
                'unfolded', **hbc_args)

            # Get RIVET hists, which are absolute counts, so need normalising
            rivet_hist_name = '/%s/%s' % (
                rivet_path,
                rn.get_plot_name(rivet_radius, rivet_region, rivet_lambda,
                                 rivet_pt_bins[ibin]))
            rivet_hists = [
                qgp.normalise_hist_divide_bin_width(
                    yoda.root.to_root(ent['yoda_dict'][rivet_hist_name]))
                for ent in self.rivet_entries
            ]

            # Create copy of data to go on top of stat unc,
            # but remove vertical error bar so we can see the stat unc
            # Note that you CAN'T set it to 0, otherwise vertical lines connecting
            # bins start being drawn. Instead set it to some super small value.
            unfolded_hist_bin_total_errors_marker_noerror = unfolded_hist_bin_total_errors.Clone(
            )  # clone to avoid restyling the original as well
            for i in range(
                    1,
                    unfolded_hist_bin_total_errors_marker_noerror.GetNbinsX() +
                    1):
                unfolded_hist_bin_total_errors_marker_noerror.SetBinError(
                    i, 1E-100)

            data_entries = [
                Contribution(unfolded_hist_bin_total_errors,
                             **data_total_errors_style),
                Contribution(unfolded_hist_bin_stat_errors,
                             **data_stat_errors_style),
                # do data with black marker to get it on top
                Contribution(unfolded_hist_bin_total_errors_marker_noerror,
                             **data_total_errors_style),
            ]

            # For subplot to ensure only MC errors drawn, not MC+data
            data_no_errors = unfolded_hist_bin_total_errors_marker_noerror.Clone(
            )
            cu.remove_th1_errors(data_no_errors)

            this_mc_style = deepcopy(mc_style)

            rivet_styles = []
            for ind, _ in enumerate(rivet_hists):
                s_dict = self.rivet_entries[ind]['style_dict']
                rivet_styles.append(
                    dict(label=s_dict['label'],
                         line_color=s_dict['color'],
                         line_width=self.line_width,
                         marker_color=s_dict['color'],
                         marker_size=s_dict.get(
                             'marker_size',
                             self.plot_styles['gen_marker_size']),
                         marker_style=s_dict['marker_style'],
                         leg_draw_opt="LEP"
                         if self.plot_styles['gen_marker_size'] > 0 else "LE"))

            # Calculate chi2 between data and MCs if desired
            if do_chi2:
                # print("unfolded_alt_truth bin", ibin)
                ematrix = self.hist_bin_chopper.get_pt_bin_normed_div_bin_width(
                    self.unfolder.total_ematrix_name, **hbc_args)
                # stats are chi2, ndof, p
                mc_stats = calc_chi2_stats(unfolded_hist_bin_total_errors,
                                           mc_gen_hist_bin, ematrix)
                # print(mc_stats)
                # print(alt_mc_stats)
                nbins = sum([
                    1 for i in range(
                        1,
                        unfolded_hist_bin_total_errors.GetNbinsX() + 1)
                    if unfolded_hist_bin_total_errors.GetBinContent(i) != 0
                ])
                # reduced_chi2 = mc_stats[0] / nbins
                # alt_reduced_chi2 = alt_mc_stats[0] / nbins

                n_sig_fig = 2
                chi2_template = "\n#lower[-0.1]{{(#chi^{{2}} / N_{{bins}} = {chi2:g} / {nbins:d})}}"
                this_mc_style['label'] += chi2_template.format(chi2=cu.nsf(
                    mc_stats[0], n_sig_fig),
                                                               nbins=nbins)

                for ind, h in enumerate(rivet_hists):
                    this_stats = calc_chi2_stats(
                        unfolded_hist_bin_total_errors, h, ematrix)
                    rivet_styles[ind]['label'] += chi2_template.format(
                        chi2=cu.nsf(this_stats[0], n_sig_fig), nbins=nbins)

            mc_entries = [
                Contribution(mc_gen_hist_bin,
                             subplot=data_no_errors,
                             **this_mc_style),
            ]

            for h, s_dict in zip(rivet_hists, rivet_styles):
                mc_entries.append(
                    Contribution(h, subplot=data_no_errors, **s_dict))

            entries = [
                # Draw MC
                *mc_entries,
                # Draw data after to put on top of MC
                *data_entries
            ]

            func_name = cu.get_current_func_name()
            if not self.check_entries(entries, "%s bin %d" %
                                      (func_name, ibin)):
                return

            ymin = 0
            if np.any(
                    cu.th1_to_ndarray(unfolded_hist_bin_total_errors)[0] < 0):
                ymin = None  # let it do its thing and auto calc ymin
            max_rel_err = 0.5 if "multiplicity" in self.setup.angle.var.lower(
            ) else -1
            plot = Plot(
                entries,
                ytitle=self.setup.pt_bin_normalised_differential_label,
                title=self.get_pt_bin_title(bin_edge_low, bin_edge_high),
                legend=True,
                xlim=qgp.calc_auto_xlim(
                    entries[2:3],
                    max_rel_err=0.5),  # set x lim to where data is non-0
                ylim=[ymin, None],
                **self.pt_bin_plot_args)

            plot.subplot_title = qgc.SIM_DATA_STR
            self._modify_plot_paper(plot)

            # disable adding objects to legend & drawing - we'll do it manually
            plot.do_legend = False
            plot.legend.SetTextSize(0.03)
            plot.legend.SetY1(0.6)
            plot.legend.SetX1(0.57)
            plot.legend.SetX2(0.93)
            if len(entries) > 4:
                # if lots of entries, try auto-expand
                plot.legend.SetY1(0.6 - (0.02 * (len(entries) - 4)))
            # plot.legend.SetEntrySeparation(0.005)
            subplot_draw_opts = "NOSTACK E1"
            plot.plot("NOSTACK E1", subplot_draw_opts)

            dummy_graphs = qgp.do_fancy_legend(chain(data_entries[:2],
                                                     mc_entries),
                                               plot,
                                               use_splitline=False)

            plot.canvas.cd()
            plot.legend.Draw()

            # Create hists for data with error region for ratio
            # Easiest way to get errors right is to do data (with 0 errors)
            # and divide by data (with errors), as if you had MC = data with 0 error
            data_stat_ratio = data_no_errors.Clone()
            data_stat_ratio.Divide(unfolded_hist_bin_stat_errors)
            data_stat_ratio.SetFillStyle(3245)
            data_stat_ratio.SetFillColor(
                self.plot_styles['unfolded_stat_colour'])
            data_stat_ratio.SetLineWidth(0)
            data_stat_ratio.SetMarkerSize(0)

            data_total_ratio = data_no_errors.Clone()
            data_total_ratio.Divide(unfolded_hist_bin_total_errors)
            data_total_ratio.SetFillStyle(3254)
            data_total_ratio.SetFillColor(
                self.plot_styles['unfolded_total_colour'])
            data_total_ratio.SetLineWidth(0)
            data_total_ratio.SetMarkerSize(0)

            # now draw the data error shaded area
            # this is a bit hacky - basically draw them on the ratio pad,
            # then redraw the existing hists & line to get them ontop
            # note that we use "same" for all - this is to keep the original axes
            # (we may want to rethink this later?)
            plot.subplot_pad.cd()
            draw_opt = "E2 SAME"
            data_stat_ratio.Draw(draw_opt)
            data_total_ratio.Draw(draw_opt)
            plot.subplot_line.Draw()
            plot.subplot_container.Draw("SAME" + subplot_draw_opts)

            # Add subplot legend
            x_left = 0.25
            y_bottom = 0.75
            width = 0.67
            height = 0.15
            plot.subplot_legend = ROOT.TLegend(x_left, y_bottom,
                                               x_left + width,
                                               y_bottom + height)
            plot.subplot_legend.AddEntry(data_total_ratio,
                                         qgc.DATA_TOTAL_UNC_STR, "F")
            plot.subplot_legend.AddEntry(data_stat_ratio,
                                         qgc.DATA_STAT_UNC_STR, "F")
            plot.subplot_legend.SetTextSize(0.085)
            plot.subplot_legend.SetFillStyle(0)
            plot.subplot_legend.SetNColumns(2)
            plot.subplot_legend.Draw()
            plot.canvas.cd()

            stp = self.setup
            fname = f"unfolded_{stp.append}_rivet_bin_{ibin:d}_divBinWidth{stp.paper_str}.{stp.output_fmt}"
            self.save_plot(plot, os.path.join(stp.output_dir, fname))

            # Do version with small x values only
            if do_zoomed:
                if self.setup.angle.var in [
                        "jet_thrust_charged", "jet_width_charged",
                        "jet_thrust", "jet_width"
                ]:
                    # plot.ylim = (1E-5)
                    plot.y_padding_max_log = 50
                    plot.y_padding_min_log = 0.5
                    plot.ylim = None
                    plot.set_logy(do_exponent=False, do_more_labels=False)
                    fname = f"unfolded_{stp.append}_alt_truth_bin_{ibin:d}_divBinWidth_logY.{stp.output_fmt}"
                    self.save_plot(plot, os.path.join(stp.output_dir, fname))

                if self.setup.angle.var in [
                        "jet_LHA_charged", "jet_thrust_charged",
                        "jet_width_charged", "jet_thrust", "jet_width"
                ]:
                    bin_edges = cu.get_bin_edges(mc_gen_hist_bin, 'x')
                    # get the bin edge thats smallest between 0.2, and 5th bin
                    bin_lt_lim = [x for x in bin_edges if x < 0.2][-1]
                    upper_bin = min(bin_edges[5], bin_lt_lim)
                    plot2 = Plot(
                        entries,
                        ytitle=self.setup.pt_bin_normalised_differential_label,
                        title=self.get_pt_bin_title(bin_edge_low,
                                                    bin_edge_high),
                        xlim=(0, upper_bin),
                        **self.pt_bin_plot_args)
                    self._modify_plot(plot2)
                    plot2.subplot_title = "* / Generator"
                    plot2.plot("NOSTACK E1")
                    # plot2.set_logx(do_exponent=False)
                    fname = f"unfolded_{stp.append}_rivet_bin_{ibin:d}_divBinWidth_lowX.{stp.output_fmt}"
                    self.save_plot(plot2, os.path.join(stp.output_dir, fname))