コード例 #1
0
def setupLimit(channel):
    def makeLegend():
        return r.TLegend(0.7, 0.9, 0.9, 0.6)
    def plot(NObserved, results, NControl, R, bkgPredict):
        r.gROOT.SetStyle("Plain")
        c = r.TCanvas("test")
        c.SetGrid()
        nbins = len(NObserved)
        obs = r.TH1D("obs", "obs", nbins, 0.5, nbins+0.5)
        pred = r.TH1D("pred", "pred", nbins, 0.5, nbins+0.5)
        pred2 = r.TH1D("pred2", "pred2", nbins, 0.5, nbins+0.5)
        for idx, b in enumerate(NObserved):
            obs.SetBinContent(idx+1, b)
            if bkgPredict: pred2.SetBinContent(idx+1, R["nominal"][idx]*bkgPredict[0][idx])
            pred.SetBinContent(idx+1, results[idx].predicted())
            perr = math.sqrt(results[idx].predicted())
            serr = R["MCStats"][idx]*NControl[idx]
            pred.SetBinError(idx+1,
                             math.sqrt(perr**2 + serr**2))
            obs.GetXaxis().SetBinLabel(idx+1, utils.formatBin(idx, False))
        pred.SetLineColor(r.kRed)
        pred2.SetLineColor(r.kGreen);
        obs.GetYaxis().SetRangeUser(0, 1.2*max(obs.GetMaximum(), pred.GetMaximum()))
        obs.SetStats(r.kFALSE)
        obs.Draw("hist")
        if bkgPredict: pred2.Draw("hist e same")
        pred.Draw("hist e same")
        leg = makeLegend()
        leg.AddEntry(pred, "Predicted", "L")
        if bkgPredict: leg.AddEntry(pred2, "Predicted (QCD Fit)", "L")
        leg.AddEntry(obs, "Observed", "L")
        leg.Draw()
        c.SaveAs("limit/%s_pred_obs.pdf" % channel.name)
    def plotA(path, *args, **kwargs):
        c = r.TCanvas("test")
        c.SetGrid()
        r.gROOT.SetStyle("Plain")
        nbins = len(args[0])
        hists = [r.TH1D("h%d" % idx, "h%d" %idx, nbins, 0.5, nbins+0.5) for idx in range(len(args))]
        for idx in range(nbins):
            for hidx, h in enumerate(hists):
                h.SetBinContent(idx+1, args[hidx][idx])
                h.SetBinError(idx+1, math.sqrt(args[hidx][idx]))
        cols = kwargs.get("cols", [r.kBlack, r.kRed])
        legs = kwargs.get("legend", [])
        legend = makeLegend() if len(legs) > 0 else None
        for hidx, h in enumerate(hists):
            h.SetLineColor(cols[hidx])
            h.GetYaxis().SetRangeUser(0, 1.2*max([h.GetMaximum() for h in hists]))
            if hidx == 0: h.Draw("hist e")
            else: h.Draw("hist e same")
            if hidx < len(legs): legend.AddEntry(h, legs[hidx], "L")
        if legend: legend.Draw()
        c.SaveAs(path)

    ctrl_channel = bkgPredict = None
    # Get the background prediction per bin
    if channel.bkgPrediction == "OtherChannel":
        ctrl_channel = channel.ctrlChannel

    data = utils.getZeroData(channel, ctrl_channel)
    mc = utils.getZeroMC(channel, ctrl_channel)

    results = utils.makePredictions(data)

    systs = utils.getSystematicsBkg(channel, ctrl_channel)

    R = {"nominal": [b.R() for b in data]}

    for name, scaled in systs:
        R[name] = utils.getSystematicShiftsR(mc, scaled[0], scaled[1])
    R["MCStats"] = utils.mcStatsSystematicBkg(channel.bkgSamples, channel, ctrl_channel)
    R["ttpol"] = [x*tt for x, tt in zip(R["nominal"], ch.ttPolarisationUncertainty)]
    NObserved = [b.observed() for b in data]
    NControl = [b.control() for b in data]
    NControlMC = [b.mcControl() for b in mc]
    # This is to fix a problem with this not being scaled when running in real data mode.
    # Its not pretty but it works (I hope!)
    if cfg.useRealData:
        scaleMC = ch.lumi/cfg.icfDefaultLumi
        NControlMC = [x*scaleMC for x in NControlMC]
    print "Extracting signal data..."
    susyEff = utils.getZeroMCSignal(channel)
    controlRegionEff = utils.getZeroMCSignalControlRegion(channel)
    effSysts = utils.getSystematicsSignalEff(channel)

    if channel.bkgPrediction == "QCDFit":
        if cfg.useRealData: bkgPredict = (channel.ewkN, channel.ewkErr, {})
        else: bkgPredict = (NControl, [rel*control for rel, control in zip(channel.ewkRelErr, NControl)], {})

    for (m0, m12), p in susyEff.iteritems():
        p["effShift"] = {}
        p["control_efficiencies"] = controlRegionEff[(m0, m12)]["efficiencies"]
        for name,scaled in effSysts:
            shift = utils.getSystematicShiftsEff(p, scaled[0], scaled[1])
            p["effShift"][name] = shift
        if "pdfunc" in channel.includeSignalSysts:
            p["effShift"]["pdfunc"] = [0.1*eff for eff in p["efficiencies"]]

    plot(NObserved, results, NControl, R, bkgPredict)
    plotA("limit/R_%s.pdf" % channel.name, R["nominal"], legend = ["R"])

    # This is an ad-hoc correction to the electron limit to account for poor
    # statistics

    if ch == cfg.Electron and False:
        print "Correcting Electron channel top bin!"
        R["nominal"] = [x*2 for x in R["nominal"]]
#        for k, v in R.iteritems():
 #           R[k] = [x*2.25 for x in R[k]]
            #R[k][-1] = R[k][-1]*2.25
        if not cfg.useRealData:
            NObserved[-1] = NObserved[-1]*2.25

    if cfg.expectedLimit:
        if bkgPredict is None: NObserved = [Ri*cont for Ri, cont in zip(R["nominal"], NControl)]
        else: NObserved = [Ri*cont for Ri, cont in zip(R["nominal"], bkgPredict[0])]
    return {
        "name" : ch.name,
        "NObserved" : NObserved,
        "NControl" : NControl,
        "NControlMC" : NControlMC,
        "bkgPredict" : bkgPredict,
        "R" : R,
        "lumi": ch.lumi,
        "triggerEfficiency":ch.triggerEfficiency,
        "lumiError": cfg.lumiError,
        "signal" : susyEff,
        }
コード例 #2
0
ファイル: runLimit.py プロジェクト: alexsparrow/statTools
def setupLimit(channel):
    def makeLegend():
        return r.TLegend(0.7, 0.9, 0.9, 0.6)
    def plot(NObserved, results, NControl, R, bkgPredict):
        r.gROOT.SetStyle("Plain")
        c = r.TCanvas("test")
        c.SetGrid()
        nbins = len(NObserved)
        obs = r.TH1D("obs", "obs", nbins, 0.5, nbins+0.5)
        pred = r.TH1D("pred", "pred", nbins, 0.5, nbins+0.5)
        pred2 = r.TH1D("pred2", "pred2", nbins, 0.5, nbins+0.5)
        for idx, b in enumerate(NObserved):
            obs.SetBinContent(idx+1, b)
            if bkgPredict: pred2.SetBinContent(idx+1, R["nominal"][idx]*bkgPredict[0][idx])
            pred.SetBinContent(idx+1, results[idx].predicted())
            perr = math.sqrt(results[idx].predicted())
            serr = R["MCStats"][idx]*NControl[idx]
            pred.SetBinError(idx+1,
                             math.sqrt(perr**2 + serr**2))
            obs.GetXaxis().SetBinLabel(idx+1, utils.formatBin(idx, False))
        pred.SetLineColor(r.kRed)
        pred2.SetLineColor(r.kGreen);
        obs.GetYaxis().SetRangeUser(0, 1.2*max(obs.GetMaximum(), pred.GetMaximum()))
        obs.SetStats(r.kFALSE)
        obs.Draw("hist")
        if bkgPredict: pred2.Draw("hist e same")
        pred.Draw("hist e same")
        leg = makeLegend()
        leg.AddEntry(pred, "Predicted", "L")
        if bkgPredict: leg.AddEntry(pred2, "Predicted (QCD Fit)", "L")
        leg.AddEntry(obs, "Observed", "L")
        leg.Draw()
        c.SaveAs("limit/%s_pred_obs.pdf" % channel.name)
    def plotA(path, *args, **kwargs):
        c = r.TCanvas("test")
        c.SetGrid()
        r.gROOT.SetStyle("Plain")
        nbins = len(args[0])
        hists = [r.TH1D("h%d" % idx, "h%d" %idx, nbins, 0.5, nbins+0.5) for idx in range(len(args))]
        for idx in range(nbins):
            for hidx, h in enumerate(hists):
                h.SetBinContent(idx+1, args[hidx][idx])
                h.SetBinError(idx+1, math.sqrt(args[hidx][idx]))
        cols = kwargs.get("cols", [r.kBlack, r.kRed])
        legs = kwargs.get("legend", [])
        legend = makeLegend() if len(legs) > 0 else None
        for hidx, h in enumerate(hists):
            h.SetLineColor(cols[hidx])
            h.GetYaxis().SetRangeUser(0, 1.2*max([h.GetMaximum() for h in hists]))
            if hidx == 0: h.Draw("hist e")
            else: h.Draw("hist e same")
            if hidx < len(legs): legend.AddEntry(h, legs[hidx], "L")
        if legend: legend.Draw()
        c.SaveAs(path)

    ctrl_channel = bkgPredict = None
    # Get the background prediction per bin
    if channel.bkgPrediction == "OtherChannel":
        ctrl_channel = channel.ctrlChannel
    elif channel.bkgPrediction == "QCDFit":
        bkgPredict = (channel.ewkN, channel.ewkErr, {})
    data = utils.getZeroData(channel, ctrl_channel)
    mc = utils.getZeroMC(channel, ctrl_channel)


    results = utils.makePredictions(data)

    systs = utils.getSystematicsBkg(channel, ctrl_channel)

    R = {"nominal": [b.R() for b in data]}

    for name, scaled in systs:
        R[name] = utils.getSystematicShiftsR(mc, scaled[0], scaled[1])
    R["MCStats"] = utils.mcStatsSystematicBkg(channel.bkgSamples, channel, ctrl_channel)
    NObserved = [b.observed() for b in data]
    NControl = [b.control() for b in data]
    NControlMC = [b.mcControl() for b in mc]
    print "Extracting signal data..."
    susyEff = utils.getZeroMCSignal(channel)
    controlRegionEff = utils.getZeroMCSignalControlRegion(channel)
    effSysts = utils.getSystematicsSignalEff(channel)

    for (m0, m12), p in susyEff.iteritems():
        p["effShift"] = {}
        p["control_efficiencies"] = controlRegionEff[(m0, m12)]["efficiencies"]
        for name,scaled in effSysts:
            shift = utils.getSystematicShiftsEff(p, scaled[0], scaled[1])
            p["effShift"][name] = shift
        if "pdfunc" in channel.includeSignalSysts:
            p["effShift"]["pdfunc"] = [0.1*eff for eff in p["efficiencies"]]

    plot(NObserved, results, NControl, R, bkgPredict)
    plotA("limit/R_%s.pdf" % channel.name, R["nominal"], legend = ["R"])
    return {
        "name" : ch.name,
        "NObserved" : NObserved,
        "NControl" : NControl,
        "NControlMC" : NControlMC,
        "bkgPredict" : bkgPredict,
        "R" : R,
        "lumi": ch.lumi,
        "triggerEfficiency":ch.triggerEfficiency,
        "lumiError": cfg.lumiError,
        "signal" : susyEff,
        }