def plot_rsp_Vs_ref(check_file, eta_min, eta_max, normX, logZ, oDir, oFormat="pdf"):
    """Plot response (l1/ref) Vs ref pt"""
    app = "_normX" if normX else ""
    hname = "eta_%g_%g/Histograms/h2d_rsp_gen%s" % (eta_min, eta_max, app)
    fwd_bin = abs(eta_min)>2.9
    if cu.exists_in_file(check_file, hname):
        h2d_rsp_ref_orig = cu.get_from_file(check_file, hname)
    else:
        h2d_rsp_ref_orig = cu.get_from_file(check_file, "eta_%g_%g/Histograms/h2d_rsp_gen" % (eta_min, eta_max))
    if normX:
        h2d_rsp_ref_orig = cu.norm_vertical_bins(h2d_rsp_ref_orig, rescale_peaks=True)
    h2d_rsp_ref = h2d_rsp_ref_orig.Rebin2D(2, 1, "hnew")
    c = generate_canvas()
    if logZ:
        c.SetLogz()
        app += "_log"
    h2d_rsp_ref.SetTitle("%s: %g-%g;%s;%s" % (eta_l1_str, eta_min, eta_max, pt_ref_str, rsp_str))
    if normX:
        h2d_rsp_ref.Draw("COL")
    else:
        h2d_rsp_ref.Draw("COLZ")
    h2d_rsp_ref.SetAxisRange(rsp_min, rsp_max, 'Y')
    if fwd_bin:
        h2d_rsp_ref.SetAxisRange(0, 254, 'X')
    line = ROOT.TLine(0, 1, 1022, 1)
    line.SetLineStyle(2)
    line.SetLineWidth(2)
    line.Draw()
    c.SaveAs("%s/h2d_rsp_ref_%g_%g%s.%s" % (oDir, eta_min, eta_max, app, oFormat))
예제 #2
0
def get_functions_graphs_params_rootfile(root_filename):
    """Get function parameters from ROOT file

    Gets object based on name in runCalibration.py

    Parameters
    ----------
    root_filename : str
        Name of ROOT file to get things from

    Returns
    -------
    all_fits : list[TF1]
        Collection of TF1 objects, one per line of file ( = 1 eta bin)
    all_fit_params : list[list[float]]
        Collection of fit parameters, one per line of file ( = 1 eta bin)
    all_graphs : list[TGraphErrors]
        Colleciton of correction graphs, one per eta bin
    """
    print 'Reading functions from ROOT file'
    in_file = cu.open_root_file(root_filename)
    all_fit_params = []
    all_fits = []
    all_graphs = []
    # Get all the fit functions from file and their corresponding graphs
    etaBins = binning.eta_bins
    for i, (eta_min, eta_max) in enumerate(izip(etaBins[:-1], etaBins[1:])):
        print "Eta bin:", eta_min, "-", eta_max

        # get the fitted TF1
        try:
            fit_func = cu.get_from_file(in_file, "fitfcneta_%g_%g" % (eta_min, eta_max))
            fit_params = [fit_func.GetParameter(par) for par in range(fit_func.GetNumberFreeParameters())]
            print "Fit fn evaluated at 5 GeV:", fit_func.Eval(5)
        except IOError:
            print "No fit func"
            fit_func = None
            fit_params = []
        all_fits.append(fit_func)
        all_fit_params.append(fit_params)
        # print "Fit parameters:", fit_params

        # get the corresponding fit graph
        fit_graph = cu.get_from_file(in_file, generate_eta_graph_name(eta_min, eta_max))
        all_graphs.append(fit_graph)

    in_file.Close()
    return all_fits, all_fit_params, all_graphs
def plot_res_all_pt(res_file, eta_min, eta_max, oDir, oFormat="pdf"):
    """Plot a graph of resolution as a function of L1 eta."""

    c = generate_canvas()

    # binned by ref pt
    grname = "eta_%g_%g/resRefRef_%g_%g_diff" % (eta_min, eta_max, eta_min, eta_max)
    try:
        graph = cu.get_from_file(res_file, grname)
    except IOError:
        print '!! Cannot get', grname
        return None
    # leg = generate_legend()
    mg = ROOT.TMultiGraph()
    i = 0
    graph.SetLineColor(plot_colors[i])
    graph.SetMarkerColor(plot_colors[i])
    graph.SetMarkerStyle(plot_markers[i])
    mg.Add(graph)
    # leg.AddEntry(graph, plot_labels[i], "LP")

    mg.Draw("ALP")
    mg.GetXaxis().SetTitleSize(0.04)
    mg.GetXaxis().SetTitleOffset(0.9)
    # mg.GetYaxis().SetTitle(res_l1_str)
    mg.GetYaxis().SetRangeUser(0, mg.GetYaxis().GetXmax() * 1.5)
    mg.GetYaxis().SetRangeUser(0, 0.6)
    mg.GetHistogram().SetTitle("%s;%s;%s" % (plot_title + ', %g < %s < %g' % (eta_min, eta_l1_str, eta_max), pt_ref_str, res_ref_str))
    mg.Draw("ALP")
    # leg.Draw()
    append = ""
    c.SaveAs("%s/res_ref_eta_%g_%g_diff%s.%s" % (oDir, eta_min, eta_max, append, oFormat))
def plot_eta_pt_rsp_2d(calib_file, etaBins, ptBins, oDir, oFormat='pdf'):
    """
    Plot a 2D map of response for each eta, pt bin. Display the <response> from
    Gaussian fit of response hist in that bin

    Uses the resolution output file, since this plot of rsp & fit for pT(L1) bin,
    and will be done for pre and post calib, whereas output from runCalibration
    will generally only be pre calib, and is binned by ref Jet pt
    """
    h_2d = ROOT.TH2D("h2d_eta_pt_rsp", ";%s;%s" % (pt_l1_str, eta_l1_str) ,
                     len(ptBins) - 1, array('d', ptBins),
                     len(etaBins) - 1, array('d', etaBins))
    for eta_ind, (eta_min, eta_max) in enumerate(zip(etaBins[:-1], etaBins[1:]), 1):
        for pt_ind, (pt_min, pt_max) in enumerate(zip(ptBins[:-1], ptBins[1:]), 1):
            h_rsp = cu.get_from_file(calib_file, "eta_%g_%g/Histograms/res_l1_%g_%g" % (eta_min, eta_max, pt_min, pt_max))
            if h_rsp.GetEntries() > 0:
                # we actually use the fit to (L1-Gen)/L1, so we need to * -1 and invert
                res = h_rsp.GetListOfFunctions().At(0).GetParameter(1)
                rsp = 1. / (1 - res)
                print rsp
                h_2d.SetBinContent(pt_ind, eta_ind, rsp)
            else:
                h_2d.SetBinContent(pt_ind, eta_ind, 0)
    c = generate_canvas()
    ROOT.gStyle.SetPaintTextFormat(".2f")
    ROOT.gStyle.SetPalette(56)
    h_2d.Draw("COLZTEXT")
    h_2d.GetZaxis().SetRangeUser(0, 2)
    c.SaveAs("%s/h2d_eta_pt_rsp.%s" % (oDir, oFormat))
def make_plots(filenames, oDir, hist_names, title):

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

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

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

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

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

        leg.Draw()

        outname = os.path.join(oDir, hname+'.pdf')
        cu.check_dir_exists_create(os.path.dirname(outname))
        c.SaveAs(os.path.join(oDir, hname+'.pdf'))
def redo_correction_fit(inputfile, outputfile, absetamin, absetamax, fitfcn):
    """Redo correction fit for a given eta bin.

    Get TGraphErrors for the bin, and perform calibration curve fitting
    procedure and save if successful.

    inputfile: TFile. The output file from running runCalibration.py previously.
    outputfile: TFile. The file you want to write the new graph & fit to.
    Can be the same as inputfile.
    absetamin: double
    absetamax: double
    fitfcn: TF1
    """
    # Get relevant graph
    gr = cu.get_from_file(inputfile,
                          generate_eta_graph_name(absetamin, absetamax))
    outputfile.WriteTObject(gr, gr.GetName(),
                            'Overwrite')  # the original graph

    # Setup fitting (calculate sensible range, make sub-graph), then do fit!
    sub_graph, this_fit = setup_fit(gr, fitfcn, absetamin, absetamax,
                                    outputfile)
    fit_graph, fit_params = fit_correction(sub_graph, this_fit)
    outputfile.WriteTObject(this_fit, this_fit.GetName(),
                            'Overwrite')  # function by itself
    outputfile.WriteTObject(
        fit_graph, fit_graph.GetName(),
        'Overwrite')  # has the function stored in it as well
    return fit_params
def make_plot_eta_binned(input_filename, output_filename, title=''):
    f = cu.open_root_file(input_filename)
    tree = cu.get_from_file(f, 'valid')

    hists = []

    eta_bins = binning.eta_bins
    # eta_bins = [0, 3, 5]
    for i, (eta_min, eta_max) in enumerate(binning.pairwise(eta_bins)):
        hname = "h_%g_%g" % (eta_min, eta_max)
        h = ROOT.TH1D(hname, title + " PU15 - 25;response;p.d.f", 30, 0, 3)
        tree.Draw("rsp>>%s" % hname, "%g < TMath::Abs(eta) && TMath::Abs(eta) < %g && numPUVertices<25 && numPUVertices >15" % (eta_min, eta_max))
        h.SetLineColor(binning.eta_bin_colors[i])
        h.SetLineWidth(2)
        h.Scale(1. / h.Integral())
        hists.append(h)

    canv = ROOT.TCanvas("c", "", 600, 600)
    canv.SetTicks(1, 1)
    hstack = ROOT.THStack("hst", title + " PU15 - 25;response;p.d.f")
    leg = ROOT.TLegend(0.6, 0.6, 0.88, 0.88)
    for i, h in enumerate(hists):
        hstack.Add(h)
        leg.AddEntry(h, '%g < |#eta| < %g' % (eta_bins[i], eta_bins[i + 1]), 'L')

    hstack.Draw("NOSTACK HIST")
    leg.Draw()
    canv.SaveAs(output_filename)
def plot_res_pt_bin(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the L1 resolution for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/res_l1_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    h_res = cu.get_from_file(res_file, hname)
    c = generate_canvas()
    h_res.Draw()
    h_res.SetAxisRange(-2, 2, "X")
    h_res.SetTitle(";%s;N" % res_l1_str)
    c.SaveAs("%s/res_l1_eta_%g_%g_%g_%g.%s" % (oDir, eta_min, eta_max, pt_min, pt_max, oFormat))
def plot_correction_graph(calib_file, eta_min, eta_max, oDir, oFormat='pdf'):
    """Plot the graph of correction value vs pT"""
    gname = generate_eta_graph_name(eta_min, eta_max)
    gr = cu.get_from_file(calib_file, gname)
    c = generate_canvas()
    gr.Draw("ALP")
    y_min = ROOT.TMath.MinElement(gr.GetN(), gr.GetY())
    y_max = ROOT.TMath.MaxElement(gr.GetN(), gr.GetY())
    if y_max > 5:
        y_max = 5
    gr.GetYaxis().SetRangeUser(y_min * 0.7, y_max * 1.1)
    c.SaveAs('%s/%s.%s' % (oDir, gname, oFormat))
예제 #10
0
 def get_obj(self):
     """Get object for this contribution."""
     input_file = cu.open_root_file(self.file_name)
     self.obj = cu.get_from_file(input_file, self.obj_name)
     self.obj.SetLineWidth(self.line_width)
     self.obj.SetLineColor(self.line_color)
     self.obj.SetLineStyle(self.line_style)
     self.obj.SetMarkerSize(self.marker_size)
     self.obj.SetMarkerColor(self.marker_color)
     self.obj.SetMarkerStyle(self.marker_style)
     input_file.Close()
     return self.obj
def plot_rsp_eta_bin(calib_file, eta_min, eta_max, oDir, oFormat="pdf"):
    """Plot the response in one eta bin"""
    hname = "eta_%g_%g/Histograms/hrsp_eta_%g_%g" % (eta_min, eta_max, eta_min, eta_max)
    h_rsp = cu.get_from_file(calib_file, hname)
    func = h_rsp.GetListOfFunctions().At(0)
    c = generate_canvas()
    h_rsp.SetTitle(os.path.basename(hname) + ';response (%s)' % rsp_str)
    h_rsp.Draw("HISTE")
    if func:
        func.Draw("SAME")
    filename = "%s/h_rsp_%g_%g.%s" % (oDir, eta_min, eta_max, oFormat)
    c.SaveAs(filename)
    return filename
def plot_ptDiff_Vs_pt(res_file, eta_min, eta_max, oDir, oFormat='pdf'):
    """Plot (ptL1 - pTRef) Vs pTL1 for given eta bin"""
    hname = "eta_%g_%g/Histograms/ptDiff_ref_2d" % (eta_min, eta_max)
    h_2d = cu.get_from_file(res_file, hname)
    c = generate_canvas()
    ROOT.gStyle.SetPalette(55)
    h_2d.RebinX(16)
    # h_2d.RebinY(2)
    h_2d.Draw("COLZ")
    h_2d.GetYaxis().SetRangeUser(-120, 120)
    c.SetLogz()
    c.SetTicks(1, 1)
    c.SaveAs("%s/h2d_ptDiff_ptRef_eta_%g_%g.%s" % (oDir, eta_min, eta_max, oFormat))
예제 #13
0
 def get_obj(self):
     """Get object for this contribution."""
     input_file = cu.open_root_file(self.file_name)
     self.obj = cu.get_from_file(input_file, self.obj_name)
     self.obj.SetLineWidth(self.line_width)
     self.obj.SetLineColor(self.line_color)
     self.obj.SetLineStyle(self.line_style)
     self.obj.SetMarkerSize(self.marker_size)
     self.obj.SetMarkerColor(self.marker_color)
     self.obj.SetMarkerStyle(self.marker_style)
     if isinstance(self.obj, ROOT.TH1):
         self.obj.SetDirectory(0)
     input_file.Close()
     return self.obj
def plot_pt_diff(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the difference between L1 and ref jet pT, for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/ptDiff_ref_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    h_diff = cu.get_from_file(res_file, hname)
    c = generate_canvas()
    h_diff.Draw()
    h_diff.SetMaximum(h_diff.GetMaximum() * 1.2)
    # h_diff.SetLineWidth(2)
    func = h_diff.GetListOfFunctions().At(0)
    func.SetLineWidth(1)
    h_diff.SetTitle("%g < %s < %g, %g < p_{T}^{%s} < %g;%s;N" % (eta_min, eta_l1_str, eta_max, pt_min, ref_str, pt_max, pt_diff_str))
    if not os.path.exists("%s/eta_%g_%g" % (oDir, eta_min, eta_max)):
        os.makedirs("%s/eta_%g_%g" % (oDir, eta_min, eta_max))
    c.SaveAs("%s/eta_%g_%g/pt_diff_eta_%g_%g_%g_%g.%s" % (oDir, eta_min, eta_max, eta_min, eta_max, pt_min, pt_max, oFormat))
def plot_rsp_Vs_pt_candle_violin(check_file, eta_min, eta_max, ptVar, oDir, oFormat):
    """Plot response vs pt as a candle plot and violin plot.
    Also puts fitted peak graph on there as well for comparison."""

    hname = "eta_%g_%g/Histograms/h2d_rsp_%s" % (eta_min, eta_max, ptVar)
    if cu.exists_in_file(check_file, hname):
        h2d_rsp_pt_orig = cu.get_from_file(check_file, hname)
    else:
        h2d_rsp_pt_orig = cu.get_from_file(check_file, "eta_%g_%g/Histograms/h2d_rsp_%s" % (eta_min, eta_max, ptVar))
    h2d_rsp_pt = h2d_rsp_pt_orig.Rebin2D(1, 1, "hnew")

    c = generate_canvas()
    ptStr = pt_l1_str if ptVar == 'l1' else pt_ref_str
    h2d_rsp_pt.SetTitle("%s: %g-%g;%s;%s" % (eta_l1_str, eta_min, eta_max, ptStr, rsp_str))
    h2d_rsp_pt.Draw("CANDLE")
    # Draw fitted peaks as well
    gr_name = "eta_{0:g}_{1:g}/gr_rsp_{2}_eta_{0:g}_{1:g}".format(eta_min, eta_max, 'pt' if ptVar == 'l1' else 'ptRef')
    gr = cu.get_from_file(check_file, gr_name)
    gr.SetLineColor(ROOT.kRed)
    gr.SetMarkerColor(ROOT.kRed)
    gr.SetMarkerStyle(21)
    gr.Draw("LP")

    max_pt = 100
    gr.GetXaxis().SetLimits(0, max_pt)
    h2d_rsp_pt.SetAxisRange(0, max_pt, 'X')
    h2d_rsp_pt.SetAxisRange(rsp_min, rsp_max, 'Y')

    line = ROOT.TLine(0, 1, max_pt, 1)
    line.SetLineStyle(2)
    line.SetLineWidth(2)
    line.Draw()
    c.SaveAs("%s/h2d_rsp_%s_%g_%g_box.%s" % (oDir, 'l1' if ptVar == 'l1' else 'ref', eta_min, eta_max, oFormat))

    h2d_rsp_pt.Draw("VIOLIN")
    gr.Draw("LP")
    c.SaveAs("%s/h2d_rsp_%s_%g_%g_violin.%s" % (oDir, 'l1' if ptVar == 'l1' else 'ref', eta_min, eta_max, oFormat))
def plot_pt_bin(calib_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the L1 pt in a given ref jet pt bin, for a given eta bin"""
    sub_dir = "eta_%g_%g" % (eta_min, eta_max)
    if not os.path.isdir("%s/%s" % (oDir, sub_dir)):
        os.mkdir("%s/%s" % (oDir, sub_dir))
    hname = "eta_%g_%g/Histograms/L1_pt_genpt_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    # ignore histogram not found errors... naughty naughty
    try:
        h_pt = cu.get_from_file(calib_file, hname)
        c = generate_canvas()
        h_pt.Draw("HISTE")
        filepath = "%s/%s/L1_pt_%g_%g_%g_%g.%s" % (oDir, sub_dir, eta_min, eta_max, pt_min, pt_max, oFormat)
        c.SaveAs(filepath)
        return filepath
    except Exception:
        print "! No histogram %s exists" % hname
def process_file(filename, eta_bins=binning.eta_bins_forward):
    """Process a ROOT file with graphs, print a mean & mean histogram for each.

    Parameters
    ----------
    filename : str
        Name of ROOT file to process (from runCalibration.py)
    eta_bins : list[[float, float]]
        Eta bin edges.
    """
    f = cu.open_root_file(filename)

    for eta_min, eta_max in binning.pairwise(eta_bins):
        gr = cu.get_from_file(f, generate_eta_graph_name(eta_min, eta_max))
        if not gr:
            raise RuntimeError("Can't get graph")

        xarr, yarr = cu.get_xy(gr)
        xarr, yarr = np.array(xarr), np.array(
            yarr)  # use numpy array for easy slicing

        # Loop over all possible subgraphs, and calculate a mean for each
        end = len(yarr)
        means = []
        while end > 0:
            start = 0
            while start < end:
                means.append(yarr[start:end].mean())
                start += 1
            end -= 1

        # Jackknife means
        jack_means = [np.delete(yarr, i).mean() for i in range(len(yarr))]

        # Do plotting & peak finding in both ROOT and MPL...not sure which is better?
        # peak = plot_find_peak_mpl(means, eta_min, eta_max, os.path.dirname(os.path.realpath(filename)))
        peak = plot_find_peak_root(means, eta_min, eta_max,
                                   os.path.dirname(os.path.realpath(filename)))
        jackpeak = plot_jacknife_root(
            jack_means, eta_min, eta_max,
            os.path.dirname(os.path.realpath(filename)))
        print 'Eta bin:', eta_min, '-', eta_max
        print peak
        print 'jackknife mean:'
        print np.array(jack_means).mean()

    f.Close()
def plot_res_pt_bin(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the L1 resolution for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/res_l1_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    try:
        h_res = cu.get_from_file(res_file, hname)
    except IOError:
        print '!! Cannot get', hname
        return None
    c = generate_canvas()
    h_res.Draw()
    h_res.SetAxisRange(-2, 2, "X")
    h_res.SetTitle(";%s;N" % res_l1_str)
    subdir = "%s/eta_%g_%g" % (oDir, eta_min, eta_max)
    cu.check_dir_exists_create("%s/eta_%g_%g" % (oDir, eta_min, eta_max))
    filename = "%s/res_l1_eta_%g_%g_%g_%g.%s" % (subdir, eta_min, eta_max, pt_min, pt_max, oFormat)
    c.SaveAs(filename)
    return filename
def plot_rsp_pt_graph(check_file, eta_min, eta_max, oDir, oFormat='pdf', x_range=None):
    """Plot a graph of response vs pt (L1) for a given eta bin"""

    grname = "eta_%g_%g/gr_rsp_pt_eta_%g_%g" % (eta_min, eta_max, eta_min, eta_max)

    graph = cu.get_from_file(check_file, grname)

    c = generate_canvas(plot_title)

    # leg = generate_legend()

    mg = ROOT.TMultiGraph()

    i = 0
    graph.SetLineColor(plot_colors[i])
    graph.SetMarkerColor(plot_colors[i])
    graph.SetMarkerStyle(plot_markers[i])
    mg.Add(graph)
    # leg.AddEntry(graph, plot_labels[i], "LP")

    pt_min, pt_max = (0, 1022) if not x_range else (x_range[0], x_range[1])
    # lines at 1, and +/- 0.1
    line_central = ROOT.TLine(pt_min, 1, pt_max, 1)
    line_plus = ROOT.TLine(pt_min, 1.1, pt_max, 1.1)
    line_minus = ROOT.TLine(pt_min, 0.9, pt_max, 0.9)
    line_central.SetLineWidth(2)
    line_central.SetLineStyle(2)
    for line in [line_plus, line_minus]:
        line.SetLineWidth(2)
        line.SetLineStyle(3)

    # bundle all graphs into a TMultiGraph - set axes limits here
    mg.Draw("ALP")
    mg.GetYaxis().SetRangeUser(rsp_min, rsp_max)
    mg.GetXaxis().SetLimits(pt_min, pt_max)
    mg.GetXaxis().SetTitleSize(0.04)
    mg.GetXaxis().SetTitleOffset(0.9)
    # mg.GetYaxis().SetTitleSize(0.04)
    mg.Draw("ALP")
    mg.GetHistogram().SetTitle("%s;%s;%s" % (plot_title + ", %g < %s < %g" % (eta_min, eta_l1_str, eta_max), pt_l1_str, rsp_str))

    # leg.Draw()
    [line.Draw() for line in [line_central, line_plus, line_minus]]
    append = ""
    c.SaveAs("%s/gr_rsp_pt_eta_%g_%g%s.%s" % (oDir, eta_min, eta_max, append, oFormat))
def plot_rsp_eta_inclusive_graph(check_file, eta_min, eta_max, pt_var, oDir, oFormat="pdf"):
    """Plot a graph of response vs L1 eta."""
    grname = "eta_%g_%g/gr_rsp_%s_eta_%g_%g" % (eta_min, eta_max, pt_var, eta_min, eta_max)

    graph = cu.get_from_file(check_file, grname)

    c = generate_canvas(plot_title)

    # leg = generate_legend() #(0.4, 0.7, 0.87, 0.87) # top right
    # leg = generate_legend()

    mg = ROOT.TMultiGraph()

    i = 0
    graph.SetLineColor(plot_colors[i])
    graph.SetMarkerColor(plot_colors[i])
    graph.SetMarkerStyle(plot_markers[i])
    mg.Add(graph)
    # leg.AddEntry(graph, plot_labels[i], "LP")

    # lines at 1, and +/- 0.1
    line_central = ROOT.TLine(eta_min, 1, eta_max, 1)
    line_plus = ROOT.TLine(eta_min, 1.1, eta_max, 1.1)
    line_minus = ROOT.TLine(eta_min, 0.9, eta_max, 0.9)
    line_central.SetLineWidth(2)
    line_central.SetLineStyle(2)
    for line in [line_plus, line_minus]:
        line.SetLineWidth(2)
        line.SetLineStyle(3)

    # bundle all graphs into a TMultiGraph - set axes limits here
    mg.Draw("ALP")
    mg.GetYaxis().SetRangeUser(rsp_min, rsp_max)
    mg.GetXaxis().SetLimits(eta_min, eta_max)
    mg.GetXaxis().SetTitleSize(0.04)
    mg.GetXaxis().SetTitleOffset(0.9)
    # mg.GetYaxis().SetTitleSize(0.04)
    mg.Draw("ALP")
    mg.GetHistogram().SetTitle("%s;%s;%s" % (plot_title, eta_l1_str, rsp_str))

    # leg.Draw()
    [line.Draw() for line in [line_central, line_plus, line_minus]]
    append = ""
    c.SaveAs("%s/gr_rsp_eta_%g_%g%s.%s" % (oDir, eta_min, eta_max, append, oFormat))
def plot_rsp_eta_bin_pt(calib_file, eta_min, eta_max, pt_var, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the response in one eta bin with a pt cut"""
    if eta_max <= 3:
        hname = "eta_0_3/Histograms/hrsp_eta_%g_%g_%s_%g_%g" % (eta_min, eta_max, pt_var, pt_min, pt_max)
    else:
        hname = "eta_3_5/Histograms/hrsp_eta_%g_%g_%s_%g_%g" % (eta_min, eta_max, pt_var, pt_min, pt_max)
    try:
        h_rsp = cu.get_from_file(calib_file, hname)
    except Exception:
        return None
    func = h_rsp.GetListOfFunctions().At(0)
    c = generate_canvas()
    h_rsp.SetTitle(os.path.basename(hname) + ';response (%s)' % rsp_str)
    h_rsp.Draw("HISTE")
    if func:
        func.Draw("SAME")
    output_filename = "%s/h_rsp_%g_%g_%s_%g_%g.%s" % (oDir, eta_min, eta_max, pt_var, pt_min, pt_max, oFormat)
    c.SaveAs(output_filename)
    return output_filename
def process_file(filename, eta_bins=binning.eta_bins_forward):
    """Process a ROOT file with graphs, print a mean & mean histogram for each.

    Parameters
    ----------
    filename : str
        Name of ROOT file to process (from runCalibration.py)
    eta_bins : list[[float, float]]
        Eta bin edges.
    """
    f = cu.open_root_file(filename)

    for eta_min, eta_max in binning.pairwise(eta_bins):
        gr = cu.get_from_file(f, generate_eta_graph_name(eta_min, eta_max))
        if not gr:
            raise RuntimeError("Can't get graph")

        xarr, yarr = cu.get_xy(gr)
        xarr, yarr = np.array(xarr), np.array(yarr)  # use numpy array for easy slicing

        # Loop over all possible subgraphs, and calculate a mean for each
        end = len(yarr)
        means = []
        while end > 0:
            start = 0
            while start < end:
                means.append(yarr[start:end].mean())
                start += 1
            end -= 1

        # Jackknife means
        jack_means = [np.delete(yarr, i).mean() for i in range(len(yarr))]

        # Do plotting & peak finding in both ROOT and MPL...not sure which is better?
        # peak = plot_find_peak_mpl(means, eta_min, eta_max, os.path.dirname(os.path.realpath(filename)))
        peak = plot_find_peak_root(means, eta_min, eta_max, os.path.dirname(os.path.realpath(filename)))
        jackpeak = plot_jacknife_root(jack_means, eta_min, eta_max, os.path.dirname(os.path.realpath(filename)))
        print 'Eta bin:', eta_min, '-', eta_max
        print peak
        print 'jackknife mean:'
        print np.array(jack_means).mean()

    f.Close()
def plot_rsp_eta_exclusive_graph(check_file, eta_min, eta_max, pt_bins, pt_var, oDir, oFormat="pdf"):
    """Plot a graph of response vs L1 eta.

    pt_bins is a list of pt bin edges to plot on the same graph
    pt_var is the varaible (pt or ptRef)
    """
    mg = ROOT.TMultiGraph()
    leg = generate_legend(x1=0.65, y1=0.65)
    c = generate_canvas(plot_title)
    gr_name = "eta_%g_%g/gr_rsp_eta_%g_%g_{0}_{1}_{2}" % (eta_min, eta_max, eta_min, eta_max)
    for i, (pt_min, pt_max) in enumerate(pt_bins):
        g = cu.get_from_file(check_file, gr_name.format(pt_var, pt_min, pt_max))
        g.SetLineColor(binning.eta_bin_colors[i])
        g.SetMarkerColor(binning.eta_bin_colors[i])
        g.SetMarkerStyle(plot_markers[0])
        mg.Add(g)
        # leg.AddEntry(g, plot_labels[0] + " %g < %s < %g" % (pt_min, pt_var, pt_max), "LP")
        leg.AddEntry(g, " %g < %s < %g" % (pt_min, pt_var, pt_max), "LP")

    # lines at 1, and +/- 0.1
    line_central = ROOT.TLine(eta_min, 1, eta_max, 1)
    line_plus = ROOT.TLine(eta_min, 1.1, eta_max, 1.1)
    line_minus = ROOT.TLine(eta_min, 0.9, eta_max, 0.9)
    line_central.SetLineWidth(2)
    line_central.SetLineStyle(2)
    for line in [line_plus, line_minus]:
        line.SetLineWidth(2)
        line.SetLineStyle(3)

    # bundle all graphs into a TMultiGraph - set axes limits here
    mg.Draw("ALP")
    mg.GetYaxis().SetRangeUser(rsp_min, rsp_max)
    mg.GetXaxis().SetLimits(eta_min, eta_max)
    mg.GetXaxis().SetTitleSize(0.04)
    mg.GetXaxis().SetTitleOffset(0.9)
    # mg.GetYaxis().SetTitleSize(0.04)
    mg.Draw("ALP")
    mg.GetHistogram().SetTitle("%s;%s;%s" % (plot_title, eta_l1_str, rsp_str))

    leg.Draw()
    [line.Draw() for line in [line_central, line_plus, line_minus]]
    c.SaveAs("%s/gr_rsp_eta_%g_%g_%s_%g_%g_binned.%s" % (oDir, eta_min, eta_max, pt_var, pt_bins[0][0], pt_bins[-1][1], oFormat))
def plot_rsp_eta_pt_bin(calib_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the response in one pt, eta bin"""
    sub_dir = "eta_%g_%g" % (eta_min, eta_max)
    if not os.path.isdir("%s/%s" % (oDir, sub_dir)):
        os.mkdir("%s/%s" % (oDir, sub_dir))
    hname = "eta_%g_%g/Histograms/Rsp_genpt_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    # ignore histogram not found errors... naughty naughty
    try:
        h_rsp = cu.get_from_file(calib_file, hname)
        c = generate_canvas()
        h_rsp.Draw("HISTE")
        func = h_rsp.GetListOfFunctions().At(0)
        if func:
            func.Draw("SAME")
        h_rsp.SetTitle("%s;%s;" % (hname, rsp_str))
        filepath = "%s/%s/h_rsp_%g_%g_%g_%g.%s" % (oDir, sub_dir, eta_min, eta_max, pt_min, pt_max, oFormat)
        c.SaveAs(filepath)
        return filepath
    except Exception:
        print "! No histogram %s exists" % hname
def plot_rsp_pt_binned_graph(check_file, eta_bins, pt_var, oDir, oFormat='pdf', x_range=None):
    """Plot a graph of response vs pt_var, in bins of eta"""

    mg = ROOT.TMultiGraph()
    leg = generate_legend(x1=0.65, y1=0.65)
    c = generate_canvas(plot_title)
    gr_name = "eta_{0:g}_{1:g}/gr_rsp_%s_eta_{0:g}_{1:g}" % (pt_var)
    for i, (eta_min, eta_max) in enumerate(zip(eta_bins[:-1], eta_bins[1:])):
        g = cu.get_from_file(check_file, gr_name.format(eta_min, eta_max))
        g.SetLineColor(binning.eta_bin_colors[i])
        g.SetMarkerColor(binning.eta_bin_colors[i])
        g.SetMarkerStyle(plot_markers[0])
        mg.Add(g)
        # leg.AddEntry(g, plot_labels[0] + " %g < |#eta^{L1}| < %g" % (eta_min, eta_var), "LP")
        leg.AddEntry(g, " %g < %s < %g" % (eta_min, eta_l1_str, eta_max), "LP")

    pt_min, pt_max = (0, 1022) if not x_range else (x_range[0], x_range[1])
    # lines at 1, and +/- 0.1
    line_central = ROOT.TLine(pt_min, 1, pt_max, 1)
    line_plus = ROOT.TLine(pt_min, 1.1, pt_max, 1.1)
    line_minus = ROOT.TLine(pt_min, 0.9, pt_max, 0.9)
    line_central.SetLineWidth(2)
    line_central.SetLineStyle(2)
    for line in [line_plus, line_minus]:
        line.SetLineWidth(2)
        line.SetLineStyle(3)

    # bundle all graphs into a TMultiGraph - set axes limits here
    mg.Draw("ALP")
    mg.GetYaxis().SetRangeUser(rsp_min, rsp_max)
    mg.GetXaxis().SetLimits(pt_min, pt_max)
    mg.GetXaxis().SetTitleSize(0.04)
    mg.GetXaxis().SetTitleOffset(0.9)
    # mg.GetYaxis().SetTitleSize(0.04)
    mg.Draw("ALP")
    xtitle = pt_l1_str if pt_var == "pt" else pt_ref_str
    mg.GetHistogram().SetTitle("%s;%s;%s" % (plot_title, xtitle, rsp_str))

    leg.Draw()
    [line.Draw() for line in [line_central, line_plus, line_minus]]
    c.SaveAs("%s/gr_rsp_%s_eta_%g_%g_binned.%s" % (oDir, pt_var, eta_bins[0], eta_bins[-1], oFormat))
def plot_pt_diff(res_file, eta_min, eta_max, pt_min, pt_max, oDir, oFormat="pdf"):
    """Plot the difference between L1 and ref jet pT, for given L1 pT, eta bin"""
    hname = "eta_%g_%g/Histograms/ptDiff_ref_%g_%g" % (eta_min, eta_max, pt_min, pt_max)
    try:
        h_diff = cu.get_from_file(res_file, hname)
    except IOError:
        print '!! Cannot get', hname
        return None
    c = generate_canvas()
    h_diff.Draw()
    h_diff.SetMaximum(h_diff.GetMaximum() * 1.2)
    # h_diff.SetLineWidth(2)
    func = h_diff.GetListOfFunctions().At(0)
    if func:
        func.SetLineWidth(2)
    h_diff.SetTitle("%g < %s < %g, %g < p_{T}^{%s} < %g;%s;N" % (eta_min, eta_l1_str, eta_max, pt_min, ref_str, pt_max, pt_diff_str))
    subdir = "%s/eta_%g_%g" % (oDir, eta_min, eta_max)
    cu.check_dir_exists_create("%s/eta_%g_%g" % (oDir, eta_min, eta_max))
    filename = "%s/pt_diff_eta_%g_%g_%g_%g.%s" % (subdir, eta_min, eta_max, pt_min, pt_max, oFormat)
    c.SaveAs(filename)
    return filename
예제 #27
0
def make_htt_plots(input_filename, output_dir):
    """Make HTT plots for one input file.

    Parameters
    ----------
    input_filename : str
        Name of pairs ROOT file.
    output_dir : str
        Name of output directory for plots.
    """
    in_stem = os.path.splitext(os.path.basename(input_filename))[0]
    output_dir = os.path.join(output_dir, in_stem)
    if not os.path.isdir(output_dir):
        print 'Making output dir', output_dir
        os.makedirs(output_dir)

    f = cu.open_root_file(input_filename)
    tree = cu.get_from_file(f, "valid")

    common_cut = COMMON_CUT
    norm_cut = '1./nMatches'  # normalisation, for event-level quantities, since we store it for each match in an event
    if common_cut != '':
        norm_cut += ' && %s' % common_cut

    do_htt_plots(tree, output_dir, norm_cut)

    do_mht_plots(tree, output_dir, norm_cut)

    # Do plots where y axis is some variable of interest
    do_dr_plots(tree, output_dir, common_cut)

    do_rsp_plots(tree, output_dir, common_cut)

    do_nvtx_plots(tree, output_dir, norm_cut)

    do_njets_plots(tree, output_dir, norm_cut)

    do_jet_pt_plots(tree, output_dir, common_cut)

    f.Close()
def make_htt_plots(input_filename, output_dir):
    """Make HTT plots for one input file.

    Parameters
    ----------
    input_filename : str
        Name of pairs ROOT file.
    output_dir : str
        Name of output directory for plots.
    """
    in_stem = os.path.splitext(os.path.basename(input_filename))[0]
    output_dir = os.path.join(output_dir, in_stem)
    if not os.path.isdir(output_dir):
        print 'Making output dir', output_dir
        os.makedirs(output_dir)

    f = cu.open_root_file(input_filename)
    tree = cu.get_from_file(f, "valid")

    common_cut = COMMON_CUT
    norm_cut = '1./nMatches'  # normalisation, for event-level quantities, since we store it for each match in an event
    if common_cut != '':
        norm_cut += ' && %s' % common_cut

    do_htt_plots(tree, output_dir, norm_cut)

    do_mht_plots(tree, output_dir, norm_cut)

    # Do plots where y axis is some variable of interest
    do_dr_plots(tree, output_dir, common_cut)

    do_rsp_plots(tree, output_dir, common_cut)

    do_nvtx_plots(tree, output_dir, norm_cut)

    do_njets_plots(tree, output_dir, norm_cut)

    do_jet_pt_plots(tree, output_dir, common_cut)

    f.Close()
def plot_rsp_pt_hists(check_file, eta_min, eta_max, pt_bins, pt_var, oDir, oFormat='pdf'):
    """Plot component hists of response vs pt graph, for given eta bin"""

    sub_dir = "eta_%g_%g" % (eta_min, eta_max)
    if not os.path.isdir("%s/%s" % (oDir, sub_dir)):
        os.mkdir("%s/%s" % (oDir, sub_dir))

    c = generate_canvas(plot_title)
    filenames = []
    for i, pt_min in enumerate(pt_bins[:-1]):
        pt_max = pt_bins[i + 1]
        hname = "%s/Histograms/rsp_%s_%g_%g" % (sub_dir, pt_var, pt_min, pt_max)
        try:
            hist = cu.get_from_file(check_file, hname)
            hist.SetTitle("%s;%s;N" % (plot_title, rsp_str))
            hist.Draw()
            filename = "%s/%s/rsp_%s_%g_%g.%s" % (oDir, sub_dir, pt_var, pt_min, pt_max, oFormat)
            c.SaveAs(filename)
            filenames.append(filename)
        except Exception:
            print '! No histogram %s exists' % hname
    return filenames
def redo_correction_fit(inputfile, outputfile, absetamin, absetamax, fitfcn):
    """Redo correction fit for a given eta bin.

    Get TGraphErrors for the bin, and perform calibration curve fitting
    procedure and save if successful.

    inputfile: TFile. The output file from running runCalibration.py previously.
    outputfile: TFile. The file you want to write the new graph & fit to.
    Can be the same as inputfile.
    absetamin: double
    absetamax: double
    fitfcn: TF1
    """
    # Get relevant graph
    gr = cu.get_from_file(inputfile, generate_eta_graph_name(absetamin, absetamax))
    outputfile.WriteTObject(gr, gr.GetName(), 'Overwrite')  # the original graph

    # Setup fitting (calculate sensible range, make sub-graph), then do fit!
    sub_graph, this_fit = setup_fit(gr, fitfcn, absetamin, absetamax, outputfile)
    fit_graph, fit_params = fit_correction(sub_graph, this_fit)
    outputfile.WriteTObject(this_fit, this_fit.GetName(), 'Overwrite')  # function by itself
    outputfile.WriteTObject(fit_graph, fit_graph.GetName(), 'Overwrite')  # has the function stored in it as well
    return fit_params
def plot_l1_Vs_ref(check_file, eta_min, eta_max, logZ, oDir, oFormat="pdf"):
    """Plot l1 pt against ref jet pt, for given L1 eta bin"""
    hname = "eta_%g_%g/Histograms/h2d_gen_l1" % (eta_min, eta_max)
    h2d_gen_l1 = cu.get_from_file(check_file, hname)
    c = generate_canvas()
    app = ""
    if logZ:
        c.SetLogz()
        app = "_log"
    h2d_gen_l1.SetTitle("%s: %g-%g;%s;%s" % (eta_l1_str, eta_min, eta_max, pt_ref_str, pt_l1_str))
    h2d_gen_l1.Draw("COLZ")
    max_pt = 512
    h2d_gen_l1.SetAxisRange(0, max_pt, 'X')
    h2d_gen_l1.SetAxisRange(0, max_pt, 'Y')
    # lines of constant response
    line1 = ROOT.TLine(0, 0, max_pt, max_pt)
    line1.SetLineStyle(1)
    line1.SetLineWidth(2)
    line1.Draw()

    line1p25 = ROOT.TLine(0, 0, max_pt / 1.25, max_pt)
    line1p25.SetLineWidth(2)
    # line1p25.Draw()

    line1p5 = ROOT.TLine(0, 0, max_pt / 1.5, max_pt)
    line1p5.SetLineWidth(2)
    # line1p5.Draw()

    line0p75 = ROOT.TLine(0, 0, max_pt, max_pt * 0.75)
    line0p75.SetLineWidth(2)
    # line0p75.Draw()

    line0p5 = ROOT.TLine(0, 0, max_pt, max_pt * 0.5)
    line0p5.SetLineWidth(2)
    # line0p5.Draw()

    c.SaveAs("%s/h2d_gen_l1_%g_%g%s.%s" % (oDir, eta_min, eta_max, app, oFormat))
def draw_horizontal_rsp(max_pt):
    # lines of constant response
    line1 = ROOT.TLine(0, 1, max_pt, 1)
    line1.SetLineStyle(1)
    line1.SetLineWidth(2)
    line1.SetLineColor(ROOT.kMagenta)
    line1.Draw()
    ROOT.SetOwnership(line1, False)


if __name__ == "__main__":
    # L1 Ntuple file
    ntuple_filename = '/hdfs/user/ra12451/L1JEC/CMSSW_7_6_0_pre7/L1JetEnergyCorrections/Stage2_Run260627/Express/run260627_expressNoJEC.root'
    f_ntuple = cu.open_root_file(ntuple_filename)
    reco_tree = cu.get_from_file(f_ntuple, 'l1JetRecoTree/JetRecoTree')

    # Matched pairs file
    pairs_filename = "/hdfs/user/ra12451/L1JEC/CMSSW_7_6_0_pre7/L1JetEnergyCorrections/Stage2_Run260627/pairs/pairs_run260627_expressNoJEC_data_ref10to5000_l10to5000_dr0p4_noCleaning_fixedEF_CSC_HLTvars.root"

    f_pairs = cu.open_root_file(pairs_filename)
    pairs_tree = cu.get_from_file(f_pairs, 'valid')

    plot_dir = '/users/ra12451/L1JEC/CMSSW_7_6_0_pre7/src/L1Trigger/L1JetEnergyCorrections/Run260627/pfCleaning/'
    if not os.path.isdir(plot_dir):
        os.makedirs(plot_dir)

    eta_cut = 'TMath::Abs(eta) < 0.348'
    etaRef_cut = 'TMath::Abs(etaRef) < 0.348'
    LS_cut = ("((LS > 91 && LS < 611) || (LS > 613 && LS < 757) || (LS > 760 && LS < 788) || (LS > 791 && LS < 1051) || (LS > 1054 && LS < 1530) || (LS > 1533 && LS < 1845))")
def make_correction_curves(inputfile, outputfile, ptBins_in, absetamin,
                           absetamax, fitfcn, do_genjet_plots,
                           do_correction_fit, pu_min, pu_max, do_burr):
    """
    Do all the relevant hists and fitting, for one eta bin.

    Briefly: make plots of L1 jet pT, and response (= l1/gen) for each genjet pt bin.
    Then find the mean L1 jet pT for the pt bin.
    Then fit a Gaussian to each response histogram, and get the mean.
    Plot 1/fitted mean Vs mean L1 pT.
    Then fit with given function, and return parameters.
    All of these plots are stored in the TFile, outputfile.

    Returns parameters of succeful fit.

    inputfile: TFile. Must contain TTree named "valid", full of pair quantities.

    outputfile: TFile. To store output histograms.

    ptBins_in: list. Edges of pt bins used to divide up correction curve.

    absetamin: float. Lower edge of eta bin, must be >= 0.

    absetamax: float. Upper edge of eta bin, must be > 0.

    fitfcn: TF1. Function to fit for correction curve.

    do_genjet_plots: bool. Whether to make plots for reference jets. Not used
        in calcualtion of correction curve, but handy for debugging.

    do_correction_fit: bool. Whether to actually fit the correction curve.

    pu_min: float. Cut on minimum number of PU vertices.

    pu_max: float. Cut on maximum number of PU vertices.

    do_burr: bool. If True, use Burr fn to fit response histograms.
    The default is to use a Gaussian.
    """

    print "Doing PU range: %g - %g" % (pu_min, pu_max)
    print "Running over pT bins:", ptBins_in

    # Input tree
    tree_raw = cu.get_from_file(inputfile, "valid")

    # Output folders
    output_f = outputfile.mkdir('eta_%g_%g' % (absetamin, absetamax))
    output_f_hists = output_f.mkdir("Histograms")

    # Eta cut string
    eta_cut = ROOT.TCut("TMath::Abs(eta)<%g && TMath::Abs(eta) > %g" %
                        (absetamax, absetamin))

    # PU cut string
    if hasattr(tree_raw, "numPUVertices"):
        pu_cut = ROOT.TCut("numPUVertices >= %g && numPUVertices <= %g" %
                           (pu_min, pu_max))
    else:
        pu_cut = ROOT.TCut("")

    # Avoid L1 saturated jets cut (from 2017 any l1 jet with a saturated tower is auto given pt=1024GeV)
    avoidSaturation_cut = ROOT.TCut("pt < 1023.1")

    # Total cut
    total_cut = ROOT.TCut(eta_cut)
    total_cut += pu_cut  # need to use += and not && cos TCut all fubar
    total_cut += avoidSaturation_cut
    print total_cut

    # Draw response (pT^L1/pT^Gen) for all pt bins
    tree_raw.Draw("rsp>>hrsp_eta_%g_%g(50,0,2)" % (absetamin, absetamax),
                  total_cut, "goff")
    hrsp_eta = ROOT.gROOT.FindObject("hrsp_eta_%g_%g" % (absetamin, absetamax))
    hrsp_eta.SetTitle(";response (p_{T}^{L1}/p_{T}^{Ref});")
    output_f_hists.WriteTObject(hrsp_eta)

    nb, pt_min, pt_max = 2048, 0, 1024

    # Draw rsp (pT^L1/pT^Gen) Vs GenJet pT
    tree_raw.Draw(
        "rsp:ptRef>>h2d_rsp_gen(%d,%g,%g,150,0,5)" % (nb, pt_min, pt_max),
        total_cut, "goff")
    h2d_rsp_gen = ROOT.gROOT.FindObject("h2d_rsp_gen")
    h2d_rsp_gen.SetTitle(
        ";p_{T}^{Ref} [GeV];response (p_{T}^{L1}/p_{T}^{Ref})")
    output_f_hists.WriteTObject(h2d_rsp_gen)

    # Draw rsp (pT^L1/pT^Gen) Vs L1 pT
    tree_raw.Draw(
        "rsp:pt>>h2d_rsp_l1(%d,%g,%g,150,0,5)" % (nb, pt_min, pt_max),
        total_cut, "goff")
    h2d_rsp_l1 = ROOT.gROOT.FindObject("h2d_rsp_l1")
    h2d_rsp_l1.SetTitle(";p_{T}^{L1} [GeV];response (p_{T}^{L1}/p_{T}^{Ref})")
    output_f_hists.WriteTObject(h2d_rsp_l1)

    # draw pT^L1 Vs pT^Gen
    tree_raw.Draw(
        "pt:ptRef>>h2d_gen_l1(%d,%g,%g,%d,%g,%g)" %
        (nb, pt_min, pt_max, nb, pt_min, pt_max), total_cut, "goff")
    h2d_gen_l1 = ROOT.gROOT.FindObject("h2d_gen_l1")
    h2d_gen_l1.SetTitle(";p_{T}^{Ref} [GeV];p_{T}^{L1} [GeV]")
    output_f_hists.WriteTObject(h2d_gen_l1)

    # Go through and find histogram bin edges that are closest to the input pt
    # bin edges, and store for future use
    ptBins = []
    bin_indices = []
    for i, ptR in enumerate(ptBins_in[0:-1]):
        bin1 = h2d_rsp_gen.GetXaxis().FindBin(ptR)
        bin2 = h2d_rsp_gen.GetXaxis().FindBin(ptBins_in[i + 1]) - 1
        xlow = h2d_rsp_gen.GetXaxis().GetBinLowEdge(bin1)
        xup = h2d_rsp_gen.GetXaxis().GetBinLowEdge(bin2 + 1)
        bin_indices.append([bin1, bin2])
        ptBins.append(xlow)
    ptBins.append(xup)  # only need this last one

    gr = ROOT.TGraphErrors()  # 1/<rsp> VS ptL1
    gr_gen = ROOT.TGraphErrors()  # 1/<rsp> VS ptGen
    grc = 0

    # Iterate over pT^Gen bins, and for each:
    # - Project 2D hist so we have a plot of response for given pT^Gen range
    # - Fit a Gaussian (if possible) to this resp histogram to get <response>
    # - Plot the L1 pT for given pT^Gen range (remember, for matched pairs)
    # - Get average response, <pT^L1>, from 1D L1 pT hist
    # - Add a new graph point, x=<pT^L1> y=<response> for this pT^Gen bin
    for i, ptR in enumerate(ptBins[0:-1]):

        bin1 = bin_indices[i][0]
        bin2 = bin_indices[i][1]
        # h2d_calib.GetXaxis().FindBin(ptR)
        # h2d_calib.GetXaxis().FindBin(ptBins[i+1])-1
        # print "Binning mis-matches", ptR, ptBins[i+1],
        # h2d_calib.GetXaxis().GetBinLowEdge(bin1),h2d_calib.GetXaxis().GetBinLowEdge(bin2+1)

        xlow = ptR
        xhigh = ptBins[i + 1]

        # Plot of response for given pT Gen bin
        hrsp = h2d_rsp_gen.ProjectionY("Rsp_genpt_%g_%g" % (xlow, xhigh), bin1,
                                       bin2)

        # cut on ref jet pt
        pt_cut = ROOT.TCut("ptRef < %g && ptRef > %g " % (xhigh, xlow))
        total_cut = ROOT.TCut(eta_cut)
        total_cut += pu_cut
        total_cut += avoidSaturation_cut
        total_cut += pt_cut
        print total_cut

        # Plots of pT L1 for given pT Gen bin
        tree_raw.Draw("pt>>hpt(4000, 0, 2000)", total_cut, "goff")
        hpt = ROOT.gROOT.FindObject("hpt")
        hpt.SetName("L1_pt_genpt_%g_%g" % (xlow, xhigh))
        # hpt = h2d_gen_l1.ProjectionX("L1_pt_genpt_%g_%g" % (xlow, xhigh))

        if hrsp.GetEntries() <= 0 or hpt.GetEntries() <= 0:
            print "Skipping as 0 entries"
            continue

        output_f_hists.WriteTObject(hpt)

        # Plots of pT Gen for given pT Gen bin
        if do_genjet_plots:
            tree_raw.Draw("ptRef>>hpt_gen(200)", total_cut, "goff")
            hpt_gen = ROOT.gROOT.FindObject("hpt_gen")
            hpt_gen.SetName("gen_pt_genpt_%g_%g" % (xlow, xhigh))
            output_f_hists.WriteTObject(hpt_gen)

        # Fit to resposne hist to get mean response & error on mean
        if do_burr:
            if (absetamin > 2 and i == 0):
                setup_burr3_higherEta()
            setup_fn = setup_burr3 if absetamin < 2 else setup_burr3_higherEta
            mean, err = do_burr_response_hist_fit(hrsp, setup_fn)
        else:
            mean, err = do_gauss_response_hist_fit(hrsp)

        output_f_hists.WriteTObject(hrsp)

        print "pT Gen: ", ptR, "-", ptBins[i + 1], "<pT L1>:", hpt.GetMean(), \
              "<pT Gen>:", (hpt_gen.GetMean() if do_genjet_plots else "NA"), "<rsp>:", mean

        # Since we're plotting 1/rsp on y axis, so need jacobian
        err = err / (mean**2)

        # add point to response graph vs pt
        # store if new max/min, but only max if pt > pt of previous point
        # max_pt = max(hpt.GetMean(), max_pt) if grc > 0 and hpt.GetMean() > gr.GetX()[grc-1] else max_pt
        # min_pt = min(hpt.GetMean(), min_pt)
        gr.SetPoint(grc, hpt.GetMean(), 1. / mean)
        gr.SetPointError(grc, hpt.GetMeanError(), err)
        if do_genjet_plots:
            gr_gen.SetPoint(grc, hpt_gen.GetMean(), 1. / mean)
            # gr_gen.SetPointError(grc, hpt.GetMeanError(), err)
        grc += 1

    # Label response VS pT graphs
    graph_name = generate_eta_graph_name(absetamin, absetamax)
    gr.SetName(graph_name)
    gr.GetXaxis().SetTitle("<p_{T}^{L1}> [GeV]")
    gr.GetYaxis().SetTitle("1/<p_{T}^{L1}/p_{T}^{Ref}>")

    if do_genjet_plots:
        gr_gen.SetName('gencorr_eta_%g_%g' % (absetamin, absetamax))
        gr_gen.GetXaxis().SetTitle("<p_{T}^{Ref}> [GeV]")
        gr_gen.GetYaxis().SetTitle("1/<p_{T}^{L1}/p_{T}^{Ref}>")

    # Save these graphs to file
    outputfile.WriteTObject(gr)
    if do_genjet_plots:
        outputfile.WriteTObject(gr_gen)

    # Fit correction function to response vs pT graph, add params list
    fit_params = []

    if do_correction_fit:
        sub_graph, this_fit = setup_fit(gr, fitfcn, absetamin, absetamax,
                                        outputfile)
        fit_graph, fit_params = fit_correction(sub_graph, this_fit)
        outputfile.WriteTObject(this_fit)  # function by itself
        outputfile.WriteTObject(
            fit_graph)  # has the function stored in it as well

    return fit_params
def main(in_args=sys.argv[1:]):
    print in_args
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--pairs",
                        help="input ROOT file with matched pairs from RunMatcher")

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

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

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

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

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

    print args

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

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

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

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

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

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

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

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


    # Choose eta
    ptBins = binning.pt_bins_stage2

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

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

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

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

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

        pairs_file.Close()

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

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

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

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

                pt_diff_filenames = []

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

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

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

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

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

                pt_diff_filenames = []

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

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

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

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

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

        res_file.Close()

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

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

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

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

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

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

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

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

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

        all_rsp_pt_plot_filenames = []
        all_rsp_ptRef_plot_filenames = []

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

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

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

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

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

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

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

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

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

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

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

        check_file.Close()

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

        calib_file = cu.open_root_file(args.calib)

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

            print eta_min, eta_max

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

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

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

                if eta_min > 2.9:
                    ptBins = binning.pt_bins_stage2_hf

                rsp_plot_filenames = []
                pt_plot_filenames = []

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

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

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

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

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

        calib_file.Close()

    if args.zip:
        print 'Zipping up files'
        zip_filename = os.path.basename(args.zip.split('.')[0])
        make_archive(zip_filename, 'gztar', args.oDir)
예제 #35
0
def draw_horizontal_rsp(max_pt):
    # lines of constant response
    line1 = ROOT.TLine(0, 1, max_pt, 1)
    line1.SetLineStyle(1)
    line1.SetLineWidth(2)
    line1.SetLineColor(ROOT.kMagenta)
    line1.Draw()
    ROOT.SetOwnership(line1, False)


if __name__ == "__main__":
    # L1 Ntuple file
    ntuple_filename = '/hdfs/user/ra12451/L1JEC/CMSSW_7_6_0_pre7/L1JetEnergyCorrections/Stage2_Run260627/Express/run260627_expressNoJEC.root'
    f_ntuple = cu.open_root_file(ntuple_filename)
    reco_tree = cu.get_from_file(f_ntuple, 'l1JetRecoTree/JetRecoTree')

    # Matched pairs file
    pairs_filename = "/hdfs/user/ra12451/L1JEC/CMSSW_7_6_0_pre7/L1JetEnergyCorrections/Stage2_Run260627/pairs/pairs_run260627_expressNoJEC_data_ref10to5000_l10to5000_dr0p4_noCleaning_fixedEF_CSC_HLTvars.root"

    f_pairs = cu.open_root_file(pairs_filename)
    pairs_tree = cu.get_from_file(f_pairs, 'valid')

    plot_dir = '/users/ra12451/L1JEC/CMSSW_7_6_0_pre7/src/L1Trigger/L1JetEnergyCorrections/Run260627/pfCleaning/'
    if not os.path.isdir(plot_dir):
        os.makedirs(plot_dir)

    eta_cut = 'TMath::Abs(eta) < 0.348'
    etaRef_cut = 'TMath::Abs(etaRef) < 0.348'
    LS_cut = (
        "((LS > 91 && LS < 611) || (LS > 613 && LS < 757) || (LS > 760 && LS < 788) || (LS > 791 && LS < 1051) || (LS > 1054 && LS < 1530) || (LS > 1533 && LS < 1845))"
def make_correction_curves(inputfile, outputfile, ptBins_in, absetamin, absetamax,
                           fitfcn, do_genjet_plots, do_correction_fit,
                           pu_min, pu_max, do_burr):
    """
    Do all the relevant hists and fitting, for one eta bin.

    Briefly: make plots of L1 jet pT, and response (= l1/gen) for each genjet pt bin.
    Then find the mean L1 jet pT for the pt bin.
    Then fit a Gaussian to each response histogram, and get the mean.
    Plot 1/fitted mean Vs mean L1 pT.
    Then fit with given function, and return parameters.
    All of these plots are stored in the TFile, outputfile.

    Returns parameters of succeful fit.

    inputfile: TFile. Must contain TTree named "valid", full of pair quantities.

    outputfile: TFile. To store output histograms.

    ptBins_in: list. Edges of pt bins used to divide up correction curve.

    absetamin: float. Lower edge of eta bin, must be >= 0.

    absetamax: float. Upper edge of eta bin, must be > 0.

    fitfcn: TF1. Function to fit for correction curve.

    do_genjet_plots: bool. Whether to make plots for reference jets. Not used
        in calcualtion of correction curve, but handy for debugging.

    do_correction_fit: bool. Whether to actually fit the correction curve.

    pu_min: float. Cut on minimum number of PU vertices.

    pu_max: float. Cut on maximum number of PU vertices.

    do_burr: bool. If True, use Burr fn to fit response histograms.
    The default is to use a Gaussian.
    """

    print "Doing PU range: %g - %g" % (pu_min, pu_max)
    print "Running over pT bins:", ptBins_in

    # Input tree
    tree_raw = cu.get_from_file(inputfile, "valid")

    # Output folders
    output_f = outputfile.mkdir('eta_%g_%g' % (absetamin, absetamax))
    output_f_hists = output_f.mkdir("Histograms")

    # Eta cut string
    eta_cut = ROOT.TCut("TMath::Abs(eta)<%g && TMath::Abs(eta) > %g" % (absetamax, absetamin))

    # PU cut string
    if hasattr(tree_raw, "numPUVertices"):
        pu_cut = ROOT.TCut("numPUVertices >= %g && numPUVertices <= %g" % (pu_min, pu_max))
    else:
        pu_cut = ROOT.TCut("")

    # Total cut
    total_cut = ROOT.TCut(eta_cut)
    total_cut += pu_cut  # need to use += and not && cos TCut all fubar
    print total_cut

    # Draw response (pT^L1/pT^Gen) for all pt bins
    tree_raw.Draw("rsp>>hrsp_eta_%g_%g(50,0,2)" % (absetamin, absetamax), total_cut, "goff")
    hrsp_eta = ROOT.gROOT.FindObject("hrsp_eta_%g_%g" % (absetamin, absetamax))
    hrsp_eta.SetTitle(";response (p_{T}^{L1}/p_{T}^{Ref});")
    output_f_hists.WriteTObject(hrsp_eta)

    nb, pt_min, pt_max = 2048, 0, 1024

    # Draw rsp (pT^L1/pT^Gen) Vs GenJet pT
    tree_raw.Draw("rsp:ptRef>>h2d_rsp_gen(%d,%g,%g,150,0,5)" % (nb, pt_min, pt_max), total_cut, "goff")
    h2d_rsp_gen = ROOT.gROOT.FindObject("h2d_rsp_gen")
    h2d_rsp_gen.SetTitle(";p_{T}^{Ref} [GeV];response (p_{T}^{L1}/p_{T}^{Ref})")
    output_f_hists.WriteTObject(h2d_rsp_gen)

    # Draw rsp (pT^L1/pT^Gen) Vs L1 pT
    tree_raw.Draw("rsp:pt>>h2d_rsp_l1(%d,%g,%g,150,0,5)" % (nb, pt_min, pt_max), total_cut, "goff")
    h2d_rsp_l1 = ROOT.gROOT.FindObject("h2d_rsp_l1")
    h2d_rsp_l1.SetTitle(";p_{T}^{L1} [GeV];response (p_{T}^{L1}/p_{T}^{Ref})")
    output_f_hists.WriteTObject(h2d_rsp_l1)

    # draw pT^L1 Vs pT^Gen
    tree_raw.Draw("pt:ptRef>>h2d_gen_l1(%d,%g,%g,%d,%g,%g)" % (nb, pt_min, pt_max, nb, pt_min, pt_max), total_cut, "goff")
    h2d_gen_l1 = ROOT.gROOT.FindObject("h2d_gen_l1")
    h2d_gen_l1.SetTitle(";p_{T}^{Ref} [GeV];p_{T}^{L1} [GeV]")
    output_f_hists.WriteTObject(h2d_gen_l1)

    # Go through and find histogram bin edges that are closest to the input pt
    # bin edges, and store for future use
    ptBins = []
    bin_indices = []
    for i, ptR in enumerate(ptBins_in[0:-1]):
        bin1 = h2d_rsp_gen.GetXaxis().FindBin(ptR)
        bin2 = h2d_rsp_gen.GetXaxis().FindBin(ptBins_in[i + 1]) - 1
        xlow = h2d_rsp_gen.GetXaxis().GetBinLowEdge(bin1)
        xup = h2d_rsp_gen.GetXaxis().GetBinLowEdge(bin2 + 1)
        bin_indices.append([bin1, bin2])
        ptBins.append(xlow)
    ptBins.append(xup)  # only need this last one

    gr = ROOT.TGraphErrors()  # 1/<rsp> VS ptL1
    gr_gen = ROOT.TGraphErrors()  # 1/<rsp> VS ptGen
    grc = 0

    # Iterate over pT^Gen bins, and for each:
    # - Project 2D hist so we have a plot of response for given pT^Gen range
    # - Fit a Gaussian (if possible) to this resp histogram to get <response>
    # - Plot the L1 pT for given pT^Gen range (remember, for matched pairs)
    # - Get average response, <pT^L1>, from 1D L1 pT hist
    # - Add a new graph point, x=<pT^L1> y=<response> for this pT^Gen bin
    for i, ptR in enumerate(ptBins[0:-1]):

        bin1 = bin_indices[i][0]
        bin2 = bin_indices[i][1]
        # h2d_calib.GetXaxis().FindBin(ptR)
        # h2d_calib.GetXaxis().FindBin(ptBins[i+1])-1
        # print "Binning mis-matches", ptR, ptBins[i+1],
        # h2d_calib.GetXaxis().GetBinLowEdge(bin1),h2d_calib.GetXaxis().GetBinLowEdge(bin2+1)

        xlow = ptR
        xhigh = ptBins[i + 1]

        # Plot of response for given pT Gen bin
        hrsp = h2d_rsp_gen.ProjectionY("Rsp_genpt_%g_%g" % (xlow, xhigh), bin1, bin2)

        # cut on ref jet pt
        pt_cut = ROOT.TCut("ptRef < %g && ptRef > %g " % (xhigh, xlow))
        total_cut = ROOT.TCut(eta_cut)
        total_cut += pu_cut
        total_cut += pt_cut
        print total_cut

        # Plots of pT L1 for given pT Gen bin
        tree_raw.Draw("pt>>hpt(4000, 0, 2000)", total_cut, "goff")
        hpt = ROOT.gROOT.FindObject("hpt")
        hpt.SetName("L1_pt_genpt_%g_%g" % (xlow, xhigh))
        # hpt = h2d_gen_l1.ProjectionX("L1_pt_genpt_%g_%g" % (xlow, xhigh))

        if hrsp.GetEntries() <= 0 or hpt.GetEntries() <= 0:
            print "Skipping as 0 entries"
            continue

        output_f_hists.WriteTObject(hpt)

        # Plots of pT Gen for given pT Gen bin
        if do_genjet_plots:
            tree_raw.Draw("ptRef>>hpt_gen(200)", total_cut, "goff")
            hpt_gen = ROOT.gROOT.FindObject("hpt_gen")
            hpt_gen.SetName("gen_pt_genpt_%g_%g" % (xlow, xhigh))
            output_f_hists.WriteTObject(hpt_gen)

        # Fit to resposne hist to get mean response & error on mean
        if do_burr:
            if (absetamin > 2 and i == 0):
                setup_burr3_higherEta()
            setup_fn = setup_burr3 if absetamin < 2 else setup_burr3_higherEta
            mean, err = do_burr_response_hist_fit(hrsp, setup_fn)
        else:
            mean, err = do_gauss_response_hist_fit(hrsp)

        output_f_hists.WriteTObject(hrsp)

        print "pT Gen: ", ptR, "-", ptBins[i + 1], "<pT L1>:", hpt.GetMean(), \
              "<pT Gen>:", (hpt_gen.GetMean() if do_genjet_plots else "NA"), "<rsp>:", mean

        # Since we're plotting 1/rsp on y axis, so need jacobian
        err = err / (mean**2)

        # add point to response graph vs pt
        # store if new max/min, but only max if pt > pt of previous point
        # max_pt = max(hpt.GetMean(), max_pt) if grc > 0 and hpt.GetMean() > gr.GetX()[grc-1] else max_pt
        # min_pt = min(hpt.GetMean(), min_pt)
        gr.SetPoint(grc, hpt.GetMean(), 1. / mean)
        gr.SetPointError(grc, hpt.GetMeanError(), err)
        if do_genjet_plots:
            gr_gen.SetPoint(grc, hpt_gen.GetMean(), 1. / mean)
            # gr_gen.SetPointError(grc, hpt.GetMeanError(), err)
        grc += 1

    # Label response VS pT graphs
    graph_name = generate_eta_graph_name(absetamin, absetamax)
    gr.SetName(graph_name)
    gr.GetXaxis().SetTitle("<p_{T}^{L1}> [GeV]")
    gr.GetYaxis().SetTitle("1/<p_{T}^{L1}/p_{T}^{Ref}>")

    if do_genjet_plots:
        gr_gen.SetName('gencorr_eta_%g_%g' % (absetamin, absetamax))
        gr_gen.GetXaxis().SetTitle("<p_{T}^{Ref}> [GeV]")
        gr_gen.GetYaxis().SetTitle("1/<p_{T}^{L1}/p_{T}^{Ref}>")

    # Save these graphs to file
    outputfile.WriteTObject(gr)
    if do_genjet_plots:
        outputfile.WriteTObject(gr_gen)

    # Fit correction function to response vs pT graph, add params list
    fit_params = []

    if do_correction_fit:
        sub_graph, this_fit = setup_fit(gr, fitfcn, absetamin, absetamax, outputfile)
        fit_graph, fit_params = fit_correction(sub_graph, this_fit)
        outputfile.WriteTObject(this_fit)  # function by itself
        outputfile.WriteTObject(fit_graph)  # has the function stored in it as well

    return fit_params