Exemple #1
0
def draw_geff(t, title, h_bins, to_draw, den_cut, extra_num_cut,
              opt = "", color = kBlue, marker_st = 1, marker_sz = 1.):
    """Make an efficiency plot"""

    ## total numerator selection cut
    num_cut = AND(den_cut,extra_num_cut)

    ## PyROOT works a little different than ROOT when you are plotting
    ## histograms directly from tree. Hence, this work-around
    nBins  = int(h_bins[1:-1].split(',')[0])
    minBin = float(h_bins[1:-1].split(',')[1])
    maxBin = float(h_bins[1:-1].split(',')[2])

    num = TH1F("num", "", nBins, minBin, maxBin)
    den = TH1F("den", "", nBins, minBin, maxBin)

    t.Draw(to_draw + ">>num", num_cut, "goff")
    t.Draw(to_draw + ">>den", den_cut, "goff")

    debug = False
    if debug:
        print("Denominator cut", den_cut, den.GetEntries())
        print("Numerator cut", num_cut, num.GetEntries())

    ## check if the number of passed entries larger than total entries
    doConsistencyCheck = False
    if doConsistencyCheck:
        for i in range(0,nBins):
            print(i, num.GetBinContent(i), den.GetBinContent(i))
            if num.GetBinContent(i) > den.GetBinContent(i):
                print(">>>Error: passed entries > total entries")

    eff = TEfficiency(num, den)

    ## plotting options
    if not "same" in opt:
        num.Reset()
        num.GetYaxis().SetRangeUser(0.0,1.1)
        num.SetStats(0)
        num.SetTitle(title)
        num.Draw()

    eff.SetLineWidth(2)
    eff.SetLineColor(color)
    eff.SetMarkerStyle(marker_st)
    eff.SetMarkerColor(color)
    eff.SetMarkerSize(marker_sz)
    eff.Draw(opt + " same")

    SetOwnership(eff, False)
    return eff
    # emtf_eff_vs_genpt_l1pt20
    hname = "emtf_eff_vs_genpt_l1pt20"
    h1a_denom = tfile.Get(hname + "_denom")
    h1a_numer = tfile.Get(hname + "_numer")
    h1b_denom = tfile.Get(hname2026_f(hname) + "_denom")
    h1b_numer = tfile.Get(hname2026_f(hname) + "_numer")

    print h1a_denom.GetEntries(), h1a_numer.GetEntries()
    print h1b_denom.GetEntries(), h1b_denom.GetEntries()

    h1a_eff = TEfficiency(h1a_numer, h1a_denom)
    h1a_eff.SetStatisticOption(0)  # kFCP
    h1a_eff.SetConfidenceLevel(0.682689492137)  # one sigma
    h1a_eff.SetMarkerColor(632)  # kRed
    h1a_eff.SetLineColor(632)  # kRed
    h1a_eff.SetLineWidth(2)

    h1b_eff = TEfficiency(h1b_numer, h1b_denom)
    h1b_eff.SetStatisticOption(0)  # kFCP
    h1b_eff.SetConfidenceLevel(0.682689492137)  # one sigma
    h1b_eff.SetMarkerColor(600)  # kBlue
    h1b_eff.SetLineColor(600)  # kBlue
    h1b_eff.SetLineWidth(2)

    gr = h1a_eff.CreateGraph()
    gr.Draw("ap")
    frame = gr.GetHistogram()
    frame = frame.Clone(hname + "_frame")
    frame.GetYaxis().SetTitle("#varepsilon")
    frame.SetMinimum(0.0)
    frame.SetMaximum(1.2)
for key in keys:
    name = key.GetName()

    if not 'Pass' in name: continue
    if 'Vs' in name: continue

    hpass = f.Get(name)
    hall = f.Get(name.replace('Pass', 'All'))

    histoStyler(hall, kCyan - 8)
    hall.SetFillColor(hall.GetLineColor())
    hall.SetFillStyle(1001)

    eff = TEfficiency(hpass, hall)
    eff.SetLineWidth(2)

    kinvar = name[1:].replace('Pass', '')

    hframe = hpass.Clone('hframe')
    hframe.Reset()
    hframe.GetYaxis().SetRangeUser(0, 1.3)
    hframe.GetXaxis().SetTitle(kinvar + ' [' + units[kinvar] + ']')
    hframe.GetYaxis().SetTitle('#epsilon')
    hframe.SetTitle('')
    hframe.Draw()

    # 	hall.Scale(1.0/hall.Integral(),'width')
    hall.Scale(1 / hall.GetMaximum())
    hall.Draw('hist same')
def MakeOneHist(dirName, histogramName):

    HeaderLabel = TPaveLabel(header_x_left,header_y_bottom,header_x_right,header_y_top,HeaderText,"NDC")
    HeaderLabel.SetTextAlign(32)
    HeaderLabel.SetTextFont(42)
    HeaderLabel.SetTextSize(0.697674)
    HeaderLabel.SetBorderSize(0)
    HeaderLabel.SetFillColor(0)
    HeaderLabel.SetFillStyle(0)

    CMSLabel = TPaveLabel(header_x_left,header_y_bottom,header_x_right,header_y_top,HeaderText,"NDC")
    CMSLabel.SetTextAlign(32)
    CMSLabel.SetTextFont(42)
    CMSLabel.SetTextSize(0.697674)
    CMSLabel.SetBorderSize(0)
    CMSLabel.SetFillColor(0)
    CMSLabel.SetFillStyle(0)

    if makeFancy:
        LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,"CMS Preliminary","NDC")
        LumiLabel.SetTextFont(62)
        LumiLabel.SetTextSize(0.7)
        LumiLabel.SetTextAlign(12)
    else:
        LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,LumiText,"NDC")
        LumiLabel.SetTextAlign(32)
        LumiLabel.SetTextFont(42)
    LumiLabel.SetBorderSize(0)
    LumiLabel.SetFillColor(0)
    LumiLabel.SetFillStyle(0)

    #legend coordinates, empirically determined :-)
    x_left = 0.4
    x_right = 0.7
    y_min = 0.15
    y_max = 0.3

    Legend = TLegend(x_left,y_min,x_right,y_max)
    Legend.SetBorderSize(0)
    Legend.SetFillColor(0)
    Legend.SetFillStyle(0)

    Canvas = TCanvas(histogramName)
    Histograms = []
    HistogramClones = []
    NBins = []
    MaxXValues = []
    MinXValues = []
    LegendEntries = []

    colorIndex = 0

    for source in input_sources: # loop over different input sources in config file
        dataset_file = "condor/%s/%s.root" % (source['condor_dir'],source['dataset'])
        inputFile = TFile(dataset_file)
        NumHistogramObj = inputFile.Get(source['num_channel'] + "Plotter/" + dirName + "/" + histogramName)
        if 'condor_dir_den' in source:   # If specified, take the denominator histogram from a different condor directory.
            dataset_fileDen = "condor/%s/%s.root" % (source['condor_dir_den'],source['dataset'])
            inputFileDen = TFile(dataset_fileDen)
            DenHistogramObj = inputFileDen.Get(source['den_channel'] + "Plotter/" + dirName + "/" + histogramName)
        else:   # Default is to use the same condor directory
            DenHistogramObj = inputFile.Get(source['den_channel'] + "Plotter/" + dirName + "/" + histogramName)
        if not NumHistogramObj:
            print "WARNING:  Could not find histogram " + source['num_channel'] + "Plotter/" + dirName + "/" + histogramName + " in file " + dataset_file + ".  Will skip it and continue."
            return
        if not DenHistogramObj:
            print "WARNING:  Could not find histogram " + source['den_channel'] + "Plotter/" + dirName + "/" + histogramName + " in file " + dataset_file + ".  Will skip it and continue."
            return

        Histogram = NumHistogramObj.Clone()
        if Histogram.Class().InheritsFrom("TH2"):
            Histogram.SetName(Histogram.GetName() + "__" + source['dataset'])
        Histogram.SetDirectory(0)
        DenHistogram = DenHistogramObj.Clone()
        DenHistogram.SetDirectory(0)
        inputFile.Close()

        nbinsN = Histogram.GetNbinsX()
        nbinsD = DenHistogram.GetNbinsX()
        if not noOverFlow:
            # Add overflow
            Histogram.SetBinContent(   nbinsN,    Histogram.GetBinContent(nbinsN) +    Histogram.GetBinContent(nbinsN+1))
            DenHistogram.SetBinContent(nbinsD, DenHistogram.GetBinContent(nbinsD) + DenHistogram.GetBinContent(nbinsD+1))

            # Set the errors to be the sum in quadrature
            Histogram.SetBinError(  nbinsN,     math.sqrt(math.pow(Histogram.GetBinError(nbinsN),2) +    math.pow(Histogram.GetBinError(nbinsN+1),2)))
            DenHistogram.SetBinError(nbinsD, math.sqrt(math.pow(DenHistogram.GetBinError(nbinsD),2) + math.pow(DenHistogram.GetBinError(nbinsD+1),2)))

        if not noUnderFlow:
            # Add underflow
            Histogram.SetBinContent(   1,    Histogram.GetBinContent(1) +    Histogram.GetBinContent(0))
            DenHistogram.SetBinContent(1, DenHistogram.GetBinContent(1) + DenHistogram.GetBinContent(0))

            # Set the errors to be the sum in quadrature
            Histogram.SetBinError(   1,    math.sqrt(math.pow(Histogram.GetBinError(1), 2) +    math.pow(Histogram.GetBinError(0), 2)))
            DenHistogram.SetBinError(1, math.sqrt(math.pow(DenHistogram.GetBinError(1), 2) + math.pow(DenHistogram.GetBinError(0), 2)))

        if arguments.rebinFactor:
            RebinFactor = int(arguments.rebinFactor)
            #don't rebin histograms which will have less than 5 bins or any gen-matching histograms
            if Histogram.GetNbinsX() >= RebinFactor*5 and Histogram.GetTitle().find("GenMatch") is -1 and not Histogram.Class().InheritsFrom("TH2"):
                Histogram.Rebin(RebinFactor)
                DenHistogram.Rebin(RebinFactor)

        xAxisLabel = Histogram.GetXaxis().GetTitle()
        unitBeginIndex = xAxisLabel.find("[")
        unitEndIndex = xAxisLabel.find("]")

        if unitBeginIndex is not -1 and unitEndIndex is not -1: #x axis has a unit
            yAxisLabel = "#epsilon_{ " + cutName + "} (" + str(Histogram.GetXaxis().GetBinWidth(1)) + " " + xAxisLabel[unitBeginIndex+1:unitEndIndex] + " width)"
        else:
            yAxisLabel = "#epsilon_{ " + cutName + "} (" + str(Histogram.GetXaxis().GetBinWidth(1)) + " width)"
        if arguments.normalizeToUnitArea:
            yAxisLabel = yAxisLabel + " (Unit Area Norm.)"

        #check if bin content is consistent
        TEfficiency.CheckConsistency(Histogram,DenHistogram)
        for i in range(1,Histogram.GetNbinsX()+1):
            if Histogram.GetBinContent(i) > DenHistogram.GetBinContent(i):
                DenHistogram.SetBinContent(i,Histogram.GetBinContent(i))

        #HistogramClone and HistogramClones only used for ratio plot
        HistogramClone = Histogram.Clone()
        HistogramClone.SetDirectory(0)
        HistogramClone.Divide(DenHistogram)
        Nbins = HistogramClone.GetNbinsX()
        MaxXValue = HistogramClone.GetXaxis().GetBinLowEdge(Nbins+1)
        MinXValue = HistogramClone.GetXaxis().GetBinLowEdge(1)

        #this Histogram becomes the main TEfficiency
        if Histogram.Class().InheritsFrom("TH2"):
            Histogram.Divide(DenHistogram)
        else:
            #using default methods (which give correct uncertainties)
            #see https://root.cern.ch/doc/master/classTEfficiency.html (c.f. section IV)
            Histogram = TEfficiency(Histogram,DenHistogram)

        if not arguments.makeFancy:
            fullTitle = Histogram.GetTitle()
            splitTitle = fullTitle.split(":")
            #    print splitTitle
            if len(splitTitle) > 1:
                histoTitle = splitTitle[1].lstrip(" ")
            else:
                histoTitle = splitTitle[0]
        else:
            histoTitle = ""

        if 'color' in source:
            Histogram.SetMarkerColor(colors[source['color']])
            Histogram.SetLineColor(colors[source['color']])
        else:
            Histogram.SetMarkerColor(colors[colorList[colorIndex]])
            Histogram.SetLineColor(colors[colorList[colorIndex]])
            colorIndex = colorIndex + 1
            if colorIndex is len(colorList):
                colorIndex = 0

        markerStyle = 20
        if 'marker' in source:
            markerStyle = markers[source['marker']]
        if 'fill' in source:
            markerStyle = markerStyle + fills[source['fill']]

        Histogram.SetMarkerStyle(markerStyle)

        Histogram.SetLineWidth(line_width)
        Histogram.SetFillStyle(0)

        LegendEntries.append(source['legend_entry'])
        Histograms.append(Histogram)
        HistogramClones.append(HistogramClone)
        NBins.append(Nbins)
        MaxXValues.append(MaxXValue)
        MinXValues.append(MinXValue)

    ### scaling histograms as per user's specifications
    for histogram in Histograms:
        if arguments.normalizeToUnitArea and histogram.Integral() > 0:
            histogram.Scale(1./histogram.Integral())


    ### formatting histograms and adding to legend
    legendIndex = 0
    for histogram in Histograms:
        Legend.AddEntry(histogram,LegendEntries[legendIndex],"LEP")
        legendIndex = legendIndex+1

    ### finding the maximum value of anything going on the canvas, so we know how to set the y-axis
    finalMax = 1.1
    if arguments.setYMax:
        finalMax = float(arguments.setYMax)

    ### Drawing histograms to canvas

    makeRatioPlots = arguments.makeRatioPlots
    makeDiffPlots = arguments.makeDiffPlots
    addOneToRatio = -1
    if arguments.addOneToRatio:
        addOneToRatio = arguments.addOneToRatio

    dontRebinRatio = -1
    if arguments.dontRebinRatio:
        dontRebinRatio = arguments.dontRebinRatio

    ratioRelErrMax = -1
    if arguments.ratioRelErrMax:
        ratioRelErrMax = arguments.ratioRelErrMax

    yAxisMin = 0.0001
    if arguments.setYMin:
        yAxisMin = float(arguments.setYMin)

    if makeRatioPlots or makeDiffPlots:
        Canvas.SetFillStyle(0)
        Canvas.Divide(1,2)
        Canvas.cd(1)
        gPad.SetPad(0,0.25,1,1)
        gPad.SetMargin(0.15,0.05,0.01,0.07)
        gPad.SetFillStyle(0)
        gPad.Update()
        gPad.Draw()
        if arguments.setLogY:
            gPad.SetLogy()
        Canvas.cd(2)
        gPad.SetPad(0,0,1,0.25)
        #format: gPad.SetMargin(l,r,b,t)
        gPad.SetMargin(0.15,0.05,0.4,0.01)
        gPad.SetFillStyle(0)
        gPad.SetGridy(1)
        gPad.Update()
        gPad.Draw()

        Canvas.cd(1)

    histCounter = 0
    plotting_options = ""
    if arguments.plot_hist:
        plotting_options = "HIST"

    h = TH2F("h1","",NBins[0],MinXValues[0],MaxXValues[0],110,0.,finalMax)
    h.SetTitle(";"+xAxisLabel+";"+yAxisLabel)
    h.Draw()

    for histogram in Histograms:
        if histogram.Class().InheritsFrom("TH2"):
            histogram.SetTitle(histoTitle)
            histogram.Draw("colz")
            DatasetName = histogram.GetName()
            DatasetName = DatasetName[DatasetName.rfind('__')+2:]  # substring starting with the last underscore
            DatasetLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,DatasetName,"NDC")
            DatasetLabel.SetBorderSize(0)
            DatasetLabel.SetFillColor(0)
            DatasetLabel.SetFillStyle(0)
            DatasetLabel.Draw()
            outputFile.cd()
            Canvas.SetName(histogram.GetName())
            Canvas.Write()

        else:
            if histogram.InheritsFrom("TEfficiency") and histCounter==0:
                plotting_options = "P SAME"
            histogram.SetTitle(histoTitle)
            histogram.Draw(plotting_options)

            if histogram.InheritsFrom("TH1"):
                histogram.SetMaximum(finalMax)
                histogram.SetMinimum(yAxisMin)

        if histCounter is 0:
            if histogram.InheritsFrom("TH1"):
                plotting_options = plotting_options + " SAME"
            elif histogram.InheritsFrom("TEfficiency"):
                plotting_options = "P" + " SAME"

        histCounter = histCounter + 1

    if histogram.Class().InheritsFrom("TH2"):
        return

    Legend.Draw()


    if arguments.makeFancy:
        HeaderLabel.Draw()
        LumiLabel.Draw()



    #drawing the ratio or difference plot if requested

    if makeRatioPlots or makeDiffPlots:
        Canvas.cd(2)
        if makeRatioPlots:
            makeRatio = functools.partial (ratioHistogram,HistogramClones[0],HistogramClones[1])
            if addOneToRatio != -1: # it gets initialized to this dummy value of -1
                makeRatio = functools.partial (makeRatio, addOne = bool (addOneToRatio))
            if ratioRelErrMax is not -1: # it gets initialized to this dummy value of -1
                makeRatio = functools.partial (makeRatio, relErrMax = float (ratioRelErrMax))
            if dontRebinRatio is True:
                makeRatio = functools.partial (makeRatio, dontRebinRatio)
            Comparison = makeRatio ()
        elif makeDiffPlots:
            Comparison = Histograms[0].Clone("diff")
            Comparison.Add(Histograms[1],-1)
            Comparison.SetTitle("")
            Comparison.GetYaxis().SetTitle("hist1-hist2")
        Comparison.GetXaxis().SetTitle(xAxisLabel)
        Comparison.GetYaxis().CenterTitle()
        Comparison.GetYaxis().SetTitleSize(0.1)
        Comparison.GetYaxis().SetTitleOffset(0.5)
        Comparison.GetXaxis().SetTitleSize(0.15)
        Comparison.GetYaxis().SetLabelSize(0.1)
        Comparison.GetXaxis().SetLabelSize(0.15)
        if makeRatioPlots:
            RatioYRange = 1.15
            if arguments.ratioYRange:
                RatioYRange = float(arguments.ratioYRange)
            if addOneToRatio == -1: # it gets initialized to this dummy value of -1
                Comparison.GetYaxis().SetRangeUser(-1*RatioYRange, RatioYRange)
            else:
                Comparison.GetYaxis().SetRangeUser(-1*RatioYRange + 1.0, RatioYRange + 1.0)
        elif makeDiffPlots:
            YMax = Comparison.GetMaximum()
            YMin = Comparison.GetMinimum()
            if YMax <= 0 and YMin <= 0:
                Comparison.GetYaxis().SetRangeUser(-1.2*YMin,0)
            elif YMax >= 0 and YMin >= 0:
                Comparison.GetYaxis().SetRangeUser(0,1.2*YMax)
            else: #axis crosses y=0
                if abs(YMax) > abs(YMin):
                    Comparison.GetYaxis().SetRangeUser(-1.2*YMax,1.2*YMax)
                else:
                    Comparison.GetYaxis().SetRangeUser(-1.2*YMin,1.2*YMin)

        Comparison.GetYaxis().SetNdivisions(205)
        Comparison.Draw("E0")

    outputFile.cd(dirName)
    Canvas.Write()

    if arguments.savePDFs:
        Canvas.SaveAs("efficiency_histograms_pdfs/"+histogramName+".pdf")