Beispiel #1
0
def calcAndDrawSignificance(SignalHist,
                            BkgrHist,
                            xtitle,
                            legendNames,
                            DataName,
                            destination,
                            year,
                            ylog=False,
                            customLabels=None,
                            extraText=None,
                            scaleSignalToBkgr=False,
                            DivideByLine=None):
    GeneralSettings()

    #Make sure the code works for single backgrounds
    if not isinstance(BkgrHist, (list, )):
        BkgrHist = [BkgrHist]
    if not isinstance(SignalHist, (list, )):
        SignalHist = [SignalHist]

    BkgrHist, legendNames = orderHist(BkgrHist, legendNames, True)

    #Add all backgrounds
    totBkgr = BkgrHist[0].Clone("TotBkgr")
    for h in BkgrHist[1:]:
        totBkgr.Add(h)

    #Normalize signal to background if needed
    if scaleSignalToBkgr:
        for h in SignalHist:
            h.scale(totBkgr.GetSumOfWeights() / h.GetSumOfWeights)

    #Define a canvas
    Canv = TCanvas("Canv" + destination, "Canv" + destination, 1500, 1000)

    #Set Histogram Styles
    for h, n in zip(BkgrHist, legendNames):
        h.SetFillColor(TColor.GetColor(GetStackColorTauPOGbyName(n)))
        h.SetLineColor(TColor.GetColor(GetStackColorTauPOGbyName(n)))

    for i, h in enumerate(SignalHist):
        h.SetMarkerColor(TColor.GetColor(GetLineColor(i)))
        h.SetLineColor(TColor.GetColor(GetLineColor(i)))
        h.SetMarkerStyle(GetMarker(i))

    list_of_significance_hists = []
    for i, sh in enumerate(SignalHist):
        #Calculate significance
        total = totBkgr.Clone("Total")
        total.Add(sh)
        sqrt_total = total.Clone('Sqrt_Total')
        for xbin in xrange(
                1,
                total.GetSize() - 1
        ):  #GetSize returns nbins + 2 (for overflow and underflow bin)
            sqrt_x = np.sqrt(total.GetBinContent(xbin))
            sqrt_total.SetBinContent(xbin, sqrt_x)
            sqrt_total.SetBinError(xbin,
                                   0.5 * total.GetBinError(xbin) / sqrt_x)

        significance = sh.Clone('Signal' + str(i))
        significance.Divide(sqrt_total)
        list_of_significance_hists.append(significance)

    #First pad
    plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98)
    plotpad.SetBottomMargin(0.025)
    plotpad.Draw()
    plotpad.cd()

    #Create Stack (Change with most logical ordering)
    hs = THStack("hs", "hs")
    for h in BkgrHist:
        hs.Add(h)
    hs.Draw(
        "EHist"
    )  #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4
    title = " ; ; Events"
    hs.SetTitle(title)
    #    hs.GetHistogram().GetXaxis().SetTickLength(0)
    hs.GetHistogram().GetXaxis().SetLabelOffset(9999999)
    #hs.GetHistogram().SetMaximum(1)
    #Set range
    overallMin = GetOverallMinimum(BkgrHist + SignalHist, True)
    overallMax = GetOverallMaximum([totBkgr] + SignalHist)

    if ylog:
        if overallMin == 0.:
            overallMin = 0.1
        ymin = 0.3 * overallMin
        ymax = 30 * overallMax
        plotpad.SetLogy()
    else:
        ymin = 0.7 * overallMin
        ymax = 1.3 * overallMax
    hs.SetMinimum(ymin)
    hs.SetMaximum(ymax)

    for h in SignalHist:
        h.Draw("EPSame")
    #Create Legend
    legend = TLegend(0.7, .7, .9, .9)
    for h, n in zip(BkgrHist, legendNames):
        legend.AddEntry(h, n)
    for h, n in zip(SignalHist, DataName):
        legend.AddEntry(h, n)
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

    legend.Draw()

    #Draw lines if needed
    if DivideByLine is not None:
        tdrStyle_Left_Margin = 0.16
        tdrStyle_Right_Margin = 0.02
        plot_size_hor = 1 - tdrStyle_Left_Margin - tdrStyle_Right_Margin
        #Option one, user provides the number of divisions and we divide equally
        if isinstance(DivideByLine[0], int):
            x_pos = np.linspace(totBkgr.GetXaxis().GetXmin(),
                                totBkgr.GetXaxis().GetXmax(),
                                DivideByLine[0] + 1)
        #Option two, user provides the specific boundaries
        if isinstance(DivideByLine[0], (list, )):
            x_pos = DivideByLine[0]

        #Draw the lines
        lines = []
        for i, x in enumerate(x_pos[1:-1]):
            lines.append(TLine(x, ymin, x, ymax))
            lines[i].SetLineColor(ROOT.kRed)
            lines[i].SetLineStyle(10)

        for line in lines:
            line.Draw('same')

        #Add extra text
        for i, name in enumerate(DivideByLine[1]):
            x = ((x_pos[i + 1] + x_pos[i]) /
                 (2 * (x_pos[-1] - x_pos[0]) /
                  plot_size_hor)) + tdrStyle_Left_Margin
            extraText.append(extraTextFormat(name, x, 0.1, None, 22))

    #Draw extra text if needed
    if extraText is not None:
        DrawExtraText(plotpad, extraText)

    #Return to canvas
    Canv.cd()

    #Second pad
    ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3)
    ratiopad.SetTopMargin(0.05)
    ratiopad.SetBottomMargin(0.25)
    ratiopad.Draw()
    ratiopad.cd()

    #print list_of_significance_hists[0].GetMaximum(), list_of_significance_hists[1].GetMaximum(), list_of_significance_hists[2].GetMaximum()
    overallMin = GetOverallMinimum(list_of_significance_hists)
    overallMax = GetOverallMaximum(list_of_significance_hists)

    significance = list_of_significance_hists[0]

    #Prepare lines before changing maximum
    lines_bottom = []
    for i, sig in enumerate(list_of_significance_hists):
        lines_bottom.append(
            TLine(sig.GetXaxis().GetXmin(), sig.GetMaximum(),
                  sig.GetXaxis().GetXmax(), sig.GetMaximum()))
        lines_bottom[i].SetLineColor(TColor.GetColor(GetLineColor(i)))
        lines_bottom[i].SetLineStyle(3)

    #Set Style for bottom plot
    significance.SetTitle(";" + xtitle + "; S/#sqrt{S+B}")
    significance.GetXaxis().SetTitleSize(.12)
    significance.GetYaxis().SetTitleSize(.12)
    significance.GetYaxis().SetTitleOffset(.6)
    significance.GetXaxis().SetLabelSize(.12)
    significance.GetYaxis().SetLabelSize(.12)
    significance.SetMinimum(0.)
    significance.SetMaximum(1.3 * overallMax)
    significance.Draw("EP")

    for sig in list_of_significance_hists[1:]:
        sig.Draw('EPSame')

    for line in lines_bottom:
        line.Draw("same")

    #Set custom x labels
    xaxis = significance.GetXaxis()
    if customLabels != None:
        number_of_bins = significance.GetNbinsX()

        if number_of_bins != len(customLabels):
            if DivideByLine is not None:
                for i in range(number_of_bins):
                    xaxis.SetBinLabel(
                        i + 1, customLabels[i % len(customLabels)]
                    )  #Only works when DivideByLine[0] is an integer
            else:
                print 'Please provide ' + str(
                    number_of_bins) + ' labels instead of ' + str(
                        len(customLabels))
                return
        else:
            for i, label in zip(range(number_of_bins), customLabels):
                xaxis.SetBinLabel(i + 1, label)

    #Throw CMs lumi at it
    cl.CMS_lumi(Canv, 4, 11, year, 'Simulation Preliminary', True)

    #Save everything
    savePlots(Canv, destination)
    ROOT.SetOwnership(
        Canv, False
    )  #https://root-forum.cern.ch/t/tlatex-crashing-in-pyroot-after-many-uses/21638/4
    return
Beispiel #2
0
def plotDataVSMC(DataHist,
                 MCHist,
                 xtitle,
                 legendNames,
                 DataName,
                 destination,
                 year,
                 ytitle_bottom='Data/MC',
                 ylog=False):
    GeneralSettings()

    Canv = TCanvas("Canv" + destination, "Canv" + destination, 1000, 1000)

    #Set Histogram Styles
    for i, h in enumerate(MCHist):
        h.SetFillColor(
            TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i])))
        h.SetLineColor(
            TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i])))

    DataHist.SetMarkerColor(ROOT.kBlack)
    DataHist.SetLineColor(ROOT.kBlack)
    DataHist.SetMarkerStyle(20)

    #Add all MC samples to use in ratios
    totBkgr = MCHist[0].Clone("totBkgr")
    for h in MCHist[1:]:
        totBkgr.Add(h)
    DataOverMC = DataHist.Clone("DataOverMC")
    DataOverMC.Divide(totBkgr)

    #Errors
    predStatError = totBkgr.Clone("PredictedStatError")
    predSystError = totBkgr.Clone("PredictedSystError")
    predTotError = totBkgr.Clone("PredictedTotalError")
    for b in xrange(predSystError.GetNbinsX() + 1):
        predSystError.SetBinError(b, 0.3 * totBkgr.GetBinContent(b))
        syst = predSystError.GetBinError(b)
        stat = predStatError.GetBinError(b)
        predTotError.SetBinError(b, np.sqrt(stat * stat + syst * syst))

    #predTotError.SetFillStyle(3013)
    #predTotError.SetFillColor(ROOT.kGray+2)
    #predTotError.SetMarkerStyle(0)
    #predTotError.Draw("E2 Same")

    #First pad
    plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98)
    plotpad.SetBottomMargin(0.025)
    plotpad.Draw()
    plotpad.cd()

    #Create Stack (Change with most logical ordering)
    hs = THStack("hs", "hs")
    for h in MCHist:
        hs.Add(h)
    hs.Draw(
        "EHist"
    )  #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4
    title = " ; ; Events / " + str(MCHist[0].GetBinWidth(1)) + " GeV"
    hs.SetTitle(title)
    #    hs.GetHistogram().GetXaxis().SetTickLength(0)
    hs.GetHistogram().GetXaxis().SetLabelOffset(9999999)
    hs.GetHistogram().SetMaximum(1)

    #Set range
    overallMin = GetOverallMinimum(MCHist + [DataHist])
    overallMax = GetOverallMaximum([totBkgr] + [DataHist])
    if ylog:
        plotpad.SetLogy()
        hs.SetMinimum(0.3 * overallMin)
        hs.SetMaximum(10 * overallMax)
    else:
        hs.SetMinimum(0.5 * overallMin)
        hs.SetMaximum(1.7 * overallMax)

    DataHist.Draw("EPSame")

    predTotError.SetFillStyle(3013)
    predTotError.SetFillColor(ROOT.kGray + 2)
    predTotError.SetMarkerStyle(0)
    predTotError.Draw("E2 Same")

    #Create Legend
    legend = TLegend(0.7, .7, .9, .9)
    for h, n in zip(MCHist, legendNames):
        legend.AddEntry(h, n)
    legend.AddEntry(DataHist, DataName)
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

    legend.Draw()

    #Return to canvas
    Canv.cd()

    #Second pad
    ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3)
    ratiopad.SetTopMargin(0.05)
    ratiopad.SetBottomMargin(0.25)
    ratiopad.Draw()
    ratiopad.cd()

    #Errors
    StatErrorRatio = predStatError.Clone("StatErrorRatio")
    StatErrorRatio.SetFillStyle(1001)
    StatErrorRatio.SetFillColor(TColor.GetColor('#6EF9F5'))
    TotErrorRatio = predTotError.Clone("SystErrorRatio")
    TotErrorRatio.SetFillColor(TColor.GetColor('#63E2C6'))
    TotErrorRatio.SetFillStyle(1001)
    for b in xrange(StatErrorRatio.GetNbinsX() + 1):
        if (StatErrorRatio.GetBinContent(b) != 0):
            StatErrorRatio.SetBinError(
                b,
                StatErrorRatio.GetBinError(b) /
                StatErrorRatio.GetBinContent(b))
            TotErrorRatio.SetBinError(
                b,
                TotErrorRatio.GetBinError(b) / TotErrorRatio.GetBinContent(b))
            StatErrorRatio.SetBinContent(b, 1.)
            TotErrorRatio.SetBinContent(b, 1.)
        else:
            StatErrorRatio.SetBinContent(b, 0)
            TotErrorRatio.SetBinContent(b, 0)

    #Set Style for bottom plot
    DataOverMC.SetTitle(";" + xtitle + "; " + ytitle_bottom)
    DataOverMC.GetXaxis().SetTitleSize(.12)
    DataOverMC.GetYaxis().SetTitleSize(.12)
    DataOverMC.GetYaxis().SetTitleOffset(.6)
    DataOverMC.GetXaxis().SetLabelSize(.12)
    DataOverMC.GetYaxis().SetLabelSize(.12)
    DataOverMC.SetMinimum(0.3)
    DataOverMC.SetMaximum(1.7)
    DataOverMC.Draw("EP")
    TotErrorRatio.Draw("E2 same")
    StatErrorRatio.Draw("E2 same")
    DataOverMC.Draw("EPsame")

    #Draw a guide for the eye
    line = TLine(DataOverMC.GetXaxis().GetXmin(), 1,
                 DataOverMC.GetXaxis().GetXmax(), 1)
    line.SetLineColor(ROOT.kRed)
    line.SetLineWidth(1)
    line.SetLineStyle(1)
    line.Draw("Same")

    #Create Legend
    legend_bottom = TLegend(0.2, .8, .9, .9)
    legend_bottom.SetNColumns(3)
    legend_bottom.AddEntry(DataOverMC, "Obs./Pred.")
    legend_bottom.AddEntry(StatErrorRatio, "Stat. Unc.")
    legend_bottom.AddEntry(TotErrorRatio, "Tot. Unc.")
    legend_bottom.SetFillStyle(0)
    legend_bottom.SetBorderSize(0)

    legend_bottom.Draw()

    #Throw CMs lumi at it
    cl.CMS_lumi(Canv, 4, 11, year, 'Preliminary', True)
    print 'save'

    #Save everything
    savePlots(Canv, destination)
    print 'saved'
Beispiel #3
0
def plotRatio(name, h1, v_hist, hs, log):
    c = Canvas('c')

    h_sum = TH1F('h_sum','sum',h1.GetNbinsX(), h1.GetXaxis().GetXmin(), h1.GetXaxis().GetXmax())
    for h in v_hist: h_sum.Add(h)
 
    pad1 = TPad('pad1', 'pad1', 0.0, 0.3, 1., 1.)
    pad1.SetBottomMargin(0.005)
    pad1.SetTicks(1,1)
    pad1.Draw()

    c.cd()
    pad2 = TPad('pad2', 'pad2', 0., 0.05, 1., 0.28)
    pad2.SetTopMargin(0.005)
    pad2.SetBottomMargin(0.3)
    pad2.SetTicks(1,1)
    pad2.Draw()

    pad1.cd()
    if log: pad1.SetLogy()
    stack = THStack('norm_stack','')
    h_mc_err = 0
    for h in v_hist: 
        stack.Add(h)
        if h_mc_err == 0: h_mc_err = h.Clone()
        else: h_mc_err.Add(h)
    stack.Draw('HIST')
    h_mc_err.Draw("e2 same")
    h_mc_err.SetMarkerSize(0)
    h_mc_err.SetFillColor(1)
    h_mc_err.SetFillStyle(3004)
    h_data = asym_error_bars(h1)
    h_data.SetLineColor(ROOT.kBlack)
    h_data.SetFillColor(ROOT.kBlack)
    h_data.SetLineWidth(2)
    h_data.Draw('p e2 same')
    hs.Draw('HIST same')
    ymax = h1.GetMaximum()*pow(10,1.0) if log else h1.GetMaximum()*1.5 
    stack.SetMaximum(ymax)
    if log: stack.SetMinimum(1)
    #stack.GetHistogram().GetYaxis().SetTitleFont(43)
    stack.GetHistogram().GetYaxis().SetTitleOffset(1.0)
    stack.GetHistogram().GetYaxis().SetTitleSize(0.05)
    stack.GetHistogram().GetYaxis().SetTitle('Events')
    pLabel, sLabel, lLabel = prelimLabel('left',log,h1.GetMaximum()), selectionLabel(lab,True,log,h1.GetMaximum()), lumiLabel(True,years)
    pLabel.Draw(), sLabel.Draw(), lLabel.Draw()
    legend = makeLegend(h1,v_hist,hs)
    legend.Draw()

    pad2.cd()
    h_ratio = h1.Clone('h_ratio')

    h_ratio.Sumw2()
    h_ratio.Divide(h_sum)
    h_ratio.SetMinimum(-0.499)
    h_ratio.SetMaximum(2.499)
    h_ratio.SetLineColor(ROOT.kBlack)
    h_ratio.SetMarkerStyle(20)
    h_ratio.SetMarkerColor(ROOT.kBlack)
    h_ratio.SetMarkerSize(0.7)
    h_ratio.Draw('p same')
    denom_err, denom_err2 = h_mc_err.Clone(), h_mc_err.Clone()
    denom_err2.Sumw2(False)
    denom_err.Divide(denom_err2)
    denom_err.Draw("e2same")
    denom_err.SetFillColor(1)
    denom_err.SetFillStyle(3004)

    l1 = TLine(h_ratio.GetXaxis().GetXmin(), 1, h_ratio.GetXaxis().GetXmax(), 1)
    l2 = TLine(h_ratio.GetXaxis().GetXmin(), 1.5, h_ratio.GetXaxis().GetXmax(), 1.5)
    l3 = TLine(h_ratio.GetXaxis().GetXmin(), 0.5, h_ratio.GetXaxis().GetXmax(), 0.5)
    l4 = TLine(h_ratio.GetXaxis().GetXmin(), 0., h_ratio.GetXaxis().GetXmax(), 0.)
    l5 = TLine(h_ratio.GetXaxis().GetXmin(), 2, h_ratio.GetXaxis().GetXmax(), 2.)
    l2.SetLineStyle(3), l3.SetLineStyle(3), l4.SetLineStyle(3), l5.SetLineStyle(3)
    l1.Draw(), l2.Draw(), l3.Draw(), l4.Draw(), l5.Draw()

    Prettify( h_ratio )

    #ax  = h_ratio.GetXaxis();
    #ax.SetNdivisions(506);

    if len(years) == 1: c.SaveAs('plots/%s/%s_%s.%s' % (years[0],name,selection,extension))
    else: c.SaveAs('plots/combined/%s_%s_%s.%s' % (name,selection,s_years,extension)) 
Beispiel #4
0
class BinnedAndIncl(plotterBase):
    def __init__(self, cvs_params):
        leg_size = cvs_params["leg_size"]
        logy = cvs_params["logy"]
        grid = cvs_params["grid"]
        super().__init__(cvs_type="ratio", leg_size=leg_size, logy=logy, grid=grid)

    def get_hists(self, hist_incl, hists_binned, hist_params):
        rebin = hist_params["rebin"]
        self.hist_incl = None
        self.hists_binned = {}
        self.stack = THStack("stack", "")
        self.syst = None
        self.ratio = None
        self.ratio_syst = None

        # Store histograms
        print("INFO: Storing histograms...")
        print("INFO: histograms automatically normalized to L = 150 fb^-1")
        self.hist_incl = self.__rebin(hist_incl, hist_params)
        for name, hist in hists_binned.items():
            self.hists_binned[name] = self.__rebin(hist, hist_params)

        self.__decorate_hists(hist_params)
        self.__make_stack_and_syst()
        self.__make_ratio(hist_params)

    def combine(self, info_params):
        info = info_params["info"]
        cmsText = info_params["cms_text"]
        extraText = info_params["extra_text"]

        super().pad_up().cd()
        self.hist_incl.Draw("p&hist")
        self.stack.Draw("hist & pfc & same")
        self.syst.Draw("e2 & f & same")
        self.hist_incl.Draw("p&hist&same")
        self.hist_incl.Draw("e1 & same")

        super().legend().Draw()
        super().info().DrawLatexNDC(0.63, 0.91, info)
        super().logo().DrawLatexNDC(0.15, 0.83, cmsText)
        super().extra_logo().DrawLatexNDC(0.15, 0.78, extraText)

        super().pad_down().cd()
        self.ratio.Draw("p & hist")
        self.ratio_syst.Draw("e2&f&same")

        super().cvs().cd()
        super().pad_up().Draw()
        super().pad_down().Draw()

    def __rebin(self, hist, hist_params):
        rebin = hist_params["rebin"]
        if rebin == -1:
            pass
        else:
            hist.Rebin(rebin)
        if "x_range" in hist_params.keys():
            x_range = hist_params["x_range"]
            hist.GetXaxis().SetRangeUser(x_range[0], x_range[1])
        return hist

    def __decorate_hists(self, hist_params):
        y_title = hist_params["y_title"]

        # y axis scale is just the Maximum of inclusive sample
        print("INFO: y axis range set to be maximum of inclusive plot...")
        y_range = self.hist_incl.GetMaximum()

        # decorate self.hist_incl
        self.hist_incl.SetStats(0)
        self.hist_incl.SetMarkerStyle(8)
        self.hist_incl.SetMarkerSize(0.5)
        self.hist_incl.SetMarkerColor(1)

        # X axis
        self.hist_incl.GetXaxis().SetLabelSize(0)

        # Y axis
        self.hist_incl.GetYaxis().SetTitle(y_title)
        self.hist_incl.GetYaxis().SetRangeUser(0., y_range*1.2)
        if self.logy:
            self.hist_incl.GetYaxis().SetRangeUser(1., y_range*100.)

        for name, hist in self.hists_binned.items():
            hist.GetXaxis().SetLabelSize(0)

        # add to legend
        super().legend().AddEntry(self.hist_incl, "Incl", "lep")

    def __make_stack_and_syst(self):
        print("WARNING: Make sure that histograms are properly scaled")
        for name, hist in self.hists_binned.items():
            hist.GetXaxis().SetLabelSize(0)
            self.stack.Add(hist)
            super().legend().AddEntry(hist, name, "f")

            if self.syst == None:
                self.syst = hist.Clone("syst")
            else:
                self.syst.Add(hist)

        self.stack.Draw()
        self.stack.GetHistogram().GetXaxis().SetLabelSize(0)
        self.syst.SetStats(0)
        self.syst.SetFillColorAlpha(12, 0.6)
        self.syst.SetFillStyle(3144)
        self.syst.GetXaxis().SetLabelSize(0)
        super().legend().AddEntry(self.syst, "stat err", "f")

    def __make_ratio(self, hist_params):
        error_range = hist_params["error_range"]
        x_title = hist_params["x_title"]

        self.ratio = self.hist_incl.Clone("ratio")
        self.ratio.Divide(self.syst)
        self.ratio_syst = self.ratio.Clone("ratio_syst")

        self.ratio.SetStats(0)
        self.ratio.SetTitle("")
        # y axis
        self.ratio.GetYaxis().SetRangeUser(error_range[0], error_range[1])
        self.ratio.GetYaxis().SetTitle("Incl / binned")
        self.ratio.GetYaxis().SetTitleSize(0.08)
        self.ratio.GetYaxis().SetTitleOffset(0.5)
        self.ratio.GetYaxis().SetLabelSize(0.08)
        # x axis
        self.ratio.GetXaxis().SetTitle(x_title)
        self.ratio.GetXaxis().SetTitleSize(0.1)
        self.ratio.GetXaxis().SetTitleOffset(0.8)
        self.ratio.GetXaxis().SetLabelSize(0.08)

        self.ratio_syst.SetStats(0)
        self.ratio_syst.SetFillColorAlpha(12, 0.6)
        self.ratio_syst.SetFillStyle(3144)
Beispiel #5
0
def drawHisto(histlist,histoD,xTitle,yTitle,outName,uncHists=""):    
    legend = TLegend(0.35, 0.72, 0.85, 0.92,"") #,"brNDC"
    legend.SetFillStyle(0)

    legend.SetTextSize(0.045)
    legend.SetNColumns(2)

    myStack = THStack("myStack","")
    for hist in histlist:
        myStack.Add(hist,"hist")
    
    histoErr = histlist[0].Clone()
    for iHist in range(1,len(histlist)):
        histoErr.Add(histlist[iHist])
        
    MCCount = myStack.GetStack().Last().Integral()
    DataCount = histoD.Integral()
    MCNormFactor = DataCount/MCCount

#    myStack.Delete()
    myStack = THStack("myStack","")

    for hist in histlist:
        hist.Scale(MCNormFactor)
        myStack.Add(hist,"hist")
        

    histoErr.Scale(MCNormFactor)
    

    if uncHists!="":
        MCMean = myStack.GetStack().Last().Clone()
        MCErr = MCMean.Clone()
        MCErr.Reset()
        for ibin in range(1,MCMean.GetNbinsX()+1):
            thisbinunc = 0
            for ihist in uncHists:
                thisbinunc += ihist.GetBinContent(ibin)**2     #sum assuming correlated
            sfunc = thisbinunc**0.5*MCNormFactor
            if args.nostat:
                MCMean.SetBinError(ibin, sfunc)
                MCErr.SetBinContent(ibin, sfunc)
            else:
                MCMean.SetBinError(ibin, math.sqrt(sfunc**2 + histoErr.GetBinError(ibin)**2))
                MCErr.SetBinContent(ibin, math.sqrt(sfunc**2 + histoErr.GetBinError(ibin)**2))
        
    c = TCanvas("main","main",1200,1200)
    c.SetCanvasSize(1200,1200)
    
    upperCanvas = TPad("up","up",0,0.24,1,1)
    upperCanvas.SetBottomMargin(0.03)
    upperCanvas.SetLeftMargin(0.12)
    upperCanvas.SetTopMargin(0.06)
#    upperCanvas.SetLogy(isLog)
    upperCanvas.Draw()
    upperCanvas.cd()
    
    myStack.Draw()
    myStack.GetYaxis().SetTitle(yTitle)
    myStack.GetHistogram().GetZaxis().SetTitle()

    myStack.GetYaxis().SetLabelSize(0.048)
    myStack.GetYaxis().SetTitleSize(0.07)
    myStack.GetYaxis().SetTitleOffset(0.78)
    myStack.GetYaxis().SetTitleFont(42)
    legend.Draw("same")

    if uncHists!="":
        MCMean.Draw("e2 same")
        MCMean.SetFillColor(kGreen)
        MCMean.SetLineColor(kGreen)
        MCMean.SetMarkerSize(0)
        MCMean.SetFillStyle(3013)
        
    if not args.nostat:
        histoErr.Draw("e2 same")
        # histoErr.Sumw2()
        histoErr.SetFillColor(kGray+3)
        histoErr.SetLineColor(kGray+3)
        histoErr.SetMarkerSize(0)
        histoErr.SetFillStyle(3013)       

    histoMC = myStack.GetStack().Last()
    histoBkg= myStack.GetStack().Before(histoMC)

    print "Total MC:", histoMC.Integral(), ", Data:",histoD.Integral()


    histoD.Draw("same p e")
    legend.AddEntry(histoD,"Data","PE")
    
    for hist in histlist:
        legend.AddEntry(hist,hist.GetName().replace('uds','udsg').replace('b','bottom').replace('c','charm'),'f')
    legend.AddEntry(histoErr,"MC Stat. Unc.",'f')
    if uncHists!="": legend.AddEntry(MCMean,"SF Unc.",'f')
    maxY = histoD.GetMaximum()
    
    #if myStack.GetMinimum() >= 0:
    myStack.SetMinimum(1e-3)
    myStack.SetMaximum(maxY*1.35)


    c.cd()
    lowerCanvas = TPad("down","down",0,0,1,0.26)
    lowerCanvas.Draw()
    lowerCanvas.cd()
    lowerCanvas.SetTicky(1)
    lowerCanvas.SetLeftMargin(0.1)
    lowerCanvas.SetRightMargin(0.1)
    lowerCanvas.SetTopMargin(0.0)
    lowerCanvas.SetBottomMargin(0.4)
    lowerCanvas.SetLeftMargin(0.12)
    lowerCanvas.SetFrameFillStyle(0)
    lowerCanvas.SetFrameBorderMode(0)
    lowerCanvas.SetGridy()

    histoRatio = histoD.Clone()
    histoRatio.Divide(histoMC)
    for ib in range(1,histoRatio.GetNbinsX()+1):
        if histoD.GetBinContent(ib) != 0:
            histoRatio.SetBinError(ib, histoD.GetBinError(ib)/histoD.GetBinContent(ib)*histoRatio.GetBinContent(ib))
        else:
            histoRatio.SetBinError(ib,0.)

    histoRatio.GetYaxis().SetTitle("Data/MC")
    histoRatio.GetYaxis().SetTitleSize(0.15)
    histoRatio.GetYaxis().SetTitleOffset(0.38)
    histoRatio.GetYaxis().SetTitleFont(42)
    histoRatio.GetYaxis().SetLabelSize(0.14)
    histoRatio.GetYaxis().CenterTitle()
    histoRatio.GetYaxis().SetLabelFont(42)
    histoRatio.GetYaxis().SetNdivisions(5)

    histoRatio.GetXaxis().SetTitle(xTitle)
    histoRatio.GetXaxis().SetLabelSize(0.14)
    histoRatio.GetXaxis().SetTitleSize(0.19)
    histoRatio.GetXaxis().SetTitleOffset(0.88)
    histoRatio.GetXaxis().SetTitleFont(42)
    histoRatio.GetXaxis().SetTickLength(0.07)
    histoRatio.GetXaxis().SetLabelFont(42)
    histoRatio.SetTitle("")

    histoRatio.Draw("P e")
    histoRatio.SetMaximum(1.49)
    histoRatio.SetMinimum(0.51)

    if uncHists!="":
        RatioErr = MCErr.Clone()
        RatioErr.Divide(histoMC)
        RatioErrVals = RatioErr.Clone()
        for ibin in range(1,RatioErr.GetNbinsX()+1):
            RatioErrVals.SetBinContent(ibin,1.)
            RatioErrVals.SetBinError(ibin,RatioErr.GetBinContent(ibin))

        RatioErrVals.Draw("e2 same")
        RatioErrVals.SetFillColor(kGreen)
        RatioErrVals.SetLineColor(kGreen)
        RatioErrVals.SetMarkerSize(0)
        RatioErrVals.SetFillStyle(3013)

    if not args.nostat:
        RatioStatUnc = histoMC.Clone()
        for ibin in range(1,RatioStatUnc.GetNbinsX()+1):
            RatioStatUnc.SetBinContent(ibin,1)
            if histoMC.GetBinContent(ibin) != 0:
                RatioStatUnc.SetBinError(ibin,histoMC.GetBinError(ibin)/histoMC.GetBinContent(ibin))
            else:
                RatioStatUnc.SetBinError(ibin,0)

        RatioStatUnc.Draw("e2 same")
        RatioStatUnc.SetFillColor(kGray+3)
        RatioStatUnc.SetLineColor(kGray+3)
        RatioStatUnc.SetMarkerSize(0)
        RatioStatUnc.SetFillStyle(3013) 
    
    histoRatio.Draw("P e same")  # To bring on top

    hLine = TLine(-0.2,1,1,1)
    hLine.SetLineColor(kRed)
    hLine.Draw()

#    if drawDataMCRatioLine:
#        MCCount = histoMC.Integral()
#        if MCCount > 0.:
#            DataCount = histoD.Integral()
#            MCNormFactor = DataCount/MCCount
#            hLine2 = TLine(start,MCNormFactor,end,MCNormFactor)
#            hLine2.SetLineColor(kBlue)
#            hLine2.Draw()

    # ----------------------------------------------------------

    # ======================== LaTeX ==========================
    texTL = TLatex()
    texTL.SetTextSize(0.07)
    texTL.SetTextAlign(13)

    texTR = TLatex()
    texTR.SetTextSize(0.05)
    texTR.SetTextAlign(31)

#    if dataset=="" or noRatio:
#        texTL.DrawLatexNDC(0.13,0.87, "CMS #it{#bf{Preliminary}}")
#        texTR.DrawLatexNDC(0.89,0.91, "#bf{"+str(lumi/1000.)+" fb^{-1} (13 TeV)}")
#    else:
    upperCanvas.cd()
    
    texTL.DrawLatexNDC(0.16,0.92, "CMS") # #it{#bf{Preliminary}}")
    if args.prelim:
        texTL2 = TLatex()
        texTL2.SetTextSize(0.05)
        texTL2.SetTextAlign(13)
        suff = "#it{#bf{Preliminary}}"
        texTL2.DrawLatexNDC(0.16,0.85, suff)

    texTR.DrawLatexNDC(0.89,0.95, "#bf{"+str(lumi/1000.)+" fb^{-1} (13 TeV)}")
    # ----------------------------------------------------------

    c.SaveAs(outName+".pdf")
    c.SaveAs(outName+".png")
Beispiel #6
0
def plotDataVSMC(DataHist,
                 MCHist,
                 xtitle,
                 legendNames,
                 DataName,
                 destination,
                 ytitle_bottom='Data/MC'):
    GeneralSettings()

    Canv = TCanvas("Canv" + destination, "Canv" + destination, 1000, 1000)

    #Set Histogram Styles
    for i, h in enumerate(MCHist):
        h.SetFillColor(
            TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i])))
        h.SetLineColor(
            TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i])))

    DataHist.SetMarkerColor(ROOT.kBlack)
    DataHist.SetLineColor(ROOT.kBlack)
    DataHist.SetMarkerStyle(20)

    #Add all MC samples to use in ratios
    totBkgr = MCHist[0].Clone("totBkgr")
    for h in MCHist[1:]:
        totBkgr.Add(h)
    DataOverMC = DataHist.Clone("DataOverMC")
    DataOverMC.Divide(totBkgr)

    #First pad
    plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98)
    plotpad.SetBottomMargin(0.025)
    plotpad.Draw()
    plotpad.cd()

    #Create Stack (Change with most logical ordering)
    hs = THStack("hs", "hs")
    for h in MCHist:
        hs.Add(h)
    hs.Draw(
        "EHist"
    )  #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4
    title = " ; ; Events / " + str(MCHist[0].GetBinWidth(1)) + " GeV"
    hs.SetTitle(title)
    #    hs.GetHistogram().GetXaxis().SetTickLength(0)
    hs.GetHistogram().GetXaxis().SetLabelOffset(9999999)
    hs.GetHistogram().SetMaximum(1)

    #Set range
    overallMin = GetOverallMinimum(MCHist + [DataHist])
    overallMax = GetOverallMaximum([totBkgr] + [DataHist])
    hs.SetMinimum(0.5 * overallMin)
    hs.SetMaximum(1.2 * overallMax)
    DataHist.Draw("EPSame")

    #Create Legend
    legend = TLegend(0.7, .7, .9, .9)
    for h, n in zip(MCHist, legendNames):
        legend.AddEntry(h, n)
    legend.AddEntry(DataHist, DataName)
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

    legend.Draw()

    #Return to canvas
    Canv.cd()

    #Second pad
    ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3)
    ratiopad.SetTopMargin(0.05)
    ratiopad.SetBottomMargin(0.25)
    ratiopad.Draw()
    ratiopad.cd()

    #Set Style for bottom plot
    DataOverMC.SetTitle(";" + xtitle + "; " + ytitle_bottom)
    DataOverMC.GetXaxis().SetTitleSize(.12)
    DataOverMC.GetYaxis().SetTitleSize(.12)
    DataOverMC.GetYaxis().SetTitleOffset(.6)
    DataOverMC.GetXaxis().SetLabelSize(.12)
    DataOverMC.GetYaxis().SetLabelSize(.12)
    DataOverMC.SetMinimum(0.6)
    DataOverMC.SetMaximum(1.4)
    DataOverMC.Draw("EP")

    #Draw a guide for the eye
    line = TLine(DataOverMC.GetXaxis().GetXmin(), 1,
                 DataOverMC.GetXaxis().GetXmax(), 1)
    line.SetLineColor(ROOT.kRed)
    line.SetLineWidth(1)
    line.SetLineStyle(1)
    line.Draw("Same")

    #Throw CMs lumi at it
    cl.CMS_lumi(Canv, 4, 11, 'Preliminary', True)
    print 'save'

    #Save everything
    savePlots(Canv, destination)
    print 'saved'