def tvector_to_th1(vector, has_oflow_x=False):
    """Convert numpy ndarray row vector to TH1, with shape (1, nbins)

    Use has_oflow_x to include the under/overflow bins
    """
    nbins_hist = vector.GetNrows()
    if has_oflow_x:
        nbins_hist -= 2

    # need the 0.5 offset to match TUnfold
    h = ROOT.TH1F(cu.get_unique_str(), "", nbins_hist, 0.5, nbins_hist + 0.5)

    x_start = 1
    x_end = nbins_hist

    if has_oflow_x:
        x_start = 0
        x_end = nbins_hist + 1

    for x_ind, ix in enumerate(range(x_start, x_end + 1)):
        h.SetBinContent(ix, vector[x_ind])
        #FIXME how to do errors
    return h
def do_pt_transfer_plot(tdir, plot_dir):
    """Plot ratio between pt bins of the spectrum. Check to make sure xfer factor << drop in pt"""
    plot_dir = os.path.join(plot_dir, tdir.GetName())
    cu.check_dir_exists_create(plot_dir)
    hist_name = "pt_jet_response_binning"
    h = cu.get_from_tfile(tdir, hist_name)
    binning = [
        h.GetXaxis().GetBinLowEdge(bin_ind)
        for bin_ind in range(1,
                             h.GetNbinsX() + 1)
    ]
    hist_factors = ROOT.TH1F(
        "hist_factors" + cu.get_unique_str(),
        ";p_{T}^{Reco} [GeV];Fraction rel to previous bin",
        len(binning) - 1, array('d', binning))
    for bin_ind in range(2, h.GetNbinsX() + 1):
        cont = h.GetBinContent(bin_ind)
        cont_prev = h.GetBinContent(bin_ind - 1)
        if cont == 0 or cont_prev == 0:
            continue
        factor = cont / cont_prev
        hist_factors.SetBinContent(bin_ind, factor)
        hist_factors.SetBinError(bin_ind, 0)

    col_purity = ROOT.kBlack
    conts = [
        Contribution(hist_factors,
                     label="Factor relative to previous bin",
                     line_color=col_purity,
                     marker_color=col_purity),
        # Contribution(hist_purity, label="Purity (gen in right bin)", line_color=col_purity, marker_color=col_purity),
    ]
    xlim = [30, binning[-1]]
    plot = Plot(conts, what='hist', xlim=xlim)
    plot.plot()
    plot.set_logx()
    plot.save(os.path.join(plot_dir, 'pt_migration_factors.%s' % (OUTPUT_FMT)))
Beispiel #3
0
def do_comparison_graph(all_results, binning, output_dirs):
    if isinstance(output_dirs, str):
        output_dirs = [output_dirs]*len(binning)
    for bin_name, odir in zip(binning, output_dirs):
        mg = ROOT.TMultiGraph()
        c = ROOT.TCanvas("cmg"+cu.get_unique_str(), "", 800, 600)
        c.SetTicks(1, 1)
        leg = ROOT.TLegend(0.65, 0.2, 0.92, 0.42)
        colors = [ROOT.kBlack, ROOT.kBlue, ROOT.kRed, ROOT.kOrange+1, ROOT.kGreen+2]

        counter = 0
        for name, result in all_results.items():
            if bin_name not in name:
                continue
            thresholds = [info['threshold'] for k, info in result.items() if 'PFJet40' not in k]
            fully_eff_pt = [info['good_eff_pt'] for k, info in result.items() if 'PFJet40' not in k]
            g = ROOT.TGraph(len(thresholds), array('d', thresholds), array('d', fully_eff_pt))
            g.SetMarkerColor(colors[counter])
            g.SetMarkerStyle(20+counter)
            g.SetLineColor(colors[counter])
            mg.Add(g)
            leg.AddEntry(g, name, "LP")
            counter += 1

        mg.SetTitle(";Trigger threshold [GeV];99% efficiency p_{T} [GeV]")
        mg.Draw("ALP")
        leg.Draw()
        cms_text = ROOT.TPaveText(0.14, 0.9, 0.4, 0.92, "NDC")
        cms_text.AddText("CMS Preliminary %.3f fb^{-1}" % (total_lumi / 1e9))
        cms_text.SetFillStyle(0)
        cms_text.SetBorderSize(0)
        cms_text.SetTextAlign(ROOT.kHAlignLeft + ROOT.kVAlignBottom)
        cms_text.SetTextFont(63)
        cms_text.SetTextSize(18)
        cms_text.Draw()
        c.SaveAs(odir+"/comparingTriggers_%s.%s" % (bin_name.replace(" ", "_"), OUTPUT_FMT))
def do_var_vs_pt_plot(histname, input_filename, output_filename):
    ROOT.gStyle.SetPalette(palette_2D)
    tf = cu.open_root_file(input_filename)
    h3d = cu.get_from_tfile(tf, histname)
    if h3d.GetEntries() == 0:
        return
    h2d = h3d.Project3D("zy")

    xlabel = h2d.GetXaxis().GetTitle()
    ylabel = h2d.GetYaxis().GetTitle()
    ylabel = get_var_str(histname)

    # find largest var value (ie row) that has a filled bin
    h2d_ndarray = cu.th2_to_ndarray(h2d)[0]

    xbins = np.array(cu.get_bin_edges(h2d, 'x'))
    ybins = np.array(cu.get_bin_edges(h2d, 'y'))

    # remove dodgy bins with 0 width cos I was an idiot and duplicated some bins
    n_deleted = 0
    # weight bin
    # xax = h2d.GetXaxis()
    # for ix in range(1, h2d.GetNbinsX()+1):
    #     if xax.GetBinWidth(ix) == 0:
    #         h2d_ndarray = np.delete(h2d_ndarray, ix-1-n_deleted, axis=1)
    #         xbins = np.delete(xbins, ix-1-n_deleted, axis=0)
    #         n_deleted += 1
    #         print("Deleting bin", ix)

    # pt bin
    # n_deleted = 0
    # yax = h2d.GetYaxis()
    # for iy in range(1, h2d.GetNbinsY()+1):
    #     if yax.GetBinWidth(iy) == 0:
    #         h2d_ndarray = np.delete(h2d_ndarray, iy-1-n_deleted, axis=0)
    #         ybins = np.delete(ybins, iy-1-n_deleted, axis=0)
    #         n_deleted += 1
    #         print("Deleting bin", iy)

    # nonzero returns (row #s)(col #s) of non-zero elements
    # we only want the largest row #
    max_filled_row_ind = int(np.nonzero(h2d_ndarray)[0].max())
    h2d = cu.ndarray_to_th2(h2d_ndarray, binsx=xbins, binsy=ybins)

    if "unweighted" in histname:
        h2d.SetTitle("Unweighted;%s;%s" % (xlabel, ylabel))
    else:
        h2d.SetTitle("Weighted;%s;%s" % (xlabel, ylabel))

    h2d.GetYaxis().SetRange(1, max_filled_row_ind+2)  # +1 as ROOT 1-indexed, +1 for padding
    h2d.GetYaxis().SetTitle(get_var_str(histname))

    xmin = 15 if "pt_genjet_vs" in histname else 30
    xmax = 300

    canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
    canv.SetTicks(1, 1)
    canv.SetLeftMargin(0.12)
    canv.SetRightMargin(0.15)
    # canv.SetLogz()
    # canv.SetLogy()
    h2d_copy = h2d.Clone()
    # h2d_copy.Scale(1, "width")
    h2d_copy.Draw("COLZ")
    canv.SetLogx()
    h2d_copy.GetXaxis().SetMoreLogLabels()
    canv.SaveAs(output_filename)

    zoom_ymin, zoom_ymax = 0.1, 5

    h2d_copy.SetAxisRange(zoom_ymin, zoom_ymax,"Y")
    h2d_copy.SetAxisRange(xmin, xmax, "X")
    canv.SaveAs(output_filename.replace(".pdf", "_zoomY.pdf"))
    
    canv.SetLogz()
    canv.SaveAs(output_filename.replace(".pdf", "_zoomY_logZ.pdf"))

    canv.SetLogz(False)
    # h2d.Scale(1, "width")
    h2d_normed = cu.make_normalised_TH2(h2d, norm_axis='x', recolour=True)
    h2d_normed.Draw("COLZ")
    h2d_normed.GetXaxis().SetMoreLogLabels()
    # h2d_normed.SetMinimum(1E-5)
    h2d_normed.SetAxisRange(xmin, xmax, "X")
    canv.SaveAs(output_filename.replace(".pdf", "_normX.pdf"))
    
    h2d_normed.SetAxisRange(zoom_ymin, zoom_ymax,"Y")
    canv.SaveAs(output_filename.replace(".pdf", "_normX_zoomY.pdf"))

    # Do cumulative plot per column (ie fraction of events passing cut < y)
    h2d_ndarray_cumsum = h2d_ndarray.cumsum(axis=0)
    nonzero_mask = h2d_ndarray_cumsum[-1] > 0
    h2d_ndarray_cumsum[:, nonzero_mask] /= h2d_ndarray_cumsum[-1][nonzero_mask] # scale so total is 1
    
    h2d_cumsum = cu.ndarray_to_th2(h2d_ndarray_cumsum, binsx=xbins, binsy=ybins)
    # Get max row ind
    max_filled_row_ind = int(h2d_ndarray_cumsum.argmax(axis=0).max())
    h2d_cumsum.GetYaxis().SetRange(1, max_filled_row_ind+1)  # +1 as ROOT 1-indexed

    # ROOT.gStyle.SetPalette(ROOT.kBird)
    ylabel = "Fraction of events with " + ylabel + " < y"
    if "unweighted" in histname:
        h2d_cumsum.SetTitle("Unweighted;%s;%s" % (xlabel, ylabel))
    else:
        h2d_cumsum.SetTitle("Weighted;%s;%s" % (xlabel, ylabel))
    canv.Clear()
    canv.SetLogz(False)

    h2d_cumsum.SetContour(20)
    h2d_cumsum.Draw("CONT1Z")
    h2d_cumsum.SetAxisRange(xmin, xmax, "X")
    canv.SetLogx()
    h2d_cumsum.GetXaxis().SetMoreLogLabels()
    canv.SaveAs(output_filename.replace(".pdf", "_cumulY.pdf"))

    h2d_cumsum.SetAxisRange(zoom_ymin, zoom_ymax,"Y")
    canv.SaveAs(output_filename.replace(".pdf", "_cumulY_zoomY.pdf"))
    canv.Clear()

    h2d_normed.Draw("COL")
    h2d_cumsum.Draw("CONT1Z SAME")
    h2d_cumsum.SetAxisRange(xmin, xmax, "X")
    canv.SetLogx()
    h2d_cumsum.GetXaxis().SetMoreLogLabels()
    canv.SaveAs(output_filename.replace(".pdf", "_cumulY_normX.pdf"))

    h2d_cumsum.SetAxisRange(zoom_ymin, zoom_ymax,"Y")
    canv.SaveAs(output_filename.replace(".pdf", "_cumulY_normX_zoomY.pdf"))

    tf.Close()
def do_cut_roc_per_pt(histname, input_filename, output_filename):
    """Plot fractional # unweighted vs fraction # weighted, for different cuts
    Not a true ROC, but kinda like one
    """
    ROOT.gStyle.SetPalette(palette_1D)
    tf = cu.open_root_file(input_filename)
    h3d = cu.get_from_tfile(tf, histname)
    h3d_unweighted = cu.get_from_tfile(tf, histname+"_unweighted")
    if h3d.GetEntries() == 0:
        return

    canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
    canv.SetTicks(1, 1)
    canv.SetLeftMargin(0.12)
    canv.SetRightMargin(0.12)
    # canv.SetLogz()
    h2d = h3d.Project3D("zy") # var vs pt
    h2d_unweighted = h3d_unweighted.Project3D("zy") # var vs pt

    var_name = os.path.basename(histname).replace("weight_vs_pt_vs_", "").replace("weight_vs_pt_genjet_vs_", "")

    for ibin in range(3, h2d.GetNbinsX()+1):  # iterate over pt bins
        if h2d.Integral(ibin, ibin+1, 0, -1) == 0:
            # data.append(None)
            continue

        pt_low = h3d.GetYaxis().GetBinLowEdge(ibin)
        pt_high = h3d.GetYaxis().GetBinLowEdge(ibin+1)

        data = []
        data_unweighted = []
        # Do integral, error for increasingly looser cuts
        # find maximum in this pt bin
        # yes I probably should collapse to a 1D hist and use GetMaximumBin
        max_val, max_bin = 0, 0
        for icut in range(1, h2d.GetNbinsY()+1):
            val =  h2d.GetBinContent(ibin, icut)
            if val > max_val:
                max_val = val
                max_bin = icut

        for icut in range(max_bin + 5, h2d.GetNbinsY()+2, 2):
        # for icut in range(2, h2d.GetNbinsY()+2):
            err = array('d', [0])
            count = h2d.IntegralAndError(ibin, ibin+1, 1, icut-1, err)
            if count == 0:
                continue
            data.append([count, err[0], h2d.GetYaxis().GetBinLowEdge(icut)])

            err = array('d', [0])
            count = h2d_unweighted.IntegralAndError(ibin, ibin+1, 1, icut-1, err)
            data_unweighted.append([count, err[0], h2d.GetYaxis().GetBinLowEdge(icut)])

        cuts = np.array([d[2] for d in data][1:])
        # cuts = np.array([d[2] for d in data])

        weighted_fractions = np.array([abs(d[0]-dd[0]) / dd[0] for d, dd in zip(data[:-1], data[1:])])
        unweighted_fractions = np.array([abs(d[0]-dd[0]) / dd[0] for d, dd in zip(data_unweighted[:-1], data_unweighted[1:])])

        non_zero_mask = (unweighted_fractions>0) & (weighted_fractions>0)
        non_zero_weighted = weighted_fractions[non_zero_mask]
        weight_min_pow = math.floor(math.log10(min(non_zero_weighted))) if len(non_zero_weighted) > 0 else -10
        weight_max_pow = math.floor(math.log10(max(non_zero_weighted))) if len(non_zero_weighted) > 0 else 0
        assert(weight_max_pow>=weight_min_pow)

        non_zero_unweighted = unweighted_fractions[non_zero_mask]
        unweight_min_pow = math.floor(math.log10(min(non_zero_unweighted))) if len(non_zero_unweighted) > 0 else -10
        unweight_max_pow = math.floor(math.log10(max(non_zero_unweighted))) if len(non_zero_unweighted) > 0 else 0
        assert(unweight_max_pow>=unweight_min_pow)

        mask = unweighted_fractions < 10**(unweight_min_pow+1)  # last decade of unweighted drops
        mask &= weighted_fractions > 10**(weight_max_pow-1)  # largest decades of weighted drops

        if np.sum(mask) == 0:
            continue

        # weighted_fractions = np.array([d[0] / data[-1][0] for d in data])
        # unweighted_fractions = np.array([d[0] / data_unweighted[-1][0] for d in data_unweighted])

        unweighted_useful = unweighted_fractions[mask & non_zero_mask]
        weighted_useful = weighted_fractions[mask & non_zero_mask]
        if "pt_jet_genHT_ratio" in histname and pt_low == 800:
            print("weight_min_pow:", weight_min_pow)
            print("weight_max_pow:", weight_max_pow)
            print("unweight_min_pow:", unweight_min_pow)
            print("unweight_max_pow:", unweight_max_pow)
            print("unweight_max_pow:", unweight_max_pow)
            print("weighted_useful:", weighted_useful)
            print("unweighted_useful:", unweighted_useful)

        gr_count = ROOT.TGraph(len(unweighted_useful), unweighted_useful, weighted_useful)
        gr_count.SetMarkerColor(ROOT.kRed)
        gr_count.SetMarkerSize(0)
        gr_count.SetMarkerStyle(21)
        gr_count.SetLineColor(ROOT.kRed)
        gr_count.SetTitle("%s, %g < p_{T} < %g GeV;Relative unweighted count;Relative weighted count" % (get_var_str(histname), pt_low, pt_high))
        gr_count.SetTitle("%s, %g < p_{T} < %g GeV;Unweighted fractional drop;Weighted fractional drop" % (get_var_str(histname), pt_low, pt_high))


        # add annotations of cuts
        latexs = []
        for i, cut in enumerate(cuts[mask * non_zero_mask]):
            latex = ROOT.TLatex(gr_count.GetX()[i], gr_count.GetY()[i], " < %.2f" % cut)
            latex.SetTextSize(0.02)
            latex.SetTextColor(ROOT.kBlue)
            gr_count.GetListOfFunctions().Add(latex)
            latexs.append(latex)

        # canv.SetLogx(False)
        # canv.SetLogy(False)

        # ROOT.TGaxis.SetMaxDigits(2)

        # gr_count.Draw("ALP")

        # ROOT.TGaxis.SetMaxDigits(2)
        # unweighted_min = 0.9999

        # # Calculate differences between points
        # unweighted_diffs = unweighted_fractions[1:] - unweighted_fractions[:-1]
        # weighted_diffs = weighted_fractions[1:] - weighted_fractions[:-1]
        # big_diff_inds = []
        # for ind, (u, w) in enumerate(zip(unweighted_diffs, weighted_diffs)):
        #     # look for big diff in weighted frac, small diff in unweighted,
        #     # with a limit on the minimum size of unweighted frac
        #     # (only trying to remove a few events)
        #     if u > 0 and w / u > 100 and u < 0.005 and unweighted_fractions[ind] > unweighted_min:
        #         big_diff_inds.append(ind)

        # if "pt_jet_genHT_ratio" in histname and pt_low == 186:
        #     for u, w in zip(unweighted_diffs, weighted_diffs):
        #         print(u, w)
        #     print(big_diff_inds)

        # make graph of big diff points, add annotations of cuts
        # if len(big_diff_inds) > 0:
        #     gr_big_diffs = ROOT.TGraph(len(big_diff_inds), array('d', [unweighted_fractions[i+1] for i in big_diff_inds]), array('d', [weighted_fractions[i+1] for i in big_diff_inds]))
        #     gr_big_diffs.SetLineWidth(0)
        #     gr_big_diffs.SetMarkerColor(ROOT.kBlue)
        #     gr_big_diffs.SetMarkerStyle(25)
        #     latexs = []
        #     for i, ind in enumerate(big_diff_inds[:]):
        #         latex = ROOT.TLatex(gr_big_diffs.GetX()[i], gr_big_diffs.GetY()[i], " < %.2f" % cuts[ind+1])
        #         latex.SetTextSize(0.02)
        #         latex.SetTextColor(ROOT.kBlue)
        #         gr_big_diffs.GetListOfFunctions().Add(latex)
        #         latexs.append(latex)
        #     gr_big_diffs.Draw("*")

        # gr_count.GetXaxis().SetLimits(unweighted_min, 1)

        # find corresponding value for weighted to set axis range
        # weighted_min = 0
        # for ind, u in enumerate(unweighted_fractions):
        #     if u >= unweighted_min:
        #         weighted_min = weighted_fractions[ind-1]
        #         if ind == len(unweighted_fractions) - 1:
        #             weighted_min = 0
        #         break
        # gr_count.GetHistogram().SetMinimum(weighted_min*1.1 - 0.1)
        # gr_count.GetHistogram().SetMaximum(1)
        # canv.SaveAs(output_filename.replace(".pdf", "_count_pt%gto%g.pdf" % (pt_low, pt_high)))

        # do a version zoomed out
        canv.Clear()
        gr_count.SetMarkerSize(0.5)
        gr_count.Draw("AP")

        # unweighted_min = 0.
        # gr_count.GetXaxis().SetLimits(unweighted_min, 1)
        # weighted_min = 0
        # for ind, u in enumerate(unweighted_fractions):
        #     if u >= unweighted_min:
        #         weighted_min = weighted_fractions[ind-1]
        #         if ind == len(unweighted_fractions) - 1:
        #             weighted_min = 0
        #         break
        # gr_count.GetHistogram().SetMinimum(weighted_min*1.1 - 0.1)

        gr_count.GetXaxis().SetMoreLogLabels()
        gr_count.GetYaxis().SetMoreLogLabels()

        weight_min_pow = math.floor(math.log10(min(weighted_useful))) if len(weighted_useful) > 0 else -10
        weight_max_pow = math.floor(math.log10(max(weighted_useful))) if len(weighted_useful) > 0 else 0

        unweight_min_pow = math.floor(math.log10(min(unweighted_useful))) if len(unweighted_useful) > 0 else -10
        unweight_max_pow = math.floor(math.log10(max(unweighted_useful))) if len(unweighted_useful) > 0 else 0
        gr_count.GetHistogram().SetMinimum(10**weight_min_pow)
        gr_count.GetHistogram().SetMaximum(10**(weight_max_pow+1))
        gr_count.GetXaxis().SetLimits(10**unweight_min_pow, 10**(unweight_max_pow+1))
        canv.SetLogy()
        canv.SetLogx()
        canv.SaveAs(output_filename.replace(".pdf", "_count_pt%gto%g_all.pdf" % (pt_low, pt_high)))


    tf.Close()
def do_cut_scan_per_pt(histname, input_filename, output_filename):
    ROOT.gStyle.SetPalette(palette_1D)
    tf = cu.open_root_file(input_filename)
    h3d = cu.get_from_tfile(tf, histname)
    h3d_unweighted = cu.get_from_tfile(tf, histname+"_unweighted")
    if h3d.GetEntries() == 0:
        return

    canv = ROOT.TCanvas(cu.get_unique_str(), "", 800, 600)
    canv.SetTicks(1, 1)
    canv.SetLeftMargin(0.12)
    canv.SetRightMargin(0.12)
    # canv.SetLogz()
    h2d = h3d.Project3D("zy") # var vs pt
    h2d_unweighted = h3d_unweighted.Project3D("zy") # var vs pt

    var_name = os.path.basename(histname).replace("weight_vs_pt_vs_", "").replace("weight_vs_pt_genjet_vs_", "")

    for ibin in range(3, h2d.GetNbinsX()+1):  # iterate over pt bins
        if h2d.Integral(ibin, ibin+1, 0, -1) == 0:
            # data.append(None)
            continue

        pt_low = h3d.GetYaxis().GetBinLowEdge(ibin)
        pt_high = h3d.GetYaxis().GetBinLowEdge(ibin+1)

        data = []
        data_unweighted = []
        # Do integral, error for increasingly looser cuts
        # find maximum in this pt bin
        # yes I probably should collapse to a 1D hist and use GetMaximumBin
        max_val, max_bin = 0, 0
        for icut in range(1, h2d.GetNbinsY()+1):
            val =  h2d.GetBinContent(ibin, icut)
            if val > max_val:
                max_val = val
                max_bin = icut

        for icut in range(max_bin + 5, h2d.GetNbinsY()+2):
            err = array('d', [0])
            count = h2d.IntegralAndError(ibin, ibin+1, 1, icut-1, err)
            if count == 0:
                continue
            data.append([count, err[0], h2d.GetYaxis().GetBinLowEdge(icut)])

            err = array('d', [0])
            count = h2d_unweighted.IntegralAndError(ibin, ibin+1, 1, icut, err)
            data_unweighted.append([count, err[0], h2d.GetYaxis().GetBinLowEdge(icut)])

        # Plot count, rel error vs cut value
        cuts = [d[2] for d in data]
        gr_count = ROOT.TGraph(len(data), array('d', cuts), array('d', [d[0] / data[-1][0] for d in data]))

        gr_count.SetMarkerColor(ROOT.kRed)
        gr_count.SetMarkerStyle(22)
        gr_count.SetLineColor(ROOT.kRed)
        gr_count.SetTitle("%g < p_{T} < %g GeV;%s cut (<);Count (relative to loosest cut)" % (pt_low, pt_high, get_var_str(histname)))

        gr_count_unweighted = ROOT.TGraph(len(data), array('d', cuts), array('d', [d[0] / data_unweighted[-1][0] for d in data_unweighted]))
        gr_count_unweighted.SetMarkerColor(ROOT.kBlack)
        gr_count_unweighted.SetMarkerStyle(23)
        gr_count_unweighted.SetLineColor(ROOT.kBlack)
        gr_count_unweighted.SetTitle("%g < p_{T} < %g GeV;%s cut (<);Count (relative to loosest cut)" % (pt_low, pt_high, get_var_str(histname)))

        leg = ROOT.TLegend(0.7, 0.5, 0.85, 0.65)
        leg.AddEntry(gr_count, "Weighted", "LP")
        leg.AddEntry(gr_count_unweighted, "Unweighted", "LP")

        # gr_rel_err = ROOT.TGraph(len(data), array('d', cuts), array('d', [(d[1] / d[0]) if d[0] != 0 else 0 for d in data ]))
        # gr_rel_err.SetMarkerColor(ROOT.kRed)
        # gr_rel_err.SetMarkerStyle(22)
        # gr_rel_err.SetLineColor(ROOT.kRed)
        # gr_rel_err.SetTitle("%g < p_{T} < %g GeV;%s cut (<);Rel. error" % (pt_low, pt_high, var_name))

        canv.SetLogy(False)

        gr_count.Draw("ALP")
        gr_count_unweighted.Draw("LP")
        gr_count.Draw("LP")
        leg.Draw()
        canv.SaveAs(output_filename.replace(".pdf", "_count_pt%gto%g.pdf" % (pt_low, pt_high)))

        # canv.Clear()
        # gr_rel_err.Draw("ALP")
        # canv.SetLogy()
        # gr_rel_err.GetYaxis().SetMoreLogLabels()
        # canv.SaveAs(output_filename.replace(".pdf", "_rel_err_pt%gto%g.pdf" % (pt_low, pt_high)))


    tf.Close()
def plot_jet_pt_response_matrix(h2d, h2d_renorm_x, h2d_renorm_y, title, plot_dir):
    """Plot 2D response matrix, absolute, and normed by x & y axes"""
    canv = ROOT.TCanvas("c"+cu.get_unique_str(), "", 700, 600)
    canv.SetTicks(1, 1)
    canv.SetLogx()
    canv.SetLogy()
    pad = ROOT.gPad
    pad.SetBottomMargin(0.12)
    pad.SetLeftMargin(0.13)
    pad.SetRightMargin(0.19)

    def _setup_map(hist_2d):
        xax = hist_2d.GetXaxis()
        xax.SetMoreLogLabels()
        xax.SetNoExponent()
        yax = hist_2d.GetYaxis()
        yax.SetMoreLogLabels()
        yax.SetNoExponent()
        xtitle_offset = 1.4
        ytitle_offset = xtitle_offset * 1.2
        ztitle_offset = xtitle_offset
        hist_2d.SetTitleOffset(xtitle_offset, 'X')
        hist_2d.SetTitleOffset(ytitle_offset, 'Y')
        hist_2d.SetTitleOffset(ztitle_offset, 'Z')

    _setup_map(h2d)
    h2d.SetMinimum(1E-3)
    var_label = 'p_{T}^{jet} [GeV]'
    title = "%s;%s (GEN);%s (RECO);N" % (title, var_label, var_label)
    h2d.SetTitle(title)
    h2d.Draw("COLZ")
    old_font_size = ROOT.gStyle.GetTitleFontSize()
    output_filename = os.path.join(plot_dir, "jet_pt.%s" % (OUTPUT_FMT))
    if not os.path.isdir(plot_dir):
        os.makedirs(plot_dir)
    canv.SaveAs(output_filename)

    canv.SetLogz()
    output_filename = os.path.join(plot_dir, "jet_pt_logZ.%s" % (OUTPUT_FMT))
    canv.SaveAs(output_filename)

    # Plot 2D map, renormalized by row
    canv.SetLogz(0)
    marker_size = 0.8
    _setup_map(h2d_renorm_y)
    h2d_renorm_y.SetTitle(title)
    h2d_renorm_y.SetMarkerSize(marker_size)
    h2d_renorm_y.SetMaximum(1)
    h2d_renorm_y.SetZTitle("P(GEN bin | RECO bin)")
    draw_opt = "COLZ"
    plot_migrations = True
    if plot_migrations:
        draw_opt += " TEXT45"
    h2d_renorm_y.Draw(draw_opt)
    canv.SaveAs(os.path.join(plot_dir, "jet_pt_renormY_linZ.%s" % (OUTPUT_FMT)))

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

    # Plot 2D map, renormalized by column
    canv.Clear()
    canv.SetLogz(0)
    _setup_map(h2d_renorm_x)
    h2d_renorm_x.SetTitle(title)
    h2d_renorm_x.SetMarkerSize(marker_size)
    h2d_renorm_x.SetMaximum(1)
    h2d_renorm_x.SetZTitle("P(RECO bin | GEN bin)")
    h2d_renorm_x.Draw(draw_opt)
    canv.SaveAs(os.path.join(plot_dir, "jet_pt_renormX_linZ.%s" % (OUTPUT_FMT)))

    canv.SetLogz()
    h2d_renorm_x.SetMinimum(1E-3)
    canv.SaveAs(os.path.join(plot_dir, "jet_pt_renormX_logZ.%s" % (OUTPUT_FMT)))

    ROOT.gStyle.SetTitleFontSize(old_font_size)
Beispiel #8
0
def make_plots(h2d, var_dict, plot_dir, append="", plot_migrations=True):
    """Plot a 2D hist, with copies renormalised by row and by column.
    Also optionally plot migrations as 1D plot.
    """
    canv = ROOT.TCanvas("c" + cu.get_unique_str(), "", 700, 600)
    canv.SetTicks(1, 1)
    if var_dict.get("log", False):
        canv.SetLogx()
        canv.SetLogy()
    pad = ROOT.gPad
    pad.SetBottomMargin(0.12)
    pad.SetLeftMargin(0.13)
    pad.SetRightMargin(0.12)
    xtitle_offset = 1.4
    ytitle_offset = xtitle_offset * 1.1
    h2d.SetTitleOffset(xtitle_offset, 'X')
    h2d.SetTitleOffset(ytitle_offset, 'Y')
    h2d.SetMinimum(1E-3)
    if var_dict.get('log', False):
        h2d.GetXaxis().SetLimits(1, 150)
        h2d.GetYaxis().SetLimits(1, 150)
    if "title" in var_dict:
        h2d.SetTitle(var_dict['title'])
    h2d.Draw("COLZ")
    output_filename = os.path.join(
        plot_dir, var_dict['name'] + "_%s.%s" % (append, OUTPUT_FMT))
    output_dir = os.path.dirname(output_filename)
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)
    canv.SaveAs(output_filename)

    canv.SetLogz()
    output_filename = os.path.join(
        plot_dir, var_dict['name'] + "_%s_logZ.%s" % (append, OUTPUT_FMT))
    canv.SaveAs(output_filename)

    # renorm by row
    canv.SetLogz(0)
    h2d_renorm_y = cu.make_normalised_TH2(h2d,
                                          'Y',
                                          recolour=False,
                                          do_errors=False)
    marker_size = 0.8
    h2d_renorm_y.SetMarkerSize(marker_size)
    h2d_renorm_y.SetMaximum(1)
    draw_opt = "COLZ"
    if plot_migrations:
        draw_opt += " TEXT45"
    h2d_renorm_y.SetMinimum(1E-3)
    h2d_renorm_y.Draw(draw_opt)
    xtitle_offset = 1.5
    h2d_renorm_y.SetTitleOffset(xtitle_offset, 'X')

    yax = h2d_renorm_y.GetYaxis()
    h2d_renorm_y.SetTitleOffset(ytitle_offset, 'Y')
    canv.Update()

    canv.SaveAs(
        os.path.join(
            plot_dir,
            "%s_%s_renormY_linZ.%s" % (var_dict['name'], append, OUTPUT_FMT)))
    canv.SetLogz()
    h2d_renorm_y.SetMaximum(1)
    h2d_renorm_y.SetMinimum(1E-3)
    canv.SaveAs(
        os.path.join(
            plot_dir,
            "%s_%s_renormY_logZ.%s" % (var_dict['name'], append, OUTPUT_FMT)))

    # renorm by column
    canv.Clear()
    canv.SetLogz(0)
    h2d_renorm_x = cu.make_normalised_TH2(h2d,
                                          'X',
                                          recolour=False,
                                          do_errors=False)
    h2d_renorm_x.SetMarkerSize(marker_size)
    h2d_renorm_x.SetMaximum(1)
    h2d_renorm_x.SetMinimum(1E-3)
    h2d_renorm_x.Draw(draw_opt)

    h2d_renorm_x.SetTitleOffset(xtitle_offset, 'X')

    yax = h2d_renorm_x.GetYaxis()
    h2d_renorm_x.SetTitleOffset(ytitle_offset, 'Y')
    yax.SetMoreLogLabels()
    canv.Update()
    canv.SaveAs(
        os.path.join(
            plot_dir,
            "%s_%s_renormX_linZ.%s" % (var_dict['name'], append, OUTPUT_FMT)))
    canv.SetLogz()
    h2d_renorm_x.SetMaximum(1)
    h2d_renorm_x.SetMinimum(1E-3)
    canv.SaveAs(
        os.path.join(
            plot_dir,
            "%s_%s_renormX_logZ.%s" % (var_dict['name'], append, OUTPUT_FMT)))

    # Plot migrations
    if plot_migrations:
        output_filename = os.path.join(
            plot_dir,
            "%s_migration_summary.%s" % (var_dict['name'], OUTPUT_FMT))
        qgg.make_migration_summary_plot(h2d_renorm_x, h2d_renorm_y,
                                        var_dict['var_label'], output_filename)
def do_1D_plot(hists, output_filename, components_styles_dicts=None,
               draw_opts="NOSTACK HISTE", do_ratio=True, logx=False, logy=False,
               normalise_hists=True, title=""):

    if (len(hists) != len(components_styles_dicts)):
        raise RuntimeError("# hists != # components_styles_dicts (%d vs %d)" % (len(hists), len(components_styles_dicts)))

    hists = [h.Clone(cu.get_unique_str()) for h in hists]
    contributions = [Contribution(hist, 
                                  normalise_hist=normalise_hists, 
                                  label=csd.get('label', 'x'), 
                                  **csd.get('style', {}))
                     for hist, csd in zip(hists, components_styles_dicts)]

    if len(contributions) == 0:
        return

    # Ignore if all empty objs
    total_entries = sum(c.obj.GetEntries() for c in contributions)
    if total_entries == 0:
        print("WARNING: all plots have 0 entries")
        return

    min_val = min([h.GetMinimum(0) for h in hists])
    max_val = max([h.GetMaximum() for h in hists])
    # print("Auto y limits:", min_val, max_val)
    if logy:
        ylim = [0.5*min_val, 50*max_val]
    else:
        # ylim = [0.5*min_val, 1.5*max_val]
        ylim = [0, 1.5*max_val]

    # Auto calc x limits to avoid lots of empty bins
    high_bin = max([find_largest_filled_bin(h)[0] for h in hists])
    low_bin = min([find_first_filled_bin(h)[0] for h in hists])
    xlim = [hists[0].GetBinLowEdge(low_bin-1), hists[0].GetBinLowEdge(high_bin+2)]

    subplot_title = "* / %s" % contributions[0].label
    if len(contributions[0].label) > 10:
        # need padding to centralise it
        padding = ' ' * int(len(contributions[0].label)/2)
        subplot_title = "#splitline{%s* /%s}{%s}" % (padding, padding, contributions[0].label)

    p = Plot(contributions, what='hist',
             ytitle="#DeltaN/N" if normalise_hists else "N",
             title=title,
             xlim=xlim,
             ylim=ylim,
             subplot_type="ratio" if do_ratio else None,
             subplot_title=subplot_title,
             subplot=contributions[0],
             # subplot_limits=(0.5, 1.5),
             # subplot_limits=(0, 2) if logy else (0.5, 1.5),
             subplot_limits=(0, 2.5) if logy else (0.5, 1.5),
             )
    # p.legend.SetX1(0.55)
    # # p.legend.SetX2(0.95)
    # p.legend.SetY1(0.7)
    # p.legend.SetY2(0.85)
    p.legend.SetX1(0.5)
    p.legend.SetX2(0.97)
    if len(contributions) > 4:
        p.legend.SetY1(0.6)
    else:
        p.legend.SetY1(0.7)
    p.legend.SetY2(0.9)
    p.plot(draw_opts)

    if logy:
        p.set_logy(do_more_labels=False)
    if logx:
        p.set_logx(do_more_labels=False)

    # p.save(os.path.join(output_dir, obj_name+".%s" % (OUTPUT_FMT)))
    p.save(output_filename)
def do_response_plot(tdir,
                     plot_dir,
                     var_name,
                     xlabel,
                     log_var=False,
                     rebinx=1,
                     rebiny=1,
                     do_migration_summary_plots=True,
                     do_resolution_plots=True,
                     save_response_hists=False):
    """Do 2D plots of genjet pt vs recojet pt"""
    h2d_orig = cu.get_from_tfile(tdir, var_name)
    h2d = h2d_orig.Clone(cu.get_unique_str())
    h2d.RebinX(rebinx)
    h2d.RebinY(rebiny)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # compare RMS and quantile results
        conts = [
            Contribution(
                res_rms,
                label="#sqrt{RMS} #pm #frac{#sqrt{#delta RMS}}{#LT %s #GT}" %
                (xlabel),
                line_color=ROOT.kRed,
                marker_color=ROOT.kRed),
            Contribution(res_quantiles,
                         label="68% quantile",
                         line_color=ROOT.kBlue,
                         marker_color=ROOT.kBlue)
        ]
        ylabel = "#frac{#sigma(RECO/GEN)}{GEN}" if "_rel_" in var_name else "#frac{#sigma(RECO)}{GEN}"
        res_plot = Plot(conts,
                        what='graph',
                        xtitle=xlabel,
                        ytitle=ylabel,
                        legend=True,
                        ylim=[0, 3])
        res_plot.legend.SetX1(0.5)
        res_plot.legend.SetX2(0.9)
        res_plot.legend.SetY1(0.7)
        res_plot.legend.SetY2(0.85)
        res_plot.plot('ALP')
        res_plot.save(
            os.path.join(
                plot_dir,
                '%s_resolution_rms_vs_quantiles.%s' % (var_name, OUTPUT_FMT)))
def make_plot(entries,
              output_filename,
              plot_kwargs,
              projection_axis='x',
              start_val=None,
              end_val=None,
              is_pdgid_plot=False,
              logy=False):
    """Make a plot from entries. Each one is a projection of a 2D plot.
    
    Parameters
    ----------
    entries : list[dict]
        List of plot entries. Each is represented by a dict
    output_filename : str
        Filename for output plot
    plot_kwargs : dict
        kwargs for Plot constructor
    projection_axis : str, optional
        Axis to use for projection. If None, must be specified in entry.
    start_val : None, optional
        If set, use this to make 1D projection plot. Cuts on X axis. 
        Otherwise should be set per entry.
    end_val : None, optional
        If set, use this to make 1D projection plot. Cuts on X axis. 
        Otherwise should be set per entry.
    is_pdgid_plot : bool, optional
        True if for PDGIDs (sets special size & binning)
    logy : bool, optional
        Description
    
    Raises
    ------
    RuntimeError
        Description
    """
    conts = []
    if not is_pdgid_plot:
        for ent in entries:
            h2d = cu.get_from_tfile(
                ent['file'],
                "ak4pfchsl1/" + ent['histname'] + "_JetEta0to0.783")
            start_val = ent.get('start_val', start_val)
            end_val = ent.get('end_val', end_val)
            if start_val is None or end_val is None:
                raise RuntimeError("Expected start_val and end_val")
            hist = cu.get_projection_plot(
                h2d, start_val, end_val,
                ent.get('projection_axis', projection_axis))
            if hist.GetEntries() == 0:
                ent['used'] = False
                continue
            contrib = Contribution(hist,
                                   label=ent['label'],
                                   line_width=lw,
                                   line_color=ent['colour'],
                                   line_style=ent.get('line_style', 1),
                                   marker_size=ent.get('marker_size', 0),
                                   marker_color=ent['colour'],
                                   marker_style=ent.get('marker_style', 1),
                                   normalise_hist=True,
                                   rebin_hist=ent.get('rebin', None))
            conts.append(contrib)
            ent['used'] = True

    else:
        # For PDGID plots, we want a different canvas aspect ratio, and only to include bins
        # with non-0 contents. We also relabel bins.
        custom_bins = []
        for ent in entries:
            h2d = cu.get_from_tfile(
                ent['file'],
                "ak4pfchsl1/" + ent['histname'] + "_JetEta0to0.783")
            start_val = ent.get('start_val', start_val)
            end_val = ent.get('end_val', end_val)
            if not start_val or not end_val:
                raise RuntimeError("Expected start_val and end_val")
            hist = cu.get_projection_plot(
                h2d, start_val, end_val,
                ent.get('projection_axis', projection_axis))
            ax = hist.GetXaxis()
            bins = dict()
            for i in range(1, hist.GetNbinsX() + 1):
                value = ax.GetBinLowEdge(i)
                cont = hist.GetBinContent(i)
                err = hist.GetBinError(i)
                if cont > 0:
                    bins[value] = [cont, err]
                    # print(custom_bins[-1])

            custom_bins.append(bins)

        nbins = max([len(d) for d in custom_bins])
        first_keys = set(custom_bins[0].keys())
        for cb in custom_bins[1:]:
            first_keys = first_keys.union(set(cb.keys()))
        all_keys = sorted(list(first_keys))
        print(all_keys)

        for cbin, ent in zip(custom_bins, entries):
            h = ROOT.TH1D(cu.get_unique_str(), ";PDGID;N", nbins, 0, nbins)
            for ind, k in enumerate(all_keys, 1):
                content, error = cbin.get(k, [0, 0])
                h.SetBinContent(ind, content)
                h.SetBinError(ind, error)
            ax = h.GetXaxis()
            for i in range(1, nbins + 1):
                # ax.SetBinLabel(i, str(int(all_keys[i-1])))
                pdgid = int(all_keys[i - 1])
                ax.SetBinLabel(i, PDGID_STR.get(pdgid, str(pdgid)))
            h.LabelsOption("v")
            contrib = Contribution(h,
                                   label=ent['label'],
                                   line_width=lw,
                                   line_color=ent['colour'],
                                   line_style=ent.get('line_style', 1),
                                   marker_size=ent.get('marker_size', 0),
                                   marker_color=ent['colour'],
                                   marker_style=ent.get('marker_style', 1),
                                   normalise_hist=True,
                                   rebin_hist=ent.get('rebin', None))
            conts.append(contrib)
            ent['used'] = True

    entries = [e for e in entries if e['used']]
    for ind, ent in enumerate(entries):
        if not ent['used']:
            continue
        if ent.get('subplot_ind', -1) >= 0:
            conts[ind].subplot = conts[ent['subplot_ind']].obj

    plot = Plot(conts,
                what="hist",
                ytitle="p.d.f.",
                has_data=False,
                **plot_kwargs)
    if is_pdgid_plot and conts[0].obj.GetNbinsX() > 10:
        plot.default_canvas_size = (800, 800)
    else:
        plot.default_canvas_size = (450, 600)
    plot.legend.SetX1(0.5)
    plot.legend.SetX2(0.97)
    if len(entries) > 4:
        plot.legend.SetY1(0.7)
        plot.legend.SetNColumns(2)
    else:
        plot.legend.SetY1(0.75)
    plot.legend.SetY2(0.9)
    plot.plot("HISTE NOSTACK")
    if logy:
        plot.set_logy()
    plot.save(output_filename)
def do_1D_plot(hists,
               components_styles_dicts,
               output_filename,
               do_ratio=True,
               logx=False,
               logy=False,
               normalise_hists=True,
               title="",
               xtitle=None,
               mean_rel_error=0.4,
               data_first=True,
               show_integrals=False,
               lumi=cu.get_lumi_str(do_dijet=False, do_zpj=True)):

    if (len(hists) != len(components_styles_dicts)):
        raise RuntimeError("# hists != # components_styles_dicts (%d vs %d)" %
                           (len(hists), len(components_styles_dicts)))

    if len(hists) == 0:
        return

    # Ignore if all empty objs
    total_entries = sum(h.GetEntries() for h in hists)
    if total_entries == 0:
        print("WARNING: all plots have 0 entries")
        return

    do_ratio = (do_ratio and len(hists) > 1)

    entries = []
    components_styles_dicts = deepcopy(components_styles_dicts)
    for h, csd in zip(hists, components_styles_dicts):
        if show_integrals:
            csd['label'] += "\nIntegral = {:.4g}".format(h.Integral())
        entries.append((h.Clone(cu.get_unique_str()), csd))

    # print("Auto y limits:", min_val, max_val)
    ylim = None
    # if not normalise_hists:
    #     min_val, min_bin, max_val, max_bin = cu.get_min_max_bin_contents_multiple_hists(hists)
    #     if logy:
    #         ylim = [0.5*min_val, 50*max_val]
    #     else:
    #         # ylim = [0.5*min_val, 1.5*max_val]
    #         ylim = [0, 1.5*max_val]

    xlim = "auto"  # Auto calc x limits to avoid lots of empty bins

    draw_opt = "NOSTACK HIST E1"
    subplot_title = "Simulation / Data"
    subplot_limits = (0, 2) if logy else (0.5, 1.5)
    # subplot_limits = [0.5, None]
    subplot_limits = None
    qgp.do_comparison_plot(
        entries,
        output_filename,
        # rebin=rebin,
        normalise_hist=normalise_hists,
        draw_opt=draw_opt,
        title=title,
        xtitle=xtitle,
        xlim=xlim,
        ylim=ylim,
        logx=logx,
        logy=logy,
        mean_rel_error=mean_rel_error,
        data_first=data_first,
        subplot_type='ratio' if do_ratio else None,
        subplot_title=subplot_title,
        subplot=entries[0][0] if do_ratio else None,
        subplot_limits=subplot_limits,
        lumi=lumi)
Beispiel #13
0
def generate_2d_canvas(size=(800, 800)):
    canv = ROOT.TCanvas(cu.get_unique_str(), "", *size)
    canv.SetTicks(1, 1)
    canv.SetRightMargin(1.5)
    canv.SetLeftMargin(0.9)
    return canv