Ejemplo n.º 1
0
def draw(hist, data, back, sign, snorm=1, ratio=0, poisson=False, log=False):
    # If not present, create BkgSum
    if not 'BkgSum' in hist.keys():
        hist['BkgSum'] = hist['data_obs'].Clone(
            "BkgSum") if 'data_obs' in hist else hist[back[0]].Clone("BkgSum")
        hist['BkgSum'].Reset("MICES")
        for i, s in enumerate(back):
            hist['BkgSum'].Add(hist[s])
    hist['BkgSum'].SetMarkerStyle(0)

    # Some style
    for i, s in enumerate(data):
        hist[s].SetMarkerStyle(21)
        hist[s].SetMarkerSize(1.25)
    for i, s in enumerate(sign):
        hist[s].SetLineWidth(3)

    for i, s in enumerate(data + back + sign + ['BkgSum']):
        addOverflow(hist[s], False)  # Add overflow

    # Set Poisson error bars
    #if len(data) > 0: hist['data_obs'].SetBinErrorOption(1) # doesn't work

    # Poisson error bars for data
    if poisson:
        alpha = 1 - 0.6827
        hist['data_obs'].SetBinErrorOption(TH1.kPoisson)
        data_graph = TGraphAsymmErrors(hist['data_obs'].GetNbinsX())
        data_graph.SetMarkerStyle(hist['data_obs'].GetMarkerStyle())
        data_graph.SetMarkerSize(hist['data_obs'].GetMarkerSize())
        res_graph = data_graph.Clone()
        for i in range(hist['data_obs'].GetNbinsX()):
            N = hist['data_obs'].GetBinContent(i + 1)
            B = hist['BkgSum'].GetBinContent(i + 1)
            L = 0 if N == 0 else ROOT.Math.gamma_quantile(alpha / 2, N, 1.)
            U = ROOT.Math.gamma_quantile_c(alpha / 2, N + 1, 1)
            data_graph.SetPoint(
                i, hist['data_obs'].GetXaxis().GetBinCenter(i + 1),
                N if not N == 0 else -1.e99)
            data_graph.SetPointError(
                i, hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
                hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2., N - L,
                U - N)
            res_graph.SetPoint(i,
                               hist['data_obs'].GetXaxis().GetBinCenter(i + 1),
                               N / B if not B == 0 and not N == 0 else -1.e99)
            res_graph.SetPointError(
                i, hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
                hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
                (N - L) / B if not B == 0 else -1.e99,
                (U - N) / B if not B == 0 else -1.e99)

    # Create stack
    bkg = THStack("Bkg",
                  ";" + hist['BkgSum'].GetXaxis().GetTitle() + ";Events")
    for i, s in enumerate(back):
        bkg.Add(hist[s])

    # Legend
    n = len([x for x in data + back + ['BkgSum'] + sign if samples[x]['plot']])
    for i, s in enumerate(sign):
        if 'sublabel' in samples[s]: n += 1
        if 'subsublabel' in samples[s]: n += 1
    #leg = TLegend(0.68, 0.9-0.05*n, 0.93, 0.9)
    leg = TLegend(0.68 - 0.05, 0.9 - 0.05 * n, 0.93, 0.9)  #DCMS
    leg.SetTextSize(0.03)  #DCMS
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)  #1001
    leg.SetFillColor(0)
    leg.SetHeader("Signal x-sec=%.0f pb" % (1 * snorm))
    if len(data) > 0:
        leg.AddEntry(hist[data[0]], samples[data[0]]['label'], "ple1")
    for i, s in reversed(list(enumerate(['BkgSum'] + back))):
        leg.AddEntry(hist[s], samples[s]['label'], "f")
    for i, s in enumerate(sign):
        leg.AddEntry(hist[s], samples[s]['label'], "f")

    # --- Display ---
    c1 = TCanvas("c1",
                 hist.values()[-1].GetXaxis().GetTitle(), 1000,
                 800 if ratio else 700)

    if ratio:
        c1.Divide(1, 2)
        setTopPad(c1.GetPad(1), ratio)
        setBotPad(c1.GetPad(2), ratio)
    c1.cd(1)
    c1.GetPad(bool(ratio)).SetTopMargin(0.06)
    c1.GetPad(bool(ratio)).SetRightMargin(0.05)
    c1.GetPad(bool(ratio)).SetTicks(1, 1)
    if log:
        c1.GetPad(bool(ratio)).SetLogy()
        #c1.GetPad(bool(ratio)).SetLogx()

    # Draw
    bkg.Draw("HIST")  # stack
    hist['BkgSum'].Draw("SAME, E2")  # sum of bkg
    if poisson: data_graph.Draw("SAME, PE")
    elif len(data) > 0: hist['data_obs'].Draw("SAME, PE")
    for i, s in enumerate(sign):
        if samples[s]['plot']:
            hist[s].DrawNormalized("SAME, HIST",
                                   hist[s].Integral() * snorm)  # signals

    bkg.GetYaxis().SetTitleOffset(bkg.GetYaxis().GetTitleOffset() * 1.075)

    # Determine range
    if 'data_obs' in hist:
        bkg.SetMaximum((2.5 if log else 1.2) * max(
            bkg.GetMaximum(),
            hist['data_obs'].GetBinContent(hist['data_obs'].GetMaximumBin()) +
            hist['data_obs'].GetBinError(hist['data_obs'].GetMaximumBin())))
        bkg.SetMinimum(
            max(
                min(
                    hist['BkgSum'].GetBinContent(hist['BkgSum'].GetMinimumBin(
                    )), hist['data_obs'].GetMinimum()), 5.e-1) if log else 0.)
    else:
        bkg.SetMaximum(bkg.GetMaximum() * (2.5 if log else 1.2))
        bkg.SetMinimum(5.e-1 if log else 0.)
    if log:
        bkg.GetYaxis().SetNoExponent(bkg.GetMaximum() < 1.e4)
        bkg.GetYaxis().SetMoreLogLabels(True)

    leg.Draw()
    #drawCMS(LUMI, "Preliminary")
    #drawRegion(channel)
    #drawAnalysis("LL")

    setHistStyle(bkg, 1.2 if ratio else 1.1)
    setHistStyle(hist['BkgSum'], 1.2 if ratio else 1.1)

    if ratio:
        c1.cd(2)
        err = hist['BkgSum'].Clone("BkgErr;")
        err.SetTitle("")
        err.GetYaxis().SetTitle("Data / Bkg")
        for i in range(1, err.GetNbinsX() + 1):
            err.SetBinContent(i, 1)
            if hist['BkgSum'].GetBinContent(i) > 0:
                err.SetBinError(
                    i, hist['BkgSum'].GetBinError(i) /
                    hist['BkgSum'].GetBinContent(i))
        setBotStyle(err)
        errLine = err.Clone("errLine")
        errLine.SetLineWidth(2)
        errLine.SetFillStyle(0)
        errLine.SetLineColor(2)  #L#
        errLine.SetLineStyle(2)  #L#
        #err.GetXaxis().SetLabelOffset(err.GetXaxis().GetLabelOffset()*5)
        #err.GetXaxis().SetTitleOffset(err.GetXaxis().GetTitleOffset()*2)
        err.Draw("E2")
        errLine.Draw("SAME, HIST")
        if 'data_obs' in hist:
            res = hist['data_obs'].Clone("Residues")
            for i in range(0, res.GetNbinsX() + 1):
                if hist['BkgSum'].GetBinContent(i) > 0:
                    res.SetBinContent(
                        i,
                        res.GetBinContent(i) / hist['BkgSum'].GetBinContent(i))
                    res.SetBinError(
                        i,
                        res.GetBinError(i) / hist['BkgSum'].GetBinContent(i))
            setBotStyle(res)
            if poisson: res_graph.Draw("SAME, PE0")
            else: res.Draw("SAME, PE0")
            if len(err.GetXaxis().GetBinLabel(
                    1)) == 0:  # Bin labels: not a ordinary plot
                drawRatio(hist['data_obs'], hist['BkgSum'])
                drawKolmogorov(hist['data_obs'], hist['BkgSum'])
        else:
            res = None
    c1.Update()

    # return list of objects created by the draw() function
    return [
        c1, bkg, leg, err if ratio else None, errLine if ratio else None,
        res if ratio else None, data_graph if poisson else None,
        res_graph if poisson else None
    ]
Ejemplo n.º 2
0
def draw(hist,
         channel,
         data,
         back,
         sign,
         snorm=1,
         lumi=-1,
         ratio=0,
         log=False):
    # If not present, create BkgSum
    if not 'BkgSum' in hist.keys():
        hist['BkgSum'] = hist['data_obs'].Clone(
            "BkgSum") if 'data_obs' in hist else hist[back[0]].Clone("BkgSum")
        hist['BkgSum'].Reset("MICES")
        for i, s in enumerate(back):
            hist['BkgSum'].Add(hist[s])
    hist['BkgSum'].SetMarkerStyle(0)

    # Set Poisson error bars
    #if len(data) > 0: hist['data_obs'].SetBinErrorOption(1) # doesn't work

    alpha = 1 - 0.6827
    hist['data_obs'].SetBinErrorOption(TH1.kPoisson)
    data_graph = TGraphAsymmErrors(hist['data_obs'].GetNbinsX())
    data_graph.SetMarkerStyle(hist['data_obs'].GetMarkerStyle())
    data_graph.SetMarkerSize(hist['data_obs'].GetMarkerSize())
    res_graph = data_graph.Clone()
    for i in range(hist['data_obs'].GetNbinsX()):
        N = hist['data_obs'].GetBinContent(i + 1)
        B = hist['BkgSum'].GetBinContent(i + 1)
        L = 0 if N == 0 else ROOT.Math.gamma_quantile(alpha / 2, N, 1.)
        U = ROOT.Math.gamma_quantile_c(alpha / 2, N + 1, 1)
        data_graph.SetPoint(i, hist['data_obs'].GetXaxis().GetBinCenter(i + 1),
                            N if not N == 0 else -1.e99)
        data_graph.SetPointError(
            i, hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
            hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2., N - L, U - N)
        res_graph.SetPoint(i, hist['data_obs'].GetXaxis().GetBinCenter(i + 1),
                           N / B if not B == 0 and not N == 0 else -1.e99)
        res_graph.SetPointError(
            i, hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
            hist['data_obs'].GetXaxis().GetBinWidth(i + 1) / 2.,
            (N - L) / B if not B == 0 else -1.e99,
            (U - N) / B if not B == 0 else -1.e99)

    # Create stack
    bkg = THStack("Bkg",
                  ";" + hist['BkgSum'].GetXaxis().GetTitle() + ";Events")
    for i, s in enumerate(back):
        bkg.Add(hist[s])

    # Legend
    n = len([x for x in data + back + ['BkgSum'] + sign if sample[x]['plot']])
    leg = TLegend(0.7, 0.9 - 0.05 * n, 0.95, 0.9)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)  #1001
    leg.SetFillColor(0)
    if len(data) > 0:
        leg.AddEntry(hist[data[0]], sample[data[0]]['label'], "pl")
    for i, s in reversed(list(enumerate(['BkgSum'] + back))):
        leg.AddEntry(hist[s], sample[s]['label'], "f")
    for i, s in enumerate(sign):
        if sample[s]['plot']:
            leg.AddEntry(hist[s],
                         sample[s]['label'].replace("m_{#Chi}=1 GeV",
                                                    ""), "fl")

    # --- Display ---
    c1 = TCanvas("c1",
                 hist.values()[0].GetXaxis().GetTitle(), 800,
                 800 if ratio else 600)

    if ratio:
        c1.Divide(1, 2)
        setTopPad(c1.GetPad(1), ratio)
        setBotPad(c1.GetPad(2), ratio)
    c1.cd(1)
    c1.GetPad(bool(ratio)).SetTopMargin(0.06)
    c1.GetPad(bool(ratio)).SetRightMargin(0.05)
    c1.GetPad(bool(ratio)).SetTicks(1, 1)
    if log:
        c1.GetPad(bool(ratio)).SetLogy()

    # Draw
    bkg.Draw("HIST")  # stack
    hist['BkgSum'].Draw("SAME, E2")  # sum of bkg
    #if len(data) > 0: hist['data_obs'].Draw("SAME, PE") # data
    data_graph.Draw("SAME, PE")
    for i, s in enumerate(sign):
        if sample[s]['plot']:
            hist[s].DrawNormalized("SAME, HIST",
                                   hist[s].Integral() * snorm)  # signals

    bkg.GetYaxis().SetTitleOffset(bkg.GetYaxis().GetTitleOffset() * 1.075)
    bkg.SetMaximum((2. if log else 1.2) * max(
        bkg.GetMaximum(),
        hist['data_obs'].GetBinContent(hist['data_obs'].GetMaximumBin()) +
        hist['data_obs'].GetBinError(hist['data_obs'].GetMaximumBin())))
    bkg.SetMinimum(
        max(
            min(hist['BkgSum'].GetBinContent(hist['BkgSum'].GetMinimumBin(
            )), hist['data_obs'].GetMinimum()), 5.e-1) if log else 0.)
    if log:
        bkg.GetYaxis().SetNoExponent(bkg.GetMaximum() < 1.e4)
        bkg.GetYaxis().SetMoreLogLabels(True)

    #if log: bkg.SetMinimum(1)
    leg.Draw()
    drawCMS(lumi, "Preliminary")
    drawRegion(channel)
    drawAnalysis(channel)

    #if nm1 and not cutValue is None: drawCut(cutValue, bkg.GetMinimum(), bkg.GetMaximum()) #FIXME
    if len(sign) > 0:
        if channel.startswith('X') and len(sign) > 0:
            drawNorm(0.9 - 0.04 * (n + 1),
                     "#sigma(X) #times B(X #rightarrow Vh) = %.1f pb" % snorm)
            #elif "SR" in channel: drawNorm(0.9-0.04*(n+1), "DM+bb/tt, scaled by %.0f" % snorm, "m_{#chi}=1 GeV, scalar mediator")
        elif "SR" in channel:
            drawNorm(0.9 - 0.04 * (n + 1), "DM+bb/tt, m_{#chi}=1 GeV",
                     "scalar mediator")

    setHistStyle(bkg, 1.2 if ratio else 1.1)
    setHistStyle(hist['BkgSum'], 1.2 if ratio else 1.1)

    if ratio:
        c1.cd(2)
        err = hist['BkgSum'].Clone("BkgErr;")
        err.SetTitle("")
        err.GetYaxis().SetTitle("Data / Bkg")
        for i in range(1, err.GetNbinsX() + 1):
            err.SetBinContent(i, 1)
            if hist['BkgSum'].GetBinContent(i) > 0:
                err.SetBinError(
                    i, hist['BkgSum'].GetBinError(i) /
                    hist['BkgSum'].GetBinContent(i))
        setBotStyle(err)
        errLine = err.Clone("errLine")
        errLine.SetLineWidth(1)
        errLine.SetFillStyle(0)
        res = hist['data_obs'].Clone("Residues")
        for i in range(0, res.GetNbinsX() + 1):
            if hist['BkgSum'].GetBinContent(i) > 0:
                res.SetBinContent(
                    i,
                    res.GetBinContent(i) / hist['BkgSum'].GetBinContent(i))
                res.SetBinError(
                    i,
                    res.GetBinError(i) / hist['BkgSum'].GetBinContent(i))
        setBotStyle(res)
        #err.GetXaxis().SetLabelOffset(err.GetXaxis().GetLabelOffset()*5)
        #err.GetXaxis().SetTitleOffset(err.GetXaxis().GetTitleOffset()*2)
        err.Draw("E2")
        errLine.Draw("SAME, HIST")
        if len(data) > 0:
            #res.Draw("SAME, PE0")
            res_graph.Draw("SAME, PE0")


#            if len(err.GetXaxis().GetBinLabel(1))==0: # Bin labels: not a ordinary plot
#                drawRatio(hist['data_obs'], hist['BkgSum'])
#                drawKolmogorov(hist['data_obs'], hist['BkgSum'])

    c1.Update()

    # return list of objects created by the draw() function
    return [c1, bkg, leg, err, errLine, res, data_graph, res_graph]
Ejemplo n.º 3
0
    eyh_c = array('f')

    x_c = np.array(LC_dict['tpr'])
    y_c = np.array(LC_dict['fpr'])
    exl_c = np.array(LC_dict['tpr_e_l'])
    eyl_c = np.array(LC_dict['fpr_e_l'])
    exh_c = np.array(LC_dict['tpr_e_h'])
    eyh_c = np.array(LC_dict['fpr_e_h'])

    # somehow if you call one of the variables before the Draw() method the graph won't work properly
    gr = GAE(n_bins, x, y, exl, exh, eyl, eyh)
    gr_s = GAE(n_bins, x, y, exl, exh, eyl, eyh)

    gr_LC = GAE(1, x_c, y_c, exl_c, exh_c, eyl_c, eyh_c)

    gr_c = gr.Clone()
    gr_sc = gr_s.Clone()

    gr.SetTitle('ROC(zoomed in)')
    #gr.SetMarkerColor(8)
    #gr.SetMarkerStyle(21)
    gr.SetFillColor(632 - 9)
    gr_s.SetTitle('ROC')
    gr_s.SetFillColor(632 - 9)
    gr_sc.SetLineColor(4)

    c1.cd(1)
    gr.GetXaxis().SetRangeUser(0, 0.5)
    gr.GetYaxis().SetRangeUser(0.00001, 0.01)
    gr_c.GetXaxis().SetRangeUser(0, 0.5)
    gr_c.GetXaxis().SetRangeUser(0.00001, 0.01)
def plotDataOverMCEff(hist_mc_tight,
                      hist_mc_loose,
                      hist_data_tight,
                      hist_data_loose,
                      plot_name='fakerate.pdf'):

    g = TGraphAsymmErrors(hist_mc_tight)
    g.Divide(hist_mc_tight, hist_mc_loose)
    g.GetYaxis().SetTitle('Fake rate')
    g.GetXaxis().SetTitle(hist_mc_tight.GetXaxis().GetTitle())
    g.GetYaxis().SetTitleOffset(1.2)
    g.GetYaxis().SetTitleOffset(1.3)

    g.SetLineColor(2)
    g.SetMarkerColor(2)

    g_data = TGraphAsymmErrors(hist_data_tight)
    g_data.Divide(hist_data_tight, hist_data_loose)
    g_data.GetYaxis().SetTitle('Fake rate')
    g_data.GetXaxis().SetTitle(hist_data_tight.GetXaxis().GetTitle())
    g_data.GetYaxis().SetTitleOffset(1.2)
    g_data.GetYaxis().SetTitleOffset(1.3)
    g_data.SetMarkerColor(1)

    g_vals = g.GetY()
    g_data_vals = g_data.GetY()

    g_ratio = g_data.Clone('ratio')

    for i in xrange(g_data.GetN()):
        ratio = g_data_vals[i] / g_vals[i] if g_vals[i] else 0.
        g_ratio.SetPoint(i, g.GetX()[i], ratio)

        rel_y_low = math.sqrt((g_data.GetErrorYlow(i) / g_data_vals[i])**2 + (
            g.GetErrorYlow(i) /
            g_vals[i])**2) if g_data_vals[i] > 0. and g_vals[i] > 0. else 0.

        g_ratio.SetPointEYlow(i, rel_y_low * ratio)

        rel_y_high = math.sqrt(
            (g_data.GetErrorYhigh(i) / g_data_vals[i])**2 +
            (g.GetErrorYhigh(i) /
             g_vals[i])**2) if g_data_vals[i] > 0. and g_vals[i] > 0. else 0.

        g_ratio.SetPointEYhigh(i, rel_y_high * ratio)

    # Gymnastics to get same label sizes etc in ratio and main plot
    ytp_ratio = 2.
    xtp_ratio = 2.

    # hr.GetYaxis().SetNdivisions(4)

    g_ratio.GetYaxis().SetTitleSize(g.GetYaxis().GetTitleSize() * xtp_ratio)
    g_ratio.GetXaxis().SetTitleSize(g.GetXaxis().GetTitleSize() * ytp_ratio)

    g_ratio.GetYaxis().SetTitleOffset(g.GetYaxis().GetTitleOffset() /
                                      xtp_ratio)
    g_ratio.GetXaxis().SetTitleOffset(
        g.GetXaxis().GetTitleOffset())  # / ytp_ratio)

    g_ratio.GetYaxis().SetLabelSize(g.GetYaxis().GetLabelSize() * xtp_ratio)
    g_ratio.GetXaxis().SetLabelSize(g.GetXaxis().GetLabelSize() * ytp_ratio)

    g_data.GetXaxis().SetLabelColor(0)
    g_data.GetXaxis().SetLabelSize(0)
    g.GetXaxis().SetLabelColor(0)
    g.GetXaxis().SetLabelSize(0)

    g_ratio.GetXaxis().SetTitle(g.GetXaxis().GetTitle())

    # maxy = 1.1 * min(g.GetMaximum(), g_data.GetMaximum(), 0.2)
    g.GetYaxis().SetRangeUser(0.001, 0.2)

    cv, pad, padr = HistDrawer.buildCanvas()

    pad.cd()

    g.Draw('AP')
    g_data.Draw('P')

    legend = TLegend(0.23, 0.73, 0.43, 0.91)
    legend.SetFillColor(0)
    legend.SetFillStyle(0)
    legend.SetLineColor(0)
    legend.SetLineWidth(0)

    legend.AddEntry(g.GetName(), 'MC', 'lep')
    legend.AddEntry(g_data.GetName(), 'Observed', 'lep')

    legend.Draw()

    padr.cd()
    g_ratio.GetYaxis().SetRangeUser(0.51, 1.49)
    g_ratio.GetYaxis().SetTitle('Obs/MC')
    g_ratio.Draw('AP')

    drawRatioLines(g_ratio)

    cv.Print(plot_name)
Ejemplo n.º 5
0
def draw(hist, data, back, sign, snorm=1, ratio=0, poisson=True, log=False):

    groupList = plt.cfg.getGroupPlot()

    # If not present, create BkgSum
    #if not 'BkgSum' in hist.keys():
    #    hist['BkgSum'] = hist['DATA'].Clone("BkgSum") if 'DATA' in hist else hist[back[0]].Clone("BkgSum")
    #    hist['BkgSum'].Reset("MICES")
    #    for i, s in enumerate(back): hist['BkgSum'].Add(hist[s].GetPtr())
    hist['BkgSum'].SetMarkerStyle(0)

    # Some style
    for i, s in enumerate(data):
        hist[s].SetMarkerStyle(20)
        hist[s].SetMarkerSize(1.25)
    for i, s in enumerate(sign):
        hist[s].SetLineWidth(3)

    for i, s in enumerate(data + back + sign + ['BkgSum']):
        addOverflow(hist[s], False)  # Add overflow

    # Set Poisson error bars
    #if len(data) > 0: hist['data_obs'].SetBinErrorOption(1) # doesn't work

    # Poisson error bars for data
    if poisson:
        alpha = 1 - 0.6827
        hist['DATA'].SetBinErrorOption(TH1.kPoisson)
        data_graph = TGraphAsymmErrors(hist['DATA'].GetNbinsX())
        data_graph.SetMarkerStyle(hist['DATA'].GetMarkerStyle())
        data_graph.SetMarkerSize(hist['DATA'].GetMarkerSize())
        res_graph = data_graph.Clone()
        for i in range(hist['DATA'].GetNbinsX()):
            N = hist['DATA'].GetBinContent(i + 1)
            B = hist['BkgSum'].GetBinContent(i + 1)
            L = 0 if N == 0 else ROOT.Math.gamma_quantile(alpha / 2, N, 1.)
            U = ROOT.Math.gamma_quantile_c(alpha / 2, N + 1, 1)
            data_graph.SetPoint(i, hist['DATA'].GetXaxis().GetBinCenter(i + 1),
                                N if not N == 0 else -1.e99)
            data_graph.SetPointError(
                i, hist['DATA'].GetXaxis().GetBinWidth(i + 1) / 2.,
                hist['DATA'].GetXaxis().GetBinWidth(i + 1) / 2., N - L, U - N)
            res_graph.SetPoint(i, hist['DATA'].GetXaxis().GetBinCenter(i + 1),
                               N / B if not B == 0 and not N == 0 else -1.e99)
            res_graph.SetPointError(
                i, hist['DATA'].GetXaxis().GetBinWidth(i + 1) / 2.,
                hist['DATA'].GetXaxis().GetBinWidth(i + 1) / 2.,
                (N - L) / B if not B == 0 else -1.e99,
                (U - N) / B if not B == 0 else -1.e99)

    # Create stack
    #bkg = THStack("Bkg", ";"+hist['BkgSum'].GetXaxis().GetTitle()+";Events")
    bkg = THStack(
        "Bkg", ";" + hist['BkgSum'].GetXaxis().GetTitle() + ";" +
        hist['BkgSum'].GetYaxis().GetTitle())

    for i, s in enumerate(back):
        bkg.Add(hist[s])

    # Legend
    n = len(
        [x for x in data + back + ['BkgSum'] + sign if groupList[x]['plot']])
    for i, s in enumerate(sign):
        if 'sublabel' in groupList[s]: n += 1
        if 'subsublabel' in groupList[s]: n += 1
    leg = TLegend(0.7, 0.9 - 0.05 * n, 0.95, 0.9)
    #leg.SetNColumns(3)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)  #1001
    leg.SetFillColor(0)
    if len(data) > 0:
        #leg.AddEntry( hist[data[0]] , groupList[data[0]]['label'], "pl")
        leg.AddEntry(
            hist[data[0]], '%s [%.1f]' %
            (groupList[data[0]]['label'], hist[data[0]].Integral()), "pl")
    for i, s in reversed(list(enumerate(['BkgSum'] + back))):
        leg.AddEntry(hist[s] if s == 'BkgSum' else hist[s],
                     '%s [%.1f]' % (groupList[s]['label'], hist[s].Integral()),
                     "f")
    for i, s in enumerate(sign):
        if groupList[s]['plot']:
            #leg.AddEntry( hist[s] if s=='BkgSum' else hist[s] , groupList[s]['label'], "fl")
            leg.AddEntry(
                hist[s] if s == 'BkgSum' else hist[s],
                '%s [%.1f]' % (groupList[s]['label'], hist[s].Integral()),
                "fl")

            #print samples[s]
            if 'sublabel' in groupList[s]:
                leg.AddEntry(
                    hist[s] if s == 'BkgSum' else hist[s],
                    groupList[s]['sublabel'].replace("m_{#Chi}=1 GeV", ""), "")
            if 'subsublabel' in groupList[s]:
                leg.AddEntry(
                    hist[s] if s == 'BkgSum' else hist[s],
                    groupList[s]['subsublabel'].replace("m_{#Chi}=1 GeV",
                                                        ""), "")

    # --- Display ---
    c1 = TCanvas("c1",
                 hist.values()[-1].GetXaxis().GetTitle(), 800,
                 800 if ratio else 600)

    if ratio:
        c1.Divide(1, 2)
        setTopPad(c1.GetPad(1), ratio)
        setBotPad(c1.GetPad(2), ratio)
    c1.cd(1)
    c1.GetPad(bool(ratio)).SetTopMargin(0.06)
    c1.GetPad(bool(ratio)).SetRightMargin(0.05)
    c1.GetPad(bool(ratio)).SetTicks(1, 1)
    if log:
        c1.GetPad(bool(ratio)).SetLogy()

    # Draw
    bkg.Draw("HIST")  # stack
    hist['BkgSum'].Draw("SAME, E2")  # sum of bkg
    if poisson: data_graph.Draw("SAME, PE")
    elif len(data) > 0: hist['DATA'].Draw("SAME, PE")
    for i, s in enumerate(sign):
        if groupList[s]['plot']:
            hist[s].DrawNormalized("SAME, HIST",
                                   hist[s].Integral() * snorm)  # signals

    #bkg.GetYaxis().SetTitleOffset(bkg.GetYaxis().GetTitleOffset()*1.075) #1.075

    if 'DATA' in hist:
        #bkg.SetMaximum((3.0 if log else 1.5)*max(bkg.GetMaximum(), hist['DATA'].GetBinContent(hist['DATA'].GetMaximumBin())+hist['DATA'].GetBinError(hist['DATA'].GetMaximumBin())))
        bkg.SetMaximum((25.0 if log else 2.0) * max(
            bkg.GetMaximum(),
            hist['DATA'].GetBinContent(hist['DATA'].GetMaximumBin()) +
            hist['DATA'].GetBinError(hist['DATA'].GetMaximumBin())))
        bkg.SetMinimum(
            max(
                min(
                    hist['BkgSum'].GetBinContent(hist['BkgSum'].GetMinimumBin(
                    )), hist['DATA'].GetMinimum()), 5.e-1) if log else 0.)
    else:
        bkg.SetMaximum(bkg.GetMaximum() * (3.0 if log else 1.5))  #2.5 ; 1.2
        bkg.SetMinimum(5.e-1 if log else 0.)
    if not log:
        #bkg.GetYaxis().SetNoExponent(1)
        bkg.GetYaxis().SetNoExponent(bkg.GetMaximum() < 1.e4)
    #    bkg.GetYaxis().SetMoreLogLabels(True)

    #set range on stack
    bkg.SetMinimum(5.e-1 if log else 1.0)

    leg.Draw()

    setHistStyle(bkg, 1.2 if ratio else 1.1)
    setHistStyle(hist['BkgSum'], 1.2 if ratio else 1.1)

    if ratio:
        #err.GetXaxis().SetTitleOffset(err.GetXaxis().GetTitleOffset()*1)
        c1.cd(2)
        err = hist['BkgSum'].Clone("BkgErr;")
        err.SetTitle("")
        err.GetYaxis().SetTitle("Data / Bkg")
        for i in range(1, err.GetNbinsX() + 1):
            err.SetBinContent(i, 1)
            if hist['BkgSum'].GetBinContent(i) > 0:
                err.SetBinError(
                    i, hist['BkgSum'].GetBinError(i) /
                    hist['BkgSum'].GetBinContent(i))
        setBotStyle(err)
        errLine = err.Clone("errLine")
        errLine.SetLineWidth(1)
        errLine.SetFillStyle(0)
        errLine.SetLineColor(1)
        #err.GetXaxis().SetLabelOffset(err.GetXaxis().GetLabelOffset()*1)
        #err.GetXaxis().SetTitleOffset(err.GetXaxis().GetTitleOffset()*1)
        #err.GetYaxis().SetTitleOffset(err.GetYaxis().GetTitleOffset()*1)
        err.Draw("E2")
        errLine.Draw("SAME, HIST")
        if 'DATA' in hist:
            res = hist['DATA'].Clone("Residues")
            for i in range(0, res.GetNbinsX() + 1):
                if hist['BkgSum'].GetBinContent(i) > 0:
                    res.SetBinContent(
                        i,
                        res.GetBinContent(i) / hist['BkgSum'].GetBinContent(i))
                    res.SetBinError(
                        i,
                        res.GetBinError(i) / hist['BkgSum'].GetBinContent(i))
            setBotStyle(res)
            if poisson: res_graph.Draw("SAME, PE0")
            else: res.Draw("SAME, PE0")
            if len(err.GetXaxis().GetBinLabel(
                    1)) == 0:  # Bin labels: not a ordinary plot
                drawRatio(hist['DATA'], hist['BkgSum'])
                drawKolmogorov(hist['DATA'], hist['BkgSum'])
                if len(sign) != 0: drawSB(hist['BkgSum'], hist[sign[0]])
                #drawRelativeYield( hist['DATA'] , hist['BkgSum'] )
        else:
            res = None
    c1.Update()

    # return list of objects created by the draw() function
    if not ratio:
        return [
            c1, bkg, leg, data_graph if poisson else None,
            res_graph if poisson else None
        ]
    else:
        return [
            c1, bkg, leg, err, errLine, res, data_graph if poisson else None,
            res_graph if poisson else None
        ]
def dependencies(source, path, selection, plots, runRange, isMC, backgrounds,
                 cmsExtra):

    hCanvas = TCanvas("hCanvas", "Distribution", 800, 800)

    plotPad = ROOT.TPad("plotPad", "plotPad", 0, 0, 1, 1)
    setTDRStyle()
    plotPad.UseCurrentStyle()
    plotPad.Draw()
    plotPad.cd()

    legend = TLegend(0.575, 0.16, 0.9, 0.4)
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

    legendHist1 = TH1F()
    legendHist2 = TH1F()
    legendHist3 = TH1F()

    legendHist1.SetMarkerColor(ROOT.kBlack)
    legendHist2.SetMarkerColor(ROOT.kRed)
    legendHist3.SetMarkerColor(ROOT.kBlue)

    legend.AddEntry(legendHist1, "ee", "p")
    legend.AddEntry(legendHist2, "#mu#mu", "p")
    legend.AddEntry(legendHist3, "e#mu", "p")

    latex = ROOT.TLatex()
    latex.SetTextFont(42)
    latex.SetTextAlign(31)
    latex.SetTextSize(0.04)
    latex.SetNDC(True)
    latexCMS = ROOT.TLatex()
    latexCMS.SetTextFont(61)
    #latexCMS.SetTextAlign(31)
    latexCMS.SetTextSize(0.06)
    latexCMS.SetNDC(True)
    latexCMSExtra = ROOT.TLatex()
    latexCMSExtra.SetTextFont(52)
    #latexCMSExtra.SetTextAlign(31)
    latexCMSExtra.SetTextSize(0.045)
    latexCMSExtra.SetNDC(True)
    latexSelection = ROOT.TLatex()
    #~ latexSelection.SetTextFont(42)
    latexSelection.SetTextSize(0.03)
    latexSelection.SetNDC(True)

    intlumi = ROOT.TLatex()
    intlumi.SetTextAlign(12)
    intlumi.SetTextSize(0.03)
    intlumi.SetNDC(True)
    if isMC:
        if os.path.isfile("shelves/triggerEff_%s_%s_%s_MC.pkl" %
                          (selection.name, source, runRange.label)):
            centralVals = pickle.load(
                open(
                    "shelves/triggerEff_%s_%s_%s_MC.pkl" %
                    (selection.name, source, runRange.label), "rb"))
        else:
            centralVals = centralValues(source, path, selection, runRange,
                                        isMC, backgrounds)
        if os.path.isfile("shelves/triggerEff_%s_%s_%s.pkl" %
                          (selection.name, source, runRange.label)):
            centralValsData = pickle.load(
                open(
                    "shelves/triggerEff_%s_%s_%s.pkl" %
                    (selection.name, source, runRange.label), "rb"))
        else:
            centralValsData = centralValues(source, path, selection, runRange,
                                            False, backgrounds)
    else:
        if os.path.isfile("shelves/triggerEff_%s_%s_%s.pkl" %
                          (selection.name, source, runRange.label)):
            centralVals = pickle.load(
                open(
                    "shelves/triggerEff_%s_%s_%s.pkl" %
                    (selection.name, source, runRange.label), "rb"))
        else:
            centralVals = centralValues(source, path, selection, runRange,
                                        isMC, backgrounds)

    for name in plots:
        if isMC:
            plotData = getPlot(name)
            plotData.addRegion(selection)
            #~ plot.cleanCuts()
            plotData.cuts = plotData.cuts % runRange.runCut
            plotData.cuts = plotData.cuts.replace("mll", "p4.M()")
            plotData.cuts = plotData.cuts.replace("pt > 25", "p4.Pt() > 25")
            plotData.cuts = plotData.cuts.replace("triggerSummary > 0 &&", "")
            plotData.variable = plotData.variable.replace("mll", "p4.M()")
            if plotData.variable == "pt":
                plotData.variable = plotData.variable.replace("pt", "p4.Pt()")

            name = name + "MC"
        plot = getPlot(name)
        plot.addRegion(selection)
        #~ plot.cleanCuts()
        plot.cuts = plot.cuts % runRange.runCut
        plot.cuts = plot.cuts.replace("mll", "p4.M()")
        plot.cuts = plot.cuts.replace("pt > 25", "p4.Pt() > 25")
        plot.cuts = plot.cuts.replace("triggerSummary > 0 &&", "")
        plot.variable = plot.variable.replace("mll", "p4.M()")
        if plot.variable == "pt":
            plot.variable = plot.variable.replace("pt", "p4.Pt()")

        #~ if  "Forward" in selection.name:
        #~ plot.nBins = int(plot.nBins/2)
        denominators, nominators = getHistograms(path, plot, runRange, isMC,
                                                 backgrounds, source)

        effEE = TGraphAsymmErrors(nominators["EE"], denominators["EE"], "cp")
        effMuMu = TGraphAsymmErrors(nominators["MuMu"], denominators["MuMu"],
                                    "cp")

        denominatorHistoOF = denominators["MuEG"].Clone()
        nominatorHistoOF = nominators["MuEG"].Clone()
        effOF = TGraphAsymmErrors(nominatorHistoOF, denominatorHistoOF, "cp")

        if isMC:
            denominatorsData, nominatorsData = getHistograms(
                locations.triggerDataSetPath, plotData, runRange, False,
                backgrounds, source)

            effEEData = TGraphAsymmErrors(nominatorsData["EE"],
                                          denominatorsData["EE"], "cp")
            effMuMuData = TGraphAsymmErrors(nominatorsData["MuMu"],
                                            denominatorsData["MuMu"], "cp")

            denominatorHistoOFData = denominatorsData["MuEG"].Clone()
            nominatorHistoOFData = nominatorsData["MuEG"].Clone()
            effOFData = TGraphAsymmErrors(nominatorHistoOFData,
                                          denominatorHistoOFData, "cp")

        effEE.SetMarkerColor(ROOT.kBlack)
        effMuMu.SetMarkerColor(ROOT.kRed)
        effOF.SetMarkerColor(ROOT.kBlue)
        effEE.SetLineColor(ROOT.kBlack)
        effMuMu.SetLineColor(ROOT.kRed)
        effOF.SetLineColor(ROOT.kBlue)
        effEE.SetMarkerStyle(20)
        effMuMu.SetMarkerStyle(21)
        effOF.SetMarkerStyle(22)

        plotPad.DrawFrame(plot.firstBin, 0.5, plot.lastBin, 1.2,
                          "; %s ; Efficiency" % (plot.xaxis))

        selectionLabel = selection.latex

        if plot.variable == "nJets":
            selectionLabel = selectionLabel.replace(
                "#notin (n_{jets}#geq 2 & p_{T}^{miss} > 100 GeV)",
                "p_{T}^{miss} < 100 GeV")
        if plot.variable == "met":
            selectionLabel = selectionLabel.replace(
                "#notin (n_{jets}#geq 2 & p_{T}^{miss} > 100 GeV)",
                "n_{jets}=1")

        legend.Clear()

        legend.AddEntry(effEE, "ee", "p")
        legend.AddEntry(effMuMu, "#mu#mu", "p")
        legend.AddEntry(effOF, "e#mu", "p")

        effEE.Draw("samep")
        effMuMu.Draw("samep")
        effOF.Draw("samep")

        latex.DrawLatex(0.95, 0.96, "%s fb^{-1} (13 TeV)" % runRange.printval)

        latexCMS.DrawLatex(0.19, 0.88, "CMS")
        if "Simulation" in cmsExtra:
            yLabelPos = 0.81
        else:
            yLabelPos = 0.84
        #~ yLabelPos = 0.84

        latexCMSExtra.DrawLatex(0.19, yLabelPos, "%s" % (cmsExtra))
        latexSelection.DrawLatex(0.20, 0.25, selectionLabel)

        legend.Draw("same")
        if isMC:
            hCanvas.Print("fig/Triggereff_%s_%s_%s_%s_%s_MC.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))
        else:
            hCanvas.Print("fig/Triggereff_%s_%s_%s_%s_%s.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))

        denominatorHistoSF = denominators["EE"].Clone()
        denominatorHistoOF = denominators["MuEG"].Clone()
        denominatorHistoSF.Add(denominators["MuMu"].Clone())

        nominatorHistoSF = nominators["EE"].Clone()
        nominatorHistoSFNoTrack = nominators["EE"].Clone()

        nominatorHistoSF.Add(nominators["MuMu"].Clone())

        nominatorHistoOF = nominators["MuEG"].Clone()

        effSF = TGraphAsymmErrors(nominatorHistoSF, denominatorHistoSF, "cp")
        effOF = TGraphAsymmErrors(nominatorHistoOF, denominatorHistoOF, "cp")

        effSF.SetMarkerColor(ROOT.kBlack)
        effOF.SetMarkerColor(ROOT.kBlue)
        effSF.SetLineColor(ROOT.kBlack)
        effOF.SetLineColor(ROOT.kBlue)
        effSF.SetMarkerStyle(20)
        effOF.SetMarkerStyle(22)

        effSFNoFit = effSF.Clone()
        effOFNoFit = effSF.Clone()

        plotPad.DrawFrame(plot.firstBin, 0.5, plot.lastBin, 1.2,
                          "; %s ; Efficiency" % (plot.xaxis))

        legend.Clear()

        legend.AddEntry(effSF, "ee and #mu#mu", "p")
        legend.AddEntry(effOF, "e#mu", "p")

        effSF.Draw("samep")
        effOF.Draw("samep")

        latex.DrawLatex(0.95, 0.96, "%s fb^{-1} (13 TeV)" % runRange.printval)

        latexCMS.DrawLatex(0.19, 0.88, "CMS")
        if "Simulation" in cmsExtra:
            yLabelPos = 0.81
        else:
            yLabelPos = 0.84
        #~ yLabelPos = 0.84

        latexCMSExtra.DrawLatex(0.19, yLabelPos, "%s" % (cmsExtra))
        latexSelection.DrawLatex(0.20, 0.25, selectionLabel)
        legend.Draw("same")
        if isMC:
            hCanvas.Print("fig/Triggereff_SFvsOF_%s_%s_%s_%s_%s_MC.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))
        else:
            hCanvas.Print("fig/Triggereff_SFvsOF_%s_%s_%s_%s_%s.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))

        if source == "SingleLepton":
            plotPad.DrawFrame(plot.firstBin, .6, plot.lastBin, 1.4,
                              "; %s ; R_{T}" % (plot.xaxis))
        else:
            plotPad.DrawFrame(plot.firstBin, .6, plot.lastBin, 1.4,
                              "; %s ; R_{T}" % (plot.xaxis))

        effSFvsOF = efficiencyRatioGeometricMean(effEE, effMuMu, effOF, source)
        if isMC:
            effSFvsOFData = efficiencyRatioGeometricMean(
                effEEData, effMuMuData, effOFData, source)
            effSFvsOF.SetLineColor(ROOT.kGreen - 2)
            effSFvsOF.SetMarkerColor(ROOT.kGreen - 2)
            effSFvsOF.SetMarkerStyle(21)

        x = array("f", [plot.firstBin, plot.lastBin])
        if isMC:
            yData = array("f", [
                float(centralValsData[runRange.label]["RT"]),
                float(centralValsData[runRange.label]["RT"])
            ])
            sfLineData = ROOT.TF1("sfLine",
                                  str(centralValsData[runRange.label]["RT"]),
                                  plot.firstBin, plot.lastBin)
        y = array("f", [
            float(centralVals[runRange.label]["RT"]),
            float(centralVals[runRange.label]["RT"])
        ])
        sfLine = ROOT.TF1("sfLine", str(centralVals[runRange.label]["RT"]),
                          plot.firstBin, plot.lastBin)
        if isMC:
            eyData = array("f", [
                float(centralValsData[runRange.label]["RTErrSyst"]),
                float(centralValsData[runRange.label]["RTErrSyst"])
            ])
            eyData = array("f", [
                float(centralVals[runRange.label]["RTErrSyst"]),
                float(centralVals[runRange.label]["RTErrSyst"])
            ])
            exData = array("f", [0., 0.])

            ge = ROOT.TGraphErrors(2, x, yData, exData, eyData)
            ge.SetFillColor(ROOT.kOrange - 9)
            ge.SetFillStyle(1001)
            ge.SetLineColor(ROOT.kWhite)
            ge.Draw("SAME 3")
        else:
            ey = array("f", [
                float(centralVals[runRange.label]["RTErrSyst"]),
                float(centralVals[runRange.label]["RTErrSyst"])
            ])
            ex = array("f", [0., 0.])

            ge = ROOT.TGraphErrors(2, x, y, ex, ey)
            ge.SetFillColor(ROOT.kOrange - 9)
            ge.SetFillStyle(1001)
            ge.SetLineColor(ROOT.kWhite)
            ge.Draw("SAME 3")

        effSFvsOF.Draw("samep")
        if isMC:
            effSFvsOFData.Draw("samep")

        sfLine.SetLineColor(ROOT.kGreen - 2)
        sfLine.SetLineWidth(3)
        sfLine.SetLineStyle(2)
        sfLine.Draw("SAME")

        if isMC:
            sfLineData.SetLineColor(ROOT.kBlack)
            sfLineData.SetLineWidth(3)
            sfLineData.SetLineStyle(2)
            sfLineData.Draw("SAME")

        latex.DrawLatex(0.95, 0.96, "%s fb^{-1} (13 TeV)" % runRange.printval)

        latexCMS.DrawLatex(0.19, 0.88, "CMS")
        if "Simulation" in cmsExtra:
            #~ cmsExtra = "Preliminary"
            cmsExtraLabel = cmsExtra.replace(
                "#splitline{Private Work}{Simulation}", "Private Work")
            #~ yLabelPos = 0.84
        else:
            #~ yLabelPos = 0.84
            cmsExtraLabel = cmsExtra
        yLabelPos = 0.84

        latexCMSExtra.DrawLatex(0.19, yLabelPos, "%s" % (cmsExtraLabel))

        legend.Clear()

        if isMC:
            legend.AddEntry(effSFvsOF, "R_{T} MC", "p")
            legend.AddEntry(effSFvsOFData, "R_{T} Data", "p")
        else:
            legend.AddEntry(effSFvsOF, "R_{T}", "p")
        if isMC:
            legend.AddEntry(
                sfLine,
                "Mean R_{T} MC: %.3f" % (centralVals[runRange.label]["RT"]),
                "l")
            legend.AddEntry(
                sfLineData, "Mean R_{T} Data: %.3f" %
                (centralValsData[runRange.label]["RT"]), "l")
        else:
            legend.AddEntry(
                sfLine,
                "Mean R_{T}: %.3f" % (centralVals[runRange.label]["RT"]), "l")

        legend.AddEntry(ge, "syst. uncert. Data", "f")
        legend.Draw("same")
        latexSelection.DrawLatex(0.20, 0.25, selectionLabel)
        ROOT.gPad.RedrawAxis()
        if isMC:
            hCanvas.Print("fig/Triggereff_SFvsOF_Syst_%s_%s_%s_%s_%s_MC.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))
        else:
            hCanvas.Print("fig/Triggereff_SFvsOF_Syst_%s_%s_%s_%s_%s.pdf" %
                          (source, selection.name, runRange.label,
                           plot.variablePlotName, plot.additionalName))
Ejemplo n.º 7
0
            if unfoldedData:
                N = origh14.GetBinContent(b + 1)
            else:
                N = 1. / pow(
                    h14.GetBinError(b + 1) / h14.GetBinContent(b + 1), 2)
            print N
            nevents += N
            L = 0
            if N > 0:
                L = ROOT.Math.gamma_quantile(alpha / 2., N, 1.)
            U = ROOT.Math.gamma_quantile_c(alpha / 2., N + 1, 1.)
            h14G.SetPointEYlow(b, (N - L) / N * h14.GetBinContent(b + 1))
            h14G.SetPointEYhigh(b, (U - N) / N * h14.GetBinContent(b + 1))
        print "data events:", nevents

        h14Gsys = h14G.Clone(histname + "sys")
        new_hists += [h14Gsys]
        h14Gsysstat = h14G.Clone(histname + "sysstat")
        new_hists += [h14Gsysstat]

        filename = "datacard_shapelimit13TeV_QCD_chi2016_backup.root"
        print filename
        fsys = TFile.Open(filename)
        new_hists += [fsys]
        uncertaintynames = ["jer", "jes", "pdf", "scale"]
        #uncertaintynames=["jer","jes","scale"]
        uncertainties = []
        for u in uncertaintynames:
            histname1 = 'QCD#chi' + str(massbins[massbin]).strip("()").replace(
                ',', "_").replace(' ', "") + "_rebin1_" + u + "Up"
            print histname1
Ejemplo n.º 8
0
def plotDataOverMCEff(hist_mc_tight, hist_mc_loose, hist_data_tight, hist_data_loose, plot_name='fakerate.pdf', mc_leg='MC', obs_leg='Observed', ratio_leg='Obs/MC'):

    g = TGraphAsymmErrors(hist_mc_tight)
    g.Divide(hist_mc_tight, hist_mc_loose)
    g.GetYaxis().SetTitle('Misidentification rate')
    g.GetXaxis().SetTitle(hist_mc_tight.GetXaxis().GetTitle())
    g.GetYaxis().SetTitleOffset(1.2)
    g.GetYaxis().SetTitleOffset(1.3)

    g.SetLineColor(2)
    g.SetMarkerColor(2)

    g_data = TGraphAsymmErrors(hist_data_tight)
    g_data.Divide(hist_data_tight, hist_data_loose)

    # if g_data.GetN() != hist_data_tight.GetNbinsX():
    #     import pdb; pdb.set_trace()

    g_data.GetYaxis().SetTitle('Misidentification rate')
    g_data.GetXaxis().SetTitle(hist_data_tight.GetXaxis().GetTitle())
    g_data.GetYaxis().SetTitleOffset(1.2)
    g_data.GetYaxis().SetTitleOffset(1.3)
    g_data.SetMarkerColor(1)

    g_vals = g.GetY()
    g_data_vals = g_data.GetY()

    g_ratio = g_data.Clone('ratio')

    for i in xrange(g_data.GetN()):
        ratio = g_data_vals[i]/g_vals[i] if g_vals[i] else 0.
        g_ratio.SetPoint(i, g.GetX()[i], ratio)

        rel_y_low = math.sqrt((g_data.GetErrorYlow(i)/g_data_vals[i])**2 + (g.GetErrorYlow(i)/g_vals[i])**2) if g_data_vals[i] > 0. and g_vals[i] > 0. else 0.

        g_ratio.SetPointEYlow(i, rel_y_low * ratio)

        rel_y_high = math.sqrt((g_data.GetErrorYhigh(i)/g_data_vals[i])**2 + (g.GetErrorYhigh(i)/g_vals[i])**2) if g_data_vals[i] > 0. and g_vals[i] > 0. else 0.

        g_ratio.SetPointEYhigh(i, rel_y_high * ratio)

    # Gymnastics to get same label sizes etc in ratio and main plot
    ytp_ratio = 2.
    xtp_ratio = 2.

    # hr.GetYaxis().SetNdivisions(4)

    g_ratio.GetYaxis().SetTitleSize(g.GetYaxis().GetTitleSize() * xtp_ratio)
    g_ratio.GetXaxis().SetTitleSize(g.GetXaxis().GetTitleSize() * ytp_ratio)

    g_ratio.GetYaxis().SetTitleOffset(g.GetYaxis().GetTitleOffset() / xtp_ratio)
    g_ratio.GetXaxis().SetTitleOffset(g.GetXaxis().GetTitleOffset())  # / ytp_ratio)

    g_ratio.GetYaxis().SetLabelSize(g.GetYaxis().GetLabelSize() * xtp_ratio)
    g_ratio.GetXaxis().SetLabelSize(g.GetXaxis().GetLabelSize() * ytp_ratio)

    g_data.GetXaxis().SetLabelColor(0)
    g_data.GetXaxis().SetLabelSize(0)
    g.GetXaxis().SetLabelColor(0)
    g.GetXaxis().SetLabelSize(0)

    g_ratio.GetXaxis().SetTitle(g.GetXaxis().GetTitle())

    maxy = 1.3 * max(g.GetMaximum(), g_data.GetMaximum(), 0.05)
    g.GetYaxis().SetRangeUser(0.0011, maxy)

    cv, pad, padr = HistDrawer.buildCanvas()

    pad.cd()

    g.Draw('AP')
    g_data.Draw('P')

    legend = TLegend(0.23, 0.73, 0.43, 0.91)
    legend.SetFillColor(0)
    legend.SetFillStyle(0)
    legend.SetLineColor(0)
    legend.SetLineWidth(0)

    legend.AddEntry(g.GetName(), mc_leg, 'lep')
    legend.AddEntry(g_data.GetName(), obs_leg, 'lep')

    legend.Draw()

    padr.cd()
    g_ratio.GetYaxis().SetRangeUser(0.01, 1.99)
    g_ratio.GetYaxis().SetTitle(ratio_leg)
    g_ratio.Draw('AP')

    drawRatioLines(g_ratio)

    cv.Print(plot_name)

    g.GetYaxis().SetRangeUser(0.0001, 1)
    pad.SetLogy(True)
    cv.Print(plot_name.replace('.', '_log.'))
    f = ROOT.TFile(plot_name.replace('.', '_log.').replace('.pdf', '.root'), 'RECREATE')
    g.Write()
    g_data.Write()
    cv.Write()
    f.Close()