Esempio n. 1
0
def writeFullUnc(pred_file):
    ''' Update the input root file, add a hist with total prediction and full uncertainty. '''
    f = rt.TFile(pred_file, 'UPDATE')
    h = TGraphAsymmErrors(f.Get(pred_total_name).Clone('bkgtotal_unc_sr'))
    h_syst = TGraphAsymmErrors(
        f.Get(pred_total_name).Clone('bkgtotal_syst_unc_sr'))
    h_pieces = {}
    h_syst_pieces = {}
    for hname, sample in zip(graph_names, all_samples):
        h_pieces[sample] = TGraphAsymmErrors(
            f.Get(hname).Clone(sample + '_unc_sr'))
        h_syst_pieces[sample + "_up"] = TH1F(sample + '_syst_up',
                                             sample + '_syst_up', 183, 0, 183)
        h_syst_pieces[sample + "_dn"] = TH1F(sample + '_syst_dn',
                                             sample + '_syst_dn', 183, 0, 183)
    print "%30s %10s %16s" % ('bin', 'total pred', 'total unc.')
    for ibin in xrange(0, h.GetN()):
        bin = binlist[ibin]
        val = h.GetY()[ibin]
        e_low, e_up = fullUnc[bin]
        h.SetPointEYlow(ibin, e_low)
        h.SetPointEYhigh(ibin, e_up)
        print "%30s %10.4f +%8.4f -%8.4f" % (bin, val, e_up, e_low)
        allVals[bin] = {'bkg': (val, e_low, e_up)}
        # Test for only syst histograms
        val = h_syst.GetY()[ibin]
        e_low, e_up = systUnc[bin]
        h_syst.SetPointEYlow(ibin, e_low)
        h_syst.SetPointEYhigh(ibin, e_up)
        for sample in all_samples:
            val = yields[bin][sample]
            e_low, e_up = fullUnc_pieces[sample][bin]
            #print "%11s %30s %10.4f +%8.4f -%8.4f" % (sample, bin, val, e_up, e_low)
            h_pieces[sample].SetPointEYlow(ibin, e_low)
            h_pieces[sample].SetPointEYhigh(ibin, e_up)
            allVals[bin][sample] = (val, e_low, e_up)
            # Test for only syst histograms
            e_low, e_up = systUnc_rel_pieces[sample][bin]
            #if sample in test_samp and bin in test_bin and type in test_type and debug:
            #if 'TTZ' in sample and e_up > 8:
            #    print("%11s %30s %10.4f +%8.4f -%8.4f" % (sample, bin, val, e_up, e_low))
            h_syst_pieces[sample + "_up"].SetBinContent(ibin + 1, e_up)
            h_syst_pieces[sample + "_dn"].SetBinContent(ibin + 1, e_low)
            h_syst_pieces[sample + "_up"].SetBinError(ibin + 1, 0)
            h_syst_pieces[sample + "_dn"].SetBinError(ibin + 1, 0)
    h.Write('bkgtotal_unc_sr', rt.TObject.kOverwrite)
    h.Write('bkgtotal_syst_unc_sr', rt.TObject.kOverwrite)
    for sample in all_samples:
        h_pieces[sample].Write(sample + '_unc_sr', rt.TObject.kOverwrite)
        h_syst_pieces[sample + "_up"].Write(sample + '_syst_up',
                                            rt.TObject.kOverwrite)
        h_syst_pieces[sample + "_dn"].Write(sample + '_syst_dn',
                                            rt.TObject.kOverwrite)
    f.Close()
Esempio n. 2
0
def numericalInvertPlot(graph):
    #pick up point by point pl

    #loop on all data points
    nPoints = graph.GetN()

    newGraph = TGraphAsymmErrors(nPoints)

    #x=array('f')
    #y=array('f')
    #ey=array('f')

    for iPoint in xrange(0, nPoints):
        #get info on data point
        dataPointX = Double(0)
        dataPointY = Double(0)
        graph.GetPoint(iPoint, dataPointX, dataPointY)
        dataErrorX = graph.GetErrorX(iPoint)
        dataErrorY = graph.GetErrorY(iPoint)

        #numerical-invert the X
        newDataPointX = dataPointX * dataPointY

        newErrorXLeft = fabs(newDataPointX - (dataPointX - dataErrorX))
        newErrorXRight = fabs(newDataPointX - (dataPointX + dataErrorX))

        #setting the new graph (with asymm errors this time)
        newGraph.SetPoint(iPoint, newDataPointX, dataPointY)
        newGraph.SetPointEXhigh(iPoint, newErrorXRight)
        newGraph.SetPointEXlow(iPoint, newErrorXLeft)
        newGraph.SetPointEYhigh(iPoint, dataErrorY)
        newGraph.SetPointEYlow(iPoint, dataErrorY)

        print dataPointY, newDataPointX
        #check that the numerical-inverted X is still in the previous bin - otherwise, ERROR!
        binRangeLow = dataPointX - dataErrorX
        binRangeHigh = dataPointX + dataErrorX
        if newDataPointX < binRangeLow or newDataPointX > binRangeHigh:
            print "Warning! Data point should not be here!"
            print "Old data point: ", dataPointX
            print "New NI data point:", newDataPointX
            print "XLow: ", binRangeLow
            print "XHigh: ", binRangeHigh
            newGraph.SetPoint(iPoint, dataPointX, 0.0000000000001)
            newGraph.SetPointEXhigh(iPoint, dataErrorX)
            newGraph.SetPointEXlow(iPoint, dataErrorX)
            newGraph.SetPointEYhigh(iPoint, dataErrorY)
            newGraph.SetPointEYlow(iPoint, dataErrorY)

    return newGraph
def writeFullUnc(pred_file):
    ''' Update the input root file, add a hist with total prediction and full uncertainty. '''
    f = rt.TFile(pred_file, 'UPDATE')
    h = TGraphAsymmErrors(f.Get(pred_total_name).Clone('bkgtotal_unc_sr'))
    h_pieces = {}
    for hname, sample in zip(graph_names, all_samples):
        h_pieces[sample] = TGraphAsymmErrors(
            f.Get(hname).Clone(sample + '_unc_sr'))
    print "%30s %10s %16s" % ('bin', 'total pred', 'total unc.')
    for ibin in xrange(0, h.GetN()):
        bin = binlist[ibin]
        val = h.GetY()[ibin]
        e_low, e_up = fullUnc[bin]
        h.SetPointEYlow(ibin, e_low)
        h.SetPointEYhigh(ibin, e_up)
        print "%30s %10.2f +%8.2f -%8.2f" % (bin, val, e_up, e_low)
        allVals[bin] = {'bkg': (val, e_low, e_up)}
        for sample in all_samples:
            val = yields[bin][sample]
            e_low, e_up = fullUnc_pieces[sample][bin]
            h_pieces[sample].SetPointEYlow(ibin, e_low)
            h_pieces[sample].SetPointEYhigh(ibin, e_up)
            allVals[bin][sample] = (val, e_low, e_up)
    h.Write('bkgtotal_unc_sr', rt.TObject.kOverwrite)
    for sample in all_samples:
        h_pieces[sample].Write(sample + '_unc_sr', rt.TObject.kOverwrite)
    f.Close()
Esempio n. 4
0
def convertToPoisson(h):
    graph = TGraphAsymmErrors()
    q = (1-0.6827)/2.

    for i in range(1,h.GetNbinsX()+1):
        x=h.GetXaxis().GetBinCenter(i)
        xLow =h.GetXaxis().GetBinLowEdge(i)
        xHigh =h.GetXaxis().GetBinUpEdge(i)
        y=h.GetBinContent(i)
        yLow=0
        yHigh=0
        if y !=0.0:
            yLow = y-Math.chisquared_quantile_c(1-q,2*y)/2.
            yHigh = Math.chisquared_quantile_c(q,2*(y+1))/2.-y
            graph.SetPoint(i-1,x,y)
            graph.SetPointEYlow(i-1,yLow)
            graph.SetPointEYhigh(i-1,yHigh)
            graph.SetPointEXlow(i-1,0.0)
            graph.SetPointEXhigh(i-1,0.0)


    graph.SetMarkerStyle(20)
    graph.SetLineWidth(2)
    graph.SetMarkerSize(1.)
    graph.SetMarkerColor(kBlack)


    return graph
Esempio n. 5
0
def makeResidHist(data, bkg):
    pulls = TGraphAsymmErrors(data.GetN())
    pulls.SetName("Pulls")
    pulls.SetLineWidth(data.GetLineWidth())
    pulls.SetLineStyle(data.GetLineStyle())
    pulls.SetLineColor(data.GetLineColor())
    pulls.SetMarkerSize(data.GetMarkerSize())
    pulls.SetMarkerStyle(data.GetMarkerStyle())
    pulls.SetMarkerColor(data.GetMarkerColor())
    pulls.SetFillStyle(data.GetFillStyle())
    pulls.SetFillColor(data.GetFillColor())

    # Add histograms, calculate Poisson confidence interval on sum value
    for i in range(data.GetN()):
        x = data.GetX()[i]
        dyl = data.GetErrorYlow(i)
        dyh = data.GetErrorYhigh(i)
        yy = data.GetY()[i] - bkg.Interpolate(x)  #bkg.GetBinContent(i+1)
        norm = dyl if yy > 0. else dyh
        if norm == 0.:
            yy, dyh, dyl = 0., 0., 0.
        else:
            yy /= norm
            dyh /= norm
            dyl /= norm
        pulls.SetPoint(i, x, yy)
        pulls.SetPointEYhigh(i, dyh)
        pulls.SetPointEYlow(i, dyl)

    return pulls
Esempio n. 6
0
def apply_centers(hPt, hCen):

    #bin center points according to the data

    cen = get_centers_from_toyMC(hCen)

    gSig = TGraphAsymmErrors(hPt.GetNbinsX())

    for i in xrange(hPt.GetNbinsX()):

        #center point
        #xcen = hPt.GetBinCenter(i+1)
        xcen = cen[i]["val"]

        #cross section value
        gSig.SetPoint(i, xcen, hPt.GetBinContent(i + 1))

        #vertical error
        gSig.SetPointEYlow(i, hPt.GetBinErrorLow(i + 1))
        gSig.SetPointEYhigh(i, hPt.GetBinErrorUp(i + 1))

        #horizontal error
        gSig.SetPointEXlow(i, cen[i]["err"])
        gSig.SetPointEXhigh(i, cen[i]["err"])

    return gSig
Esempio n. 7
0
def fixData(hist, useGarwood=True, cutGrass=False, maxPoisson=False):
    if hist == None: return
    varBins = False
    data = TGraphAsymmErrors()
    alpha = 1 - 0.6827

    for i in list(reversed(range(0, hist.GetNbinsX()))):
        #print "bin", i, "x:", hist.GetX()[i], "y:", hist.GetY()[i]
        # X error bars to 0 - do not move this, otherwise the first bin will disappear, thanks Wouter and Rene!
        N = max(hist.GetBinContent(i + 1), 0.)  # Avoid unphysical bins
        data.SetPoint(i, hist.GetXaxis().GetBinCenter(i + 1), N)
        if not varBins:
            data.SetPointEXlow(i, 0)
            data.SetPointEXhigh(i, 0)
        # Garwood confidence intervals
        if (useGarwood):
            L = ROOT.Math.gamma_quantile(alpha / 2, N, 1.) if N > 0 else 0.
            U = ROOT.Math.gamma_quantile_c(alpha / 2, N + 1, 1)
            # maximum between Poisson and Sumw2 error bars
            EL = N - L if not maxPoisson else max(N -
                                                  L, hist.GetBinErrorLow(i))
            EU = U - N if not maxPoisson else max(U -
                                                  N, hist.GetBinErrorHigh(i))
            data.SetPointEYlow(i, EL)
            data.SetPointEYhigh(i, EU)
        else:
            data.SetPointEYlow(i, math.sqrt(N))
            data.SetPointEYhigh(i, math.sqrt(N))
        # Cut grass
        if cutGrass and data.GetY()[i] > 0.: cutGrass = False
        # Treatment for 0 bins


#        if abs(hist.GetY()[i])<=1.e-6:
#            if cutGrass: hist.SetPointError(i, hist.GetErrorXlow(i), hist.GetErrorXhigh(i), 1.e-6, 1.e-6, )
#            if (hist.GetX()[i]>65 and hist.GetX()[i]<135 and hist.GetY()[i]==0): hist.SetPointError(i, hist.GetErrorXlow(i), hist.GetErrorXhigh(i), 1.e-6, 1.e-6, )
#            hist.SetPoint(i, hist.GetX()[i], -1.e-4)
# X error bars
#if hist.GetErrorXlow(i)<1.e-4:
#    binwidth = hist.GetX()[1]-hist.GetX()[0]
#    hist.SetPointEXlow(i, binwidth/2.)
#    hist.SetPointEXhigh(i, binwidth/2.)
    data.SetMarkerColor(hist.GetMarkerColor())
    data.SetMarkerStyle(hist.GetMarkerStyle())
    data.SetMarkerSize(hist.GetMarkerSize())
    #data.SetLineSize(hist.GetLineSize())
    return data
Esempio n. 8
0
    def __init__( self, process_list, sf = None, df = None ):
        
        self.__processes = process_list
        
        if sf and df:
            
            self.__sf = sf
            self.__df = df
            
            alpha = 1 - 0.6827            

            self.__sfCRGraph = TGraphAsymmErrors(self.__sf)
            self.__dfCRGraph = TGraphAsymmErrors(self.__df)
            
            for g in [self.__sfCRGraph, self.__dfCRGraph]:
                for i in range(g.GetN()):
                    N = g.GetY()[i]
                    LowErr = 0 if N == 0 else Math.gamma_quantile(alpha/2, N, 1.)
                    UpErr = Math.gamma_quantile_c(alpha/2, N+1, 1.) # recommended by StatComm (1.8)
                    # Math.gamma_quantile_c(alpha, N+1, 1.) # gives 1.2, strictly 68% one-sided
                    g.SetPointEYlow(i, N-LowErr)
                    g.SetPointEYhigh(i, UpErr-N)
            
            for p in self.__processes:
                
                if p.name() in ['nonpromptSF', 'nonpromptDF']:
                    
                    nom, low, high = [], [], []
                    
                    for ib in range(p.nominal().GetXaxis().GetNbins()):
                        if p.name() in ['nonpromptDF']: hnp = self.__dfCRGraph
                        else: hnp = self.__sfCRGraph
                        npcr = hnp.GetY()[ib]
                        npcrErrLow = hnp.GetEYlow()[ib]
                        npcrErrHigh = hnp.GetEYhigh()[ib]
                        np = p.nominal().GetBinContent(ib+1)
                        npErr = p.nominal().GetBinError(ib+1)
                        alpha = np/npcr if npcr > 0 else npErr
                        nom.append(npcr*alpha)
                        low.append(npcrErrLow*alpha)
                        high.append(npcrErrHigh*alpha)
                            
                    hnom = p.nominal().Clone()
                    for ib in range(hnom.GetXaxis().GetNbins()):
                        hnom.SetBinContent(ib+1, nom[ib])
                    npGraph = TGraphAsymmErrors(hnom)
                    for ib in range(hnom.GetXaxis().GetNbins()):
                        npGraph.SetPointEYlow(ib, low[ib])
                        npGraph.SetPointEYhigh(ib, high[ib])
                    if p.name() in ['nonpromptDF']:
                        self.__dfGraph = npGraph
                    else:
                        self.__sfGraph = npGraph
                        
        self.__uncertainties = set()
        for p in self.__processes:
            self.__uncertainties = self.__uncertainties.union( set( p.uncertaintySources() ) )
Esempio n. 9
0
def normalizeGraph(graph, binwidth):
    xsecSum = 0.
    for pt in range(1, graph.GetN()):
        xsecSum += graph.GetY()[pt] * binwidth[pt]
    normGraph = TGraphAsymmErrors(graph.GetN() - 1)
    for pt in range(0, normGraph.GetN()):
        normGraph.SetPoint(pt,
                           graph.GetX()[pt + 1],
                           graph.GetY()[pt + 1] / xsecSum)
        normGraph.SetPointEYhigh(pt, graph.GetErrorYhigh(pt + 1) / xsecSum)
        normGraph.SetPointEYlow(pt, graph.GetErrorYlow(pt + 1) / xsecSum)
    return normGraph
Esempio n. 10
0
def histToGraph(hist, name='', keepErrors=True, poissonErrors=True):
    ## Helper method to convert a histogram to a corresponding graph
    #  @hist           TH1 object
    #  @name           name of the graph (default is name of histogram)
    #  @keepErrors     decide if the y-errors should be propagated to the graph
    #  @poissonErrors  decide if the y-errors should be calculated as Poisson errors
    #  @return graph
    if not name:
        name = 'g%s' % (hist.GetName())
    from ROOT import TGraphAsymmErrors
    nBins = hist.GetNbinsX()
    graph = TGraphAsymmErrors(nBins)
    graph.SetNameTitle(name, hist.GetTitle())
    xAxis = hist.GetXaxis()
    for i in xrange(nBins):
        xVal = xAxis.GetBinCenter(i + 1)
        yVal = hist.GetBinContent(i + 1)
        graph.SetPoint(i, xVal, yVal)
        graph.SetPointEXlow(i, abs(xVal - xAxis.GetBinLowEdge(i + 1)))
        graph.SetPointEXhigh(i, abs(xVal - xAxis.GetBinUpEdge(i + 1)))
        if keepErrors:
            if poissonErrors:
                lo, hi = calculatePoissonErrors(yVal)
                graph.SetPointEYlow(i, lo)
                graph.SetPointEYhigh(i, hi)
            else:
                graph.SetPointEYlow(i, hist.GetBinErrorLow(i + 1))
                graph.SetPointEYhigh(i, hist.GetBinErrorUp(i + 1))
    # copy the style
    graph.SetMarkerStyle(hist.GetMarkerStyle())
    graph.SetMarkerColor(hist.GetMarkerColor())
    graph.SetMarkerSize(hist.GetMarkerSize())
    graph.SetLineStyle(hist.GetLineStyle())
    graph.SetLineColor(hist.GetLineColor())
    graph.SetLineWidth(hist.GetLineWidth())
    graph.SetFillColor(hist.GetFillColor())
    graph.SetFillStyle(hist.GetFillStyle())
    return graph
    def diffGraph(self, g, h, opt):
        gdiff = TGraphAsymmErrors(g)
        gdiff.SetName(g.GetName() + h.GetName() + '_diff')

        for i in range(0, gdiff.GetN()):
            x = Double(0.)
            y = Double(0.)
            g.GetPoint(i, x, y)
            gdiff.SetPoint(i, x, y - h.GetBinContent(i + 1))

            if opt == 1:  # keep bin errors
                pass
            elif opt == 2:
                gdiff.SetPointEYhigh(
                    i,
                    math.sqrt(g.GetErrorYhigh(i)**2 + h.GetBinError(i + 1)**2))

        return gdiff
    def createTGraphPoisson(self, h, w=1.):
        self.tfile.cd()
        g = TGraphAsymmErrors(h)
        for i in range(0, g.GetN()):
            y = h.GetBinContent(i + 1)
            binWidth = h.GetBinWidth(i + 1)

            # From https://twiki.cern.ch/twiki/bin/view/CMS/PoissonErrorBars
            alpha = 1. - 0.6827
            n = int(
                round(y * binWidth /
                      w))  # Round is necessary due to, well, rounding errors
            l = Math.gamma_quantile(alpha / 2., n, 1.) if n != 0. else 0.
            u = Math.gamma_quantile_c(alpha, n + 1, 1)
            # print y*binWidth/w, n, y, u, l
            g.SetPointEYlow(i, (n - l) / binWidth * w)
            g.SetPointEYhigh(i, (u - n) / binWidth * w)

        return g
Esempio n. 13
0
def fixed_centers(hPt):

    #fixed bin centers

    gSig = TGraphAsymmErrors(hPt.GetNbinsX())

    for i in xrange(hPt.GetNbinsX()):

        #cross section value
        gSig.SetPoint(i, hPt.GetBinCenter(i + 1), hPt.GetBinContent(i + 1))

        #vertical error
        gSig.SetPointEYlow(i, hPt.GetBinErrorLow(i + 1))
        gSig.SetPointEYhigh(i, hPt.GetBinErrorUp(i + 1))

        #horizontal error
        gSig.SetPointEXlow(i, hPt.GetBinWidth(i + 1) / 2.)
        gSig.SetPointEXhigh(i, hPt.GetBinWidth(i + 1) / 2.)

    return gSig
Esempio n. 14
0
    def totalBkgWithStatErrors( self ):
        
        total_bkg_hist = None
        low, high = None, None

        for p in self.__processes:
            if p.isSignal():
                continue
            nbins = p.nominal().GetXaxis().GetNbins()
            if low is None: low = [0]*nbins
            if high is None: high = [0]*nbins
            
            if total_bkg_hist is None:
                total_bkg_hist = p.nominal().Clone()
            else:
                total_bkg_hist.Add( p.nominal() )
            gr = None
            if p.name() in ['nonpromptDF']: gr = self.__dfGraph
            elif p.name() in ['nonpromptSF']: gr = self.__sfGraph
            if gr:
                for ib in range(nbins):
                    low[ib] += math.pow(gr.GetEYlow()[ib], 2)
                    high[ib] += math.pow(gr.GetEYhigh()[ib], 2)
            else:
                for ib in range(nbins):
                    low[ib] += math.pow(p.nominal().GetBinError(ib), 2)
                    high[ib] += math.pow(p.nominal().GetBinError(ib), 2)
                            
        for ib in range(len(low)):
            low[ib] = math.sqrt(low[ib])
            high[ib] = math.sqrt(high[ib])
                    
        total_bkg_graph = TGraphAsymmErrors(total_bkg_hist)
        for ib in range(total_bkg_graph.GetN()):
            total_bkg_graph.SetPointEYlow(ib, low[ib])
            total_bkg_graph.SetPointEYhigh(ib, high[ib])
                    
        return [total_bkg_hist, total_bkg_graph]
Esempio n. 15
0
        alpha = 1. - 0.6827
        nevents = 0
        for b in range(h14G.GetN()):
            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:
def make_plots_ROOT(histograms, category, save_path, histname, channel):
    global variable, translateOptions, k_value, b_tag_bin, maximum
    ROOT.TH1.SetDefaultSumw2(False)
    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;')
    plotting.setStyle()
    gStyle.SetTitleYOffset(2.)
    ROOT.gROOT.ForceStyle()
    canvas = Canvas(width=700, height=500)
    canvas.SetLeftMargin(0.18)
    canvas.SetBottomMargin(0.15)
    canvas.SetTopMargin(0.05)
    canvas.SetRightMargin(0.05)
    legend = plotting.create_legend(x0=0.6, y1=0.5)

    hist_data = histograms['unfolded']
    hist_data.GetXaxis().SetTitle(translate_options[variable] + ' [GeV]')
    hist_data.GetYaxis().SetTitle('#frac{1}{#sigma} #frac{d#sigma}{d' +
                                  translate_options[variable] + '} [GeV^{-1}]')
    hist_data.GetXaxis().SetTitleSize(0.05)
    hist_data.GetYaxis().SetTitleSize(0.05)
    hist_data.SetMinimum(0)
    hist_data.SetMaximum(maximum[variable])
    hist_data.SetMarkerSize(1)
    hist_data.SetMarkerStyle(8)
    plotAsym = TGraphAsymmErrors(hist_data)
    plotStatErr = TGraphAsymmErrors(hist_data)

    xsections = read_unfolded_xsections(channel)
    bins = variable_bins_ROOT[variable]
    assert (len(bins) == len(xsections['central']))

    for bin_i in range(len(bins)):
        scale = 1  # / width
        centralresult = xsections['central'][bin_i]
        fit_error = centralresult[1]
        uncertainty = calculateTotalUncertainty(xsections, bin_i)
        uncertainty_total_plus = uncertainty['Total+'][0]
        uncertainty_total_minus = uncertainty['Total-'][0]
        uncertainty_total_plus, uncertainty_total_minus = symmetriseErrors(
            uncertainty_total_plus, uncertainty_total_minus)
        error_up = sqrt(fit_error**2 + uncertainty_total_plus**2) * scale
        error_down = sqrt(fit_error**2 + uncertainty_total_minus**2) * scale
        plotStatErr.SetPointEYhigh(bin_i, fit_error * scale)
        plotStatErr.SetPointEYlow(bin_i, fit_error * scale)
        plotAsym.SetPointEYhigh(bin_i, error_up)
        plotAsym.SetPointEYlow(bin_i, error_down)

    gStyle.SetEndErrorSize(20)
    plotAsym.SetLineWidth(2)
    plotStatErr.SetLineWidth(2)
    hist_data.Draw('P')
    plotStatErr.Draw('same P')
    plotAsym.Draw('same P Z')
    legend.AddEntry(hist_data, 'unfolded', 'P')

    hist_measured = histograms['measured']
    hist_measured.SetMarkerSize(1)
    hist_measured.SetMarkerStyle(20)
    hist_measured.SetMarkerColor(2)
    #hist_measured.Draw('same P')
    #legend.AddEntry(hist_measured, 'measured', 'P')

    for key, hist in sorted(histograms.iteritems()):
        if not 'unfolded' in key and not 'measured' in key:
            hist.SetLineStyle(7)
            hist.SetLineWidth(2)
            # setting colours
            if 'POWHEG' in key or 'matchingdown' in key:
                hist.SetLineColor(kBlue)
            elif 'MADGRAPH' in key or 'matchingup' in key:
                hist.SetLineColor(kRed + 1)
            elif 'MCATNLO' in key or 'scaleup' in key:
                hist.SetLineColor(kGreen - 3)
            elif 'scaledown' in key:
                hist.SetLineColor(kMagenta + 3)
            hist.Draw('hist same')
            legend.AddEntry(hist, translate_options[key], 'l')

    legend.Draw()

    mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC")
    channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC")
    if 'electron' in histname:
        channelLabel.AddText(
            "e, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    elif 'muon' in histname:
        channelLabel.AddText(
            "#mu, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    else:
        channelLabel.AddText(
            "combined, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    mytext.AddText("CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" %
                   (5.8))

    mytext.SetFillStyle(0)
    mytext.SetBorderSize(0)
    mytext.SetTextFont(42)
    mytext.SetTextAlign(13)

    channelLabel.SetFillStyle(0)
    channelLabel.SetBorderSize(0)
    channelLabel.SetTextFont(42)
    channelLabel.SetTextAlign(13)
    mytext.Draw()
    channelLabel.Draw()

    canvas.Modified()
    canvas.Update()

    path = save_path + '/' + variable + '/' + category
    make_folder_if_not_exists(path)
    canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.png')
    canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.pdf')
Esempio n. 17
0
def uncertainty_band(process, region, calculation, uncertainty, estimation):
    """Calculates an uncertainty band (TGraphAsymmErrors) for a specific
    uncertainty.

    Any uncertainties (except statistical) that have a shape component will
    have the shape component converted to an overall component (considered in
    addition to any existing overall component).

    NOTE: CURRENTLY ROOT'S STATISTICAL ERRORS ARE USED AND THIS METHOD IS
    DISABLED
    NOTE: The statistical error calculated is the statistical error on the
    estimate given the poisson statistics of the unweighted samples. This is
    calculated per-bin as:

        uncertainty = sqrt(unweighted) * weighted / unweighted
                    = weighted / sqrt(unweighted)

    For samples such as data, where there is no weighting applied, this just
    reduces to sqrt(weighted) = sqrt(unweighted), which is the usual
    uncertainty applied by ROOT.

    NOTE: The y-component of the uncertainty band will NOT be set to bin
    content because this leads to errors in usage when combining the bands
    and is only really necessary when computing the final combined band, so
    instead simply pass a base for the error band when calling
    combined_uncertainty_band.

    Args:
        process: The process to consider
        region: The region to consider
        calculation: The calculation, which should return a histogram
        uncertainty: The Uncertainty subclass to consider, or None to compute
            statistical uncertainty of Monte Carlo samples
        estimation: The Estimation subclass to consider

    Returns:
        A TGraphAsymmErrors representing the error band.
    """
    # Compute the nominal histogram
    nominal = estimation(calculation)(process, region)

    # Compute and unpack variations
    if uncertainty is not None:
        # Perform the uncertainty estimation
        variations = estimation(uncertainty(calculation))(process, region)

        # Unpack variations
        overall_up, overall_down, shape_up, shape_down = variations

        # Convert any shape variations to overall
        if shape_up is None:
            shape_overall_up = None
        else:
            shape_overall_up = to_overall(shape_up, nominal)
            shape_up = None
        if shape_down is None:
            shape_overall_down = None
        else:
            shape_overall_down = to_overall(shape_down, nominal)
            shape_down = None
    else:
        # We're computing statistical variation, so we don't need these
        overall_up = overall_down = None
        shape_up = shape_down = None
        shape_overall_up = shape_overall_down = None

        # TODO: What's the idea here? This doesn't work as it is.
        # For computing the uncertainty of weighted MC samples, we need the
        # unweighted histogram
        #unweighted = estimation(calculation)(
        #process,
        #region.weighted(False),
        #weighted_combination = False
        #)

    # Create the error band.  We pass it the nominal histogram just to get
    # the binning correct.  The graph will also extract values and errors
    # from the histogram, but that's okay because we'll overwrite them
    # below.
    band = TGraphAsymmErrors(nominal)

    # Get the number of bins in the histogram
    bins = nominal.GetNbinsX()

    # Go through each point in the graph and 0-out the Y-value and Y-error.
    # Unfortunately we can't set the Y-value individually (which would have
    # been great since the X-values would already be at bin centers).
    # Anyway, no big deal, X-values are easy to set.  The X-error will have
    # already bin set to bin width.
    for bin in xrange(0, bins):
        band.SetPoint(bin, band.GetX()[bin], 0)
        band.SetPointEYhigh(bin, 0.0)
        band.SetPointEYlow(bin, 0.0)

    # Loop over all bins and compute uncertainties
    for bin, point in zip(range(1, bins + 1), range(0, bins)):
        # Get the bin content
        content = nominal.GetBinContent(bin)

        # If the content is 0, there are no uncertainties, because we only
        # consider overall and statistical uncertainties
        if content == 0.0:
            band.SetPointEYhigh(point, 0.0)
            band.SetPointEYlow(point, 0.0)
            continue

        # Create a list of fractional variations for this bin.  These lists
        # will hold FRACTIONAL variations, i.e. variations normalized to bin
        # content, and will be converted to absolute variations below when they
        # are set as errors.
        up_variations = []
        down_variations = []

        # Add any overall variations
        if overall_up is not None:
            up_variations.append(overall_up - 1.0)
        if overall_down is not None:
            down_variations.append(1.0 - overall_down)
        if shape_overall_up is not None:
            up_variations.append(shape_overall_up - 1.0)
        if shape_overall_down is not None:
            down_variations.append(1.0 - shape_overall_down)

        # TODO: What's the point of using the unweighted distribution? It
        # makes no sense to me.
        # Add the statistical variation if uncertainty is None.  Note that we
        # compute this for the statistics of the unweighted Monte Carlo and not
        # the weighted bin count.
        #if uncertainty is None:
        ## Get the unweighted content
        #unweighted_content = unweighted.GetBinContent(bin)

        ## Calculate error if possible
        #if content > 0.0 and unweighted_content > 0.0:
        ## The extra factor of 1/content is just because we normalize
        ## everything to content for combining together.  It has nothing
        ## to do with the derivation of the uncertainty, and it is
        ## multipled out below.
        #statistical_variation = (
        #content / sqrt(unweighted_content)
        #) / content
        #up_variations.append(statistical_variation)
        #down_variations.append(statistical_variation)

        # Statistical error; use the error from the distribution directly
        if uncertainty is None:
            error = nominal.GetBinError(bin)
            band.SetPointEYhigh(point, error)
            band.SetPointEYlow(point, error)
        else:
            # Set the point and error.  Note that, since we sum things in
            # quadrature, it really doesn't matter how we compute the
            # differences above.
            band.SetPointEYhigh(point, sum_quadrature(up_variations) * content)
            band.SetPointEYlow(point,
                               sum_quadrature(down_variations) * content)

    # All done
    return band
Esempio n. 18
0
def make_ratioplot(name,
                   ttbar_file=0,
                   qcd_file=0,
                   signal_files=[],
                   histo=0,
                   rebin=1,
                   minx=0,
                   maxx=0,
                   miny=0,
                   maxy=0,
                   logy=False,
                   xtitle='',
                   ytitle='',
                   textsizefactor=1,
                   signal_legend=[],
                   outfile=0,
                   signal_colors=[],
                   signal_zoom=1,
                   qcd_zoom=1,
                   ttbar_zoom=1,
                   ttbar_legend='t#bar{t}',
                   qcd_legend='QCD from MC',
                   dosys=False,
                   docms=True,
                   legendtitle=''):

    ###canvas setting up
    canvas = 0
    canvas = TCanvas(name, '', 0, 0, 600, 600)
    canvas.SetLeftMargin(0.15)
    canvas.SetRightMargin(0.05)
    canvas.SetTopMargin(0.10)
    canvas.SetBottomMargin(0.10)
    charsize = 0.04
    offset = 1.9

    ###latex label
    latex = 0
    latex = TLatex(0.6, 0.7, '13 TeV, 2.69 fb^{-1}')
    latex.SetTextSize(charsize)
    latex.SetNDC(1)
    latex.SetTextFont(42)

    ###legend setting up
    #legend=TLegend(0.0,0.75,0.99,1.04)
    legend = TLegend(0.4, 0.6, 0.94, 0.95)
    legend.SetNColumns(2)
    legend.SetHeader('')
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

    ###mc stack
    stack = THStack(name + '_stack', '')

    qcd_histo = qcd_file.Get(histo).Clone(name + '_make_plot')
    qcd_histo.Rebin(rebin)
    ttbar_histo = ttbar_file.Get(histo).Clone()
    ttbar_histo.Rebin(rebin)
    ttbar_histo.SetFillColor(kRed - 9)
    ttbar_histo.SetLineColor(kRed - 9)
    ttbar_histo.SetMarkerColor(kRed - 9)
    if ttbar_zoom != 1:
        ttbar_histo.Scale(ttbar_zoom)
    legend.AddEntry(ttbar_histo, ttbar_legend, 'f')
    qcd_histo.SetFillColor(kOrange - 5)
    qcd_histo.SetLineColor(kOrange - 5)
    qcd_histo.SetMarkerColor(kOrange - 5)
    if qcd_zoom != 1:
        qcd_histo.Scale(qcd_zoom)
    legend.AddEntry(qcd_histo, qcd_legend, 'f')

    sum_mc = qcd_histo.Clone(histo + 'tmp')
    sum_mc.Add(ttbar_histo)
    stack.Add(ttbar_histo)
    stack.Add(qcd_histo)

    sum_mc.SetLineColor(kBlack)
    sum_mc.SetFillStyle(0)
    err = TGraphAsymmErrors(sum_mc)
    legend.AddEntry(err, 'Total uncertainty', 'f')

    if legendtitle == '':
        legend.AddEntry(0, "", '')
        legend.AddEntry(0, "g_{RS} #rightarrow t#bar{t} (2pb)", '')
    else:
        legend.AddEntry(0, "", '')
        legend.AddEntry(0, legendtitle, '')

    ###signal setting up
    signal_histos = []
    colors = [
        kBlack, kRed, kOrange, kBlue, kGreen + 3, 44, 45, 46, 47, 48, 49, 50,
        51, 52, 53, 54, 55, 56, 57, 58, 59, 60
    ]
    styles = [
        1, 3, 5, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1
    ]
    if signal_colors != []:
        colors = signal_colors
    for i in range(len(signal_files)):
        signal_histos.append(signal_files[i].Get(histo).Clone())
        signal_histos[i].SetLineWidth(3)
        signal_histos[i].SetLineStyle(styles[i])
        signal_histos[i].SetLineColor(colors[i])
        signal_histos[i].SetMarkerColor(colors[i])
        signal_histos[i].Rebin(rebin)
        if signal_zoom != 1:
            signal_histos[i].Scale(signal_zoom)
        legend.AddEntry(signal_histos[i], signal_legend[i], 'l')

    ###mc shape line
    ttbar_line = 0
    ttbar_line = ttbar_histo.Clone()
    ttbar_line.SetLineColor(kBlack)
    ttbar_line.SetFillStyle(0)

    ###mc errors
    if dosys:
        sys_diff_qcd = []
        sys_diff_ttbar = []
        for imtt in range(1, ttbar_histo.GetNbinsX() + 1):
            sys_diff_qcd.append([])
            sys_diff_ttbar.append([])

        #adding stat uncertainties <--removed
        # for imtt in range(1,ttbar_histo.GetNbinsX()+1):
        #   sys_diff_ttbar[imtt-1].append(ttbar_histo.GetBinError(imtt))
        #   sys_diff_ttbar[imtt-1].append(-ttbar_histo.GetBinError(imtt))
        #   sys_diff_qcd[imtt-1].append(qcd_histo.GetBinError(imtt))
        #   sys_diff_qcd[imtt-1].append(-qcd_histo.GetBinError(imtt))
        #adding flat uncertainties
        for imtt in range(1, ttbar_histo.GetNbinsX() + 1):
            #ttbar
            for i in [
                    2.4,  #pdf
                    10.0,  #mu
                    3.0,  #xsec
                    6.0,  #toppt
                    1.0,  #lumi
                    3.5,  #jec
                    3.0,  #jer
                    10.0,  #btag
                    #3.0,#trig
                    10.0,  #toptag
                    3.0
            ]:  #pileup
                sys_diff_ttbar[imtt - 1].append(
                    i / 100.0 * ttbar_histo.GetBinContent(imtt))
                sys_diff_ttbar[imtt - 1].append(
                    -i / 100.0 * ttbar_histo.GetBinContent(imtt))
            closureunc = 5.0
            # if '1b' in histo:
            #   closureunc=5.0
            # elif '2b' in histo:
            #   closureunc=10.0
            for i in [
                    2.0,  #modmass
                    closureunc
            ]:  #closure
                sys_diff_qcd[imtt - 1].append(i / 100.0 *
                                              qcd_histo.GetBinContent(imtt))
                sys_diff_qcd[imtt - 1].append(-i / 100.0 *
                                              qcd_histo.GetBinContent(imtt))
            # #3% trigger
            # sys_diff_ttbar[imtt-1].append(0.03*ttbar_histo.GetBinContent(imtt))
            # sys_diff_ttbar[imtt-1].append(-0.03*ttbar_histo.GetBinContent(imtt))
            # #2.7% lumi
            # sys_diff_ttbar[imtt-1].append(0.023*ttbar_histo.GetBinContent(imtt))
            # sys_diff_ttbar[imtt-1].append(-0.023*ttbar_histo.GetBinContent(imtt))
            # #15% ttbar
            # #sys_diff_ttbar[imtt-1].append(0.15*ttbar_histo.GetBinContent(imtt))
            # #sys_diff_ttbar[imtt-1].append(-0.15*ttbar_histo.GetBinContent(imtt))
            # #2.8% QCD
            # sys_diff_qcd[imtt-1].append(0.028*qcd_histo.GetBinContent(imtt))
            # sys_diff_qcd[imtt-1].append(-0.028*qcd_histo.GetBinContent(imtt))
        #combining uncertainties
        sys_tot_ttbar = []
        sys_tot_qcd = []
        sys_tot = []
        sys_global_ttbar = [0.0, 0.0]
        sys_global_qcd = [0.0, 0.0]
        nevt_global = [0.0, 0.0, 0.0]
        for imtt in range(1, ttbar_histo.GetNbinsX() + 1):
            uperr_qcd = 0
            downerr_qcd = 0
            uperr_ttbar = 0
            downerr_ttbar = 0
            for error in sys_diff_ttbar[imtt - 1]:
                if error < 0:
                    downerr_ttbar = downerr_ttbar + error * error
                else:
                    uperr_ttbar = uperr_ttbar + error * error
            for error in sys_diff_qcd[imtt - 1]:
                if error < 0:
                    downerr_qcd = downerr_qcd + error * error
                else:
                    uperr_qcd = uperr_qcd + error * error
            sys_tot_ttbar.append(
                [math.sqrt(downerr_ttbar),
                 math.sqrt(uperr_ttbar)])
            sys_tot_qcd.append([math.sqrt(downerr_qcd), math.sqrt(uperr_qcd)])
            sys_tot.append([
                math.sqrt(downerr_qcd + downerr_ttbar),
                math.sqrt(uperr_qcd + uperr_ttbar)
            ])
            sys_global_qcd[0] = sys_global_qcd[0] + downerr_qcd
            sys_global_qcd[1] = sys_global_qcd[1] + uperr_qcd
            sys_global_ttbar[0] = sys_global_ttbar[0] + downerr_ttbar
            sys_global_ttbar[1] = sys_global_ttbar[1] + uperr_ttbar
            # nevt_global[0]=nevt_global[0]+data_histo.GetBinContent(imtt)
            nevt_global[1] = nevt_global[1] + qcd_histo.GetBinContent(imtt)
            nevt_global[2] = nevt_global[2] + ttbar_histo.GetBinContent(imtt)
            #print 'ttbar+qcd',math.sqrt(uperr_qcd+uperr_ttbar),math.sqrt(downerr_qcd+downerr_ttbar)
            #print 'qcd',math.sqrt(uperr_qcd),math.sqrt(downerr_qcd)
            #print 'ttbar',math.sqrt(uperr_ttbar),math.sqrt(downerr_ttbar)
            err.SetPointEYhigh(imtt - 1, math.sqrt(uperr_qcd + uperr_ttbar))
            err.SetPointEYlow(imtt - 1, math.sqrt(downerr_qcd + downerr_ttbar))
        sys_global = [0.0, 0.0]
        sys_global[0] = math.sqrt(sys_global_qcd[0] + sys_global_ttbar[0])
        sys_global[1] = math.sqrt(sys_global_qcd[1] + sys_global_ttbar[1])
        sys_global_qcd[0] = math.sqrt(sys_global_qcd[0])
        sys_global_qcd[1] = math.sqrt(sys_global_qcd[1])
        sys_global_ttbar[0] = math.sqrt(sys_global_ttbar[0])
        sys_global_ttbar[1] = math.sqrt(sys_global_ttbar[1])
        # print name
        # print "\hline"
        # print "Multijet QCD & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[1],sys_global_qcd[1],sys_global_qcd[0])
        # print "SM ttbar & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[2],sys_global_ttbar[1],sys_global_ttbar[0])
        # print "\hline"
        # print "Total background & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[1]+nevt_global[2],sys_global[1],sys_global[0])
        # print 'DATA & %.0f' %nevt_global[0]

    err.SetFillStyle(3145)
    err.SetFillColor(kGray + 1)

    ###drawing top
    canvas.cd()
    stack.Draw('hist')
    stack.GetXaxis().SetTitle(ttbar_histo.GetXaxis().GetTitle())
    stack.GetYaxis().SetTitle(ttbar_histo.GetYaxis().GetTitle())
    stack.GetXaxis().SetLabelSize(charsize)
    stack.GetXaxis().SetTitleSize(charsize)
    stack.GetYaxis().SetLabelSize(charsize)
    stack.GetYaxis().SetTitleSize(charsize)
    stack.GetYaxis().SetTitleOffset(offset)
    if minx != 0 or maxx != 0:
        stack.GetXaxis().SetRangeUser(minx, maxx)
    #else:
    #  stack.GetXaxis().SetRangeUser(0,4000)
    if miny != 0 or maxy != 0:
        stack.SetMaximum(maxy)
        stack.SetMinimum(miny)
    else:
        if logy:
            stack.SetMaximum(stack.GetMaximum() * 10)
            stack.SetMinimum(0.2)
        else:
            stack.SetMaximum(stack.GetMaximum() * 2.0)
            stack.SetMinimum(0.001)
    err.Draw('2')
    sum_mc.Draw('samehist')
    if ttbar_file != 0:
        ttbar_line.Draw('samehist')
    for i in signal_histos:
        i.Draw('samehist')
    if logy:
        canvas.SetLogy()
    legend.Draw()

    latex2text = ''
    if 'ldy_0b' in name:
        latex2text = '#Deltay < 1; 0 b tag'
    elif 'ldy_1b' in name:
        latex2text = '#Deltay < 1; 1 b tag'
    elif 'ldy_2b' in name:
        latex2text = '#Deltay < 1; 2 b tag'
    elif 'hdy_0b' in name:
        latex2text = '#Deltay > 1; 0 b tag'
    elif 'hdy_1b' in name:
        latex2text = '#Deltay > 1; 1 b tag'
    elif 'hdy_2b' in name:
        latex2text = '#Deltay > 1; 2 b tag'
    latex2 = TLatex(0.19, 0.7, latex2text)
    latex2.SetTextSize(0.03)
    latex2.SetNDC(1)
    latex2.SetTextFont(42)
    latex2.Draw()

    if docms:
        if '3000' in name:
            CMS_lumi.CMS_lumi(canvas, 3, 11)
        elif '1000' in name:
            CMS_lumi.CMS_lumi(canvas, 2, 11)
        elif '300' in name:
            CMS_lumi.CMS_lumi(canvas, 1, 11)
        elif '36' in name:
            CMS_lumi.CMS_lumi(canvas, 0, 11)

    ###saving
    canvas.SaveAs('pdf/' + name + '.pdf')
    if outfile != 0:
        canvas.Write()
Esempio n. 19
0
def nuisance_plot(input_file_, orien_, sticker_, oname_):

    pars = get_parameters_from_file(input_file_)
    #adjust_parameters(pars)

    N = len(pars)

    g68 = TGraph(2 * N + 7)
    g95 = TGraph(2 * N + 7)
    gPR = TGraphAsymmErrors(N)

    for i in range(0, N):
        x = pars[i].value
        y = i + 1.5
        xerr = pars[i].error
        yerr = 0.

        if orien_ == 'h':
            x, y = y, x
            xerr, yerr = yerr, xerr

        gPR.SetPoint(i, x, y)
        gPR.SetPointEXlow(i, xerr)
        gPR.SetPointEYlow(i, yerr)
        gPR.SetPointEXhigh(i, xerr)
        gPR.SetPointEYhigh(i, yerr)

    for a in range(0, N + 3):

        if orien_ == 'h':
            g68.SetPoint(a, a, -1)
            g95.SetPoint(a, a, -2)
            g68.SetPoint(a + 1 + N + 2, N + 2 - a, 1)
            g95.SetPoint(a + 1 + N + 2, N + 2 - a, 2)

        else:
            g68.SetPoint(a, -1, a)
            g95.SetPoint(a, -2, a)
            g68.SetPoint(a + 1 + N + 2, 1, N + 2 - a)
            g95.SetPoint(a + 1 + N + 2, 2, N + 2 - a)

    gPR.SetLineStyle(1)
    gPR.SetLineWidth(1)
    gPR.SetLineColor(1)
    gPR.SetMarkerStyle(21)
    gPR.SetMarkerSize(1.25)

    g68.SetFillColor(kGreen)
    g95.SetFillColor(kYellow)

    if orien_ == 'h':
        text_TL = TPaveText(0.100, 0.925, 0.440, 0.995, 'NDC')
        text_TR = TPaveText(0.587, 0.925, 0.999, 0.993, 'NDC')

    else:
        text_TL = TPaveText(0.370, 0.945, 0.590, 0.995, 'NDC')
        text_TR = TPaveText(0.600, 0.945, 0.995, 0.993, 'NDC')

    text_TL.AddText(label_TL)
    text_TL.SetFillColor(0)
    text_TL.SetTextAlign(12)
    text_TL.SetTextSize(0.06)
    text_TL.SetTextFont(42)

    text_TR.AddText(sticker_)
    text_TR.SetFillColor(0)
    text_TR.SetTextAlign(32)
    text_TR.SetTextSize(0.05)
    text_TR.SetTextFont(42)

    if orien_ == 'h':
        c = TCanvas('c', 'c', 1000, 700)
        c.SetTopMargin(0.08)
        c.SetRightMargin(0.02)
        c.SetBottomMargin(0.16)
        c.SetLeftMargin(0.11)

    else:
        c = TCanvas('c', 'c', 700, 1000)
        c.SetTopMargin(0.06)
        c.SetRightMargin(0.02)
        c.SetBottomMargin(0.12)
        c.SetLeftMargin(0.35 * 700 / 650)

    c.SetTickx()
    c.SetTicky()

    c.Update()
    g95.Draw('AF')
    g68.Draw('F')
    gPR.Draw('P')
    text_TL.Draw('same')
    text_TR.Draw('same')

    ax_1 = g95.GetHistogram().GetYaxis()
    ax_2 = g95.GetHistogram().GetXaxis()
    if orien_ == 'h': ax_1, ax_2 = ax_2, ax_1

    ax_1.Set(N + 2, 0, N + 2)
    ax_1.SetNdivisions(-414)
    for i in range(0, N):
        ax_1.SetBinLabel(i + 2, pars[i].name)

    g95.SetTitle('')
    ax_2.SetTitle('post-fit nuisance parameters values')
    #ax_2.SetTitle('deviation in units of #sigma')
    ax_1.SetTitleSize(0.050)
    ax_2.SetTitleSize(0.050)
    ax_1.SetTitleOffset(1.4)
    ax_2.SetTitleOffset(1.0)
    ax_1.SetLabelSize(0.05)
    #ax_2.SetLabelSize(0.05)
    ax_1.SetRangeUser(0, N + 2)
    ax_2.SetRangeUser(-2.4, 2.4)

    g95.GetHistogram().Draw('axis,same')

    c.SaveAs(oname_ + '.pdf')

    c.Close()
def makeplot_single(
    h1_sig=None,
    h1_bkg=None,
    h1_data=None,
    sig_legends_=None,
    bkg_legends_=None,
    sig_colors_=None,
    bkg_colors_=None,
    hist_name_=None,
    sig_scale_=1.0,
    dir_name_="plots",
    output_name_=None,
    extraoptions=None
    ):

    if h1_sig ==  None or h1_bkg == None:
        print("nothing to plot...")
        return
    os.system("mkdir -p "+dir_name_)
    os.system("cp index.php "+dir_name_)
    s_color = [632, 617, 839, 800, 1]
    b_color = [920, 2007, 2005, 2003, 2001, 2011]
    if sig_colors_:
        s_color = sig_colors_
    if bkg_colors_:
        b_color = bkg_colors_
    for idx in range(len(h1_sig)):
        h1_sig[idx].SetLineWidth(3)
        h1_sig[idx].SetLineColor(s_color[idx])
    for idx in range(len(h1_bkg)):
        h1_bkg[idx].SetLineWidth(2)
        h1_bkg[idx].SetLineColor(b_color[idx])
        h1_bkg[idx].SetFillColorAlpha(b_color[idx], 1)
    if h1_data:
        h1_data.SetBinErrorOption(1)
        h1_data.SetLineColor(1)
        h1_data.SetLineWidth(2)
        h1_data.SetMarkerColor(1)
        h1_data.SetMarkerStyle(20)

    myC = r.TCanvas("myC","myC", 600, 600)
    myC.SetTicky(1)
    pad1 = r.TPad("pad1","pad1", 0.05, 0.33,0.95, 0.97)
    pad1.SetBottomMargin(0.027)
    pad1.SetRightMargin( rightMargin )
    pad1.SetLeftMargin( leftMargin )
    pad2 = r.TPad("pad2","pad2", 0.05, 0.04, 0.95, 0.31)
    pad2.SetBottomMargin(0.4)
    pad2.SetTopMargin(0.05)
    pad2.SetRightMargin( rightMargin )
    pad2.SetLeftMargin( leftMargin )

    pad2.Draw()
    pad1.Draw()

    pad1.cd()

    for idx in range(len(h1_sig)):
        print("before signal scaling",h1_sig[idx].Integral())
        h1_sig[idx].Scale(sig_scale_)
        print("after signal scaling",h1_sig[idx].Integral())
        
    stack = r.THStack("stack", "stack")
    nS = np.zeros(h1_bkg[0].GetNbinsX())
    eS = np.zeros(h1_bkg[0].GetNbinsX())
    #hist_all is used to make the data/mc ratio. remove signal for the moment due to signal is scaled right now
    hist_all = h1_sig[0].Clone("hist_all")
    hist_all.Scale(0.0)
    hist_s = h1_sig[0].Clone("hist_s")
    hist_b = h1_bkg[0].Clone("hist_b")
    for idx in range(len(h1_bkg)):
        stack.Add(h1_bkg[idx])
        for ib in range(h1_bkg[0].GetNbinsX()):
            nS[ib] += h1_bkg[idx].GetBinContent(ib+1)
            eS[ib] = math.sqrt(eS[ib]*eS[ib] + h1_bkg[idx].GetBinError(ib+1)*h1_bkg[idx].GetBinError(ib+1))
        hist_all.Add(h1_bkg[idx]) 
        if idx > 0:
            hist_b.Add(h1_bkg[idx]) 
            
    for idx in range(len(h1_sig)):
        print("ggH signal yield: ", hist_s.Integral())
        if idx > 0:
            hist_temp = h1_sig[idx].Clone(h1_sig[idx].GetName()+"_temp")
            #hist_all.Add(hist_temp)
            hist_s.Add(h1_sig[idx])
        print("all signal yield: ", hist_s.Integral())

    stack.SetTitle("")
    
    maxY = 0.0
    if "stack_signal" in extraoptions and extraoptions["stack_signal"]:
        for idx in range(len(h1_sig)):
            h1_sig[idx].SetFillColorAlpha(s_color[idx], 1)
            stack.Add(h1_sig[idx])
            for ib in range(h1_bkg[0].GetNbinsX()):
                nS[ib] += h1_sig[idx].GetBinContent(ib+1)
                eS[ib] = math.sqrt(eS[ib]*eS[ib] + h1_sig[idx].GetBinError(ib+1)*h1_sig[idx].GetBinError(ib+1))
        if stack.GetMaximum() > maxY:
            maxY = stack.GetMaximum()
        #if "SR" in h.GetTitle(): 
        stack.Draw("hist")
    else:
        stack.Draw("hist")
        if stack.GetMaximum() > maxY:
            maxY = stack.GetMaximum()
        for idx in range(len(h1_sig)):
            if h1_sig[idx].GetMaximum() > maxY:
                maxY = h1_sig[idx].GetMaximum()
            if "SR" in h1_bkg[0].GetTitle():
                #h1_sig[idx].Draw("samehist")
                hist_s.Draw("samehist")

    ##draw  stack total unc on top of total histogram
    box = r.TBox(0,0,1,1,)
    box.SetFillStyle(3002)
    box.SetLineWidth(0)
    box.SetFillColor(r.kBlack)
    for idx in range(h1_bkg[0].GetNbinsX()):
        box.DrawBox(h1_bkg[0].GetBinCenter(idx+1)-0.5*h1_bkg[0].GetBinWidth(idx+1), nS[idx]-eS[idx], h1_bkg[0].GetBinCenter(idx+1)+0.5*h1_bkg[0].GetBinWidth(idx+1), nS[idx]+eS[idx])

    if h1_data:
        if h1_data.GetMaximum() > maxY:
            maxY = h1_data.GetMaximum()+np.sqrt(h1_data.GetMaximum())
        #if not "SR" in h1_data.GetTitle() or "fail" in h1_data.GetTitle():  
        if True:
            #print("debug h1_data.GetName()",h1_data.GetName(), h1_data.GetTitle())           
            TGraph_data = TGraphAsymmErrors(h1_data)
            for i in range(TGraph_data.GetN()):
                #data point
                var_x, var_y = Double(0.), Double(0.)
                TGraph_data.GetPoint(i,var_x,var_y)    
                if np.fabs(var_y) < 1e-5:
                    TGraph_data.SetPoint(i,var_x,-1.0)
                    TGraph_data.SetPointEYlow(i,-1)
                    TGraph_data.SetPointEYhigh(i,-1)
                    #print("zero bins in the data TGraph: bin",i+1)
                else:
                    TGraph_data.SetPoint(i,var_x,var_y)
                    err_low = var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y))
                    TGraph_data.SetPointEYlow(i, var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y)))
                    TGraph_data.SetPointEYhigh(i, (0.5*TMath.ChisquareQuantile(1.-0.1586555,2.*(var_y+1))) - var_y)
        
            TGraph_data.SetMarkerColor(1)
            TGraph_data.SetMarkerSize(1)
            TGraph_data.SetMarkerStyle(20)
            TGraph_data.Draw("same P")

    stack.GetYaxis().SetTitle("Events")
    stack.GetYaxis().SetTitleOffset(1.05)
    stack.GetYaxis().SetTitleSize(0.08)
    stack.GetYaxis().SetLabelSize(0.06)
    #stack.GetYaxis().CenterTitle()
    stack.GetXaxis().SetLabelSize(0.)
    #stack.GetXaxis().SetLabelOffset(0.013)
    #if "xaxis_range" in extraoptions:
    #    stack.GetXaxis().SetRangeUser(float(extraoptions["xaxis_range"][0]),float(extraoptions["xaxis_range"][1]))

    leg = r.TLegend(0.2, 0.60, 0.9, 0.88)
    leg.SetNColumns(3)
    leg.SetFillStyle(0)
    leg.SetBorderSize(0)
    leg.SetTextFont(42)
    leg.SetTextSize(0.05)
    for idx in range(len(h1_bkg)):
        leg.AddEntry(h1_bkg[idx], bkg_legends_[idx], "F")
    if "SR" in hist_s.GetTitle():
        leg.AddEntry(hist_s, 'HH #times {:1.2}'.format(sig_scale_), "L")

    leg.AddEntry(box, "Total  unc", "F")
    if h1_data:
        leg.AddEntry(h1_data, "Data", "ep")
    leg.Draw()

    pad2.cd()
    pad2.SetGridy(1)
    
    ratio = None
    ratio_Low  = 0.0
    ratio_High  = 4
    
    if h1_data:      
        ratio = TGraphAsymmErrors(h1_data)
        for i in range(ratio.GetN()):
            
            #bkg prediction
            imc = Double(hist_all.GetBinContent(i+1))
            #data point
            var_x, var_y = Double(0.), Double(0.)
            if not ("SR" in h1_data.GetTitle() and (i>5 and i<9)):
            	ratio.GetPoint(i,var_x,var_y)    
            if var_y == 0.:
                ratio.SetPoint(i,var_x,-1.0)
                ratio.SetPointEYlow(i,-1)
                ratio.SetPointEYhigh(i,-1)
                continue
            ratio.SetPoint(i,var_x,var_y/imc)
            err_low = (var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y)))/imc
            err_high = ((0.5*TMath.ChisquareQuantile(1.-0.1586555,2.*(var_y+1))) - var_y)/imc
            ratio.SetPointEYlow(i, err_low)
            ratio.SetPointEYhigh(i, err_high)
        
        ratio.SetMarkerColor(1)
        ratio.SetMarkerSize(1)
        ratio.SetMarkerStyle(20)
        ratio.GetXaxis().SetTitle("j_{2} regressed mass [GeV]")
        #myC.Update()
        
        if "ratio_range" in extraoptions:
            ratio_Low = extraoptions["ratio_range"][0]
            ratio_High = extraoptions["ratio_range"][1]
        ratio.GetYaxis().SetTitle("data/mc")
        ratio.GetYaxis().SetRangeUser(ratio_Low, ratio_High)
        ratio.GetXaxis().SetRangeUser(50, 220)
        ratio.SetTitle("")
        ratio.Draw("same AP")
        pad2.Update()
        
        print(ratio.GetTitle(),ratio.GetName(),"debug")
    else:
        ratio = h1_sig[0].Clone("ratio")
        ratio_High = 0.0
        for ibin in range(1,ratio.GetNbinsX()+1):
            s = hist_s.GetBinContent(ibin) 
            b = hist_b.GetBinContent(ibin)
            L = 0.0
            if b > 0.0:
                L = s/math.sqrt(b)
                if L > ratio_High:
                    ratio_High = L
            ratio.SetBinContent(ibin, L)
        if ratio_High > 1.0:
            ratio_High = 1.0
        ratio.GetYaxis().SetRangeUser(ratio_Low, ratio_High*1.2)
        ratio.GetYaxis().SetTitle("S/#sqrt{B}")
        ratio.Draw("samehist")
    ratio.SetLineColor(1)
    ratio.SetLineWidth(2)
    ratio.SetMarkerStyle(20)
    ratio.SetMarkerColor(1)
    ratio.SetFillColorAlpha(1, 0)
    ratio.GetXaxis().SetTitleOffset(0.94)
    ratio.GetXaxis().SetTitleSize(0.18)
    ratio.GetXaxis().SetLabelSize(0.12)
    ratio.GetXaxis().SetLabelOffset(0.013)
    ratio.GetYaxis().SetTitleOffset(0.40)
    ratio.GetYaxis().SetTitleSize(0.17)
    ratio.GetYaxis().SetLabelSize(0.13)
    ratio.GetYaxis().SetTickLength(0.01)
    ratio.GetYaxis().SetNdivisions(505)
    #if "xaxis_range" in extraoptions:
    #    ratio.GetXaxis().SetRangeUser(float(extraoptions["xaxis_range"][0]),float(extraoptions["xaxis_range"][1]))

    #draw  stack total unc on the ratio plot to present the background uncertainty
    box_ratio = r.TBox(0,0,1,1,)
    box_ratio.SetFillStyle(3002)
    box_ratio.SetLineWidth(0)
    box_ratio.SetFillColor(r.kBlack)
    for idx in range(h1_bkg[0].GetNbinsX()):
        if np.fabs(nS[idx])> 1e-06: 
            box_ratio.DrawBox(h1_bkg[0].GetBinCenter(idx+1)-0.5*h1_bkg[0].GetBinWidth(idx+1), (nS[idx]-eS[idx])/nS[idx], h1_bkg[0].GetBinCenter(idx+1)+0.5*h1_bkg[0].GetBinWidth(idx+1), (nS[idx]+eS[idx])/nS[idx])
        else:
            print("blinded Higgs peak region") 
    
    if "xaxis_label" in extraoptions and extraoptions["xaxis_label"] != None:
        x_title = extraoptions["xaxis_label"]
        ratio.GetXaxis().SetTitle(x_title)
    ratio.GetYaxis().CenterTitle()

    ##########draw CMS preliminary
    pad1.cd()
    tex1 = r.TLatex(leftMargin, 0.91, "CMS")
    tex1.SetNDC()
    tex1.SetTextFont(61)
    tex1.SetTextSize(0.070)
    tex1.SetLineWidth(2)
    tex1.Draw()
    tex2 = r.TLatex(leftMargin+0.12,0.912,"Internal")
    tex2.SetNDC()
    tex2.SetTextFont(52)
    tex2.SetTextSize(0.055)
    tex2.SetLineWidth(2)
    tex2.Draw()

    lumi_value = 137
    if "lumi_value" in extraoptions:
        lumi_value = extraoptions["lumi_value"]
    tex3 = r.TLatex(0.72,0.912,"%d"%lumi_value+" fb^{-1} (13 TeV)")
    tex3.SetNDC()
    tex3.SetTextFont(42)
    tex3.SetTextSize(0.055)
    tex3.SetLineWidth(2)
    tex3.Draw()
    outFile = dir_name_
    if output_name_:
        outFile = outFile + "/" +output_name_
    else:
        outFile = outFile + "/" + hist_name_

    #print("maxY = "+str(maxY))
    stack.SetMaximum(maxY*1.7)

    #print everything into txt file
    text_file = open(outFile+"_linY.txt", "w")
    text_file.write("bin    |   x    ")
    for idx in range(len(h1_bkg)):
        text_file.write(" | %21s"%bkg_legends_[idx])
    text_file.write(" | %21s"%("total B"))
    for idx in range(len(sig_legends_)):
        text_file.write(" | %25s"%sig_legends_[idx])
    if h1_data:
        text_file.write(" | data | data/mc")
    text_file.write("\n-------------")
    for idx in range(24*(len(h1_bkg) + 1)+ 29*len(sig_legends_)):
        text_file.write("-")
    if h1_data:
        text_file.write("-------")
    text_file.write("\n")
    for ibin in range(0,h1_sig[0].GetNbinsX()+1):
        text_file.write("%3d"%ibin+"   ")
        text_file.write(" | %6.3f"%h1_data.GetBinCenter(ibin)+" ")
        for idx in range(len(h1_bkg)):
            text_file.write(" | %7.3f "%h1_bkg[idx].GetBinContent(ibin)+"$\\pm$"+ " %7.3f"%h1_bkg[idx].GetBinError(ibin))
        text_file.write(" | %7.3f "%hist_b.GetBinContent(ibin)+"$\\pm$"+ " %7.3f"%hist_b.GetBinError(ibin))
        for idx in range(len(sig_legends_)):
            text_file.write(" | %9.3f "%h1_sig[idx].GetBinContent(ibin)+"$\\pm$"+ " %9.3f"%h1_sig[idx].GetBinError(ibin))
        if h1_data:
            text_file.write(" | %d"%h1_data.GetBinContent(ibin) +  " | %7.3f "%h1_data.GetBinContent(ibin) +"$\\pm$"+ " %7.3f"%h1_data.GetBinError(ibin))
        text_file.write("\n\n")
        
    #print yield table for AN
    text_file.write("print yield table for AN\n")
    bkg_all = 0
    bkg_all_errsq = 0
    for idx in range(len(h1_bkg)):
        bkg_tmp = h1_bkg[idx].GetBinContent(7)+h1_bkg[idx].GetBinContent(8)+h1_bkg[idx].GetBinContent(9)
        bkg_errsq_tmp = h1_bkg[idx].GetBinError(7)*h1_bkg[idx].GetBinError(7)+h1_bkg[idx].GetBinError(8)*h1_bkg[idx].GetBinError(8)+h1_bkg[idx].GetBinError(9)*h1_bkg[idx].GetBinError(9)
        bkg_all += bkg_tmp
        bkg_all_errsq += bkg_errsq_tmp
        text_file.write("%s"%(bkg_legends_[idx])+"& %7.2f"%(bkg_tmp)+"$\\pm$"+ "%7.2f"%np.sqrt(bkg_errsq_tmp)+"\n")
    text_file.write("total background & %7.2f"%(bkg_all)+"$\\pm$"+ "%7.2f"%np.sqrt(bkg_all_errsq)+"\n")
    
    text_file.write("\ggHH SM ($\kapl=1$) & %7.2f"%((h1_sig[0].GetBinContent(7)+h1_sig[0].GetBinContent(8)+h1_sig[0].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.1f"%(sig_scale_*np.sqrt(h1_sig[0].GetBinError(7)*h1_sig[0].GetBinError(7)+h1_sig[0].GetBinError(8)*h1_sig[0].GetBinError(8)+h1_sig[0].GetBinError(9)*h1_sig[0].GetBinError(9)))+"\n")
    text_file.write("\VBFHH SM ($\kapl=1$) & %7.2f"%((h1_sig[1].GetBinContent(7)+h1_sig[1].GetBinContent(8)+h1_sig[1].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.1f"%(sig_scale_*np.sqrt(h1_sig[1].GetBinError(7)*h1_sig[1].GetBinError(7)+h1_sig[1].GetBinError(8)*h1_sig[1].GetBinError(8)+h1_sig[1].GetBinError(9)*h1_sig[1].GetBinError(9)))+"\n")
    
    text_file.write("HH bin 8 value %s"%h1_sig[0].GetBinContent(8)+"\n")
    text_file.write("HH bin 9 value %s"%h1_sig[0].GetBinContent(9)+"\n")
    text_file.write("HH bin 7 value %s"%h1_sig[0].GetBinContent(7)+"\n")

    text_file.write("HH bin 8 error %s"%h1_sig[0].GetBinError(8)+"\n")
    text_file.write("HH bin 9 error %s"%h1_sig[0].GetBinError(9)+"\n")
    text_file.write("HH bin 7 error %s"%h1_sig[0].GetBinError(7)+"\n")
    
    text_file.write("total & %7.2f"%(bkg_all+(h1_sig[0].GetBinContent(7)+h1_sig[0].GetBinContent(8)+h1_sig[0].GetBinContent(9)+h1_sig[1].GetBinContent(7)+h1_sig[1].GetBinContent(8)+h1_sig[1].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.2f"%(np.sqrt((h1_sig[0].GetBinError(7)*h1_sig[0].GetBinError(7)+h1_sig[0].GetBinError(8)*h1_sig[0].GetBinError(8)+h1_sig[0].GetBinError(9)*h1_sig[0].GetBinError(9))/(sig_scale_*sig_scale_)+(h1_sig[1].GetBinError(7)*h1_sig[1].GetBinError(7)+h1_sig[1].GetBinError(8)*h1_sig[1].GetBinError(8)+h1_sig[1].GetBinError(9)*h1_sig[1].GetBinError(9))/(sig_scale_*sig_scale_)+bkg_all_errsq))+"\n")
    
    text_file.close()
    os.system("cp "+outFile+"_linY.txt "+outFile+"_logY.txt")

    pad1.RedrawAxis()
    myC.SaveAs(outFile+"_linY.png")
    myC.SaveAs(outFile+"_linY.pdf")
    myC.SaveAs(outFile+"_linY.C")
    pad1.cd()
    stack.SetMaximum(maxY*100.0)
    stack.SetMinimum(0.5)
    pad1.SetLogy()
    pad1.RedrawAxis()
    myC.SaveAs(outFile+"_logY.png")
    myC.SaveAs(outFile+"_logY.pdf")
    myC.SaveAs(outFile+"_logY.C")
    #save histogram and ratio to root file
    outFile_root = r.TFile(outFile+".root", "recreate")
    outFile_root.cd()
    for idx in range(len(h1_bkg)):
        h1_bkg[idx].Write()
    for idx in range(len(sig_legends_)):
        h1_sig[idx].Write()
    if  h1_data:
        h1_data.Write()
        ratio.Write()
    #outFile_root.Write()
    outFile_root.Close()
		ey_lo_ratio = 0.0
	else:
		ey_lo_ratio = y_ratio * math.hypot(ey_lo_mu / y_mu, ey_lo_ele / y_ele)

	ey_hi_mu = grMu.GetErrorYhigh(i)
	ey_hi_ele = grEle.GetErrorYhigh(i)
	if y_mu < 1.e-9 or y_ele < 1.e-9:
		ey_hi_ratio = 0.0
	else:
		ey_hi_ratio = y_ratio * math.hypot(ey_hi_mu / y_mu, ey_hi_ele / y_ele)

	grRatio.SetPoint(i, x, y_ratio)
	grRatio.SetPointEXlow(i, ex_lo)
	grRatio.SetPointEXhigh(i, ex_hi)
	grRatio.SetPointEYlow(i, ey_lo_ratio)
	grRatio.SetPointEYhigh(i, ey_hi_ratio)

if True:
    grRatio.SetMarkerStyle(20)
    grRatio.SetMarkerSize(1.5)
    grRatio.SetMarkerColor(1)

    grRatio.SetLineStyle(1)
    grRatio.SetLineColor(1)
    grRatio.SetLineWidth(1)

    grRatio.GetXaxis().SetLabelSize(0.04)
    grRatio.GetXaxis().SetTitleSize(0.04)
    grRatio.GetXaxis().SetTitleOffset(1.25)

    grRatio.GetYaxis().SetLabelSize(0.04)