Beispiel #1
0
def drawTemplateFitter(tf, canvas = None, trueVal = None) :
    if not canvas : canvas = r.TCanvas()
    else: canvas.Clear()
    canvas.cd(0)
    canvas.Divide(2,2)

    #------1
    LL = r.TGraph(len(tf.pars), np.array(tf.pars), tf.templatesN2LL)
    fit = r.TF1("fit","pol3",min(tf.pars),max(tf.pars))
    for i,c in enumerate(tf.coefficients) : fit.SetParameter(i,c)
    xMaxLL = [r.TGraph(2,np.array([val,val]),np.array([min(tf.templatesN2LL),max(tf.templatesN2LL)])) for val in [tf.value,tf.value+tf.error,tf.value-tf.error]]
    for h in xMaxLL : h.SetLineColor(r.kBlue)
    if trueVal != None :
        xMaxLL.append(r.TGraph(2,np.array([trueVal,trueVal]),np.array([min(tf.templatesN2LL),max(tf.templatesN2LL)])))
        xMaxLL[-1].SetLineColor(r.kRed)
        xMaxLL[-1].SetLineWidth(2)
    xMaxLL[1].SetLineStyle(r.kDashed)
    xMaxLL[2].SetLineStyle(r.kDashed)
    LL.SetTitle("best fit: %s  | corrected: %s"%(utils.roundString(tf.value,tf.error, noSci=True), 
                                                 utils.roundString(tf.value-tf.bias, tf.error*tf.pull,noSci=True)) +
                ("  |  %0.3f"%trueVal if trueVal is not None else ""))
    canvas.cd(1)
    LL.Draw('A*')
    for h in reversed(xMaxLL) : h.Draw('')
    fit.Draw('same')

    #------2
    n2lls = utils.rHist("-2logLs", *np.histogram([toy.n2LL for toy in tf.ensemble], 100) )
    n2ll = n2lls.Clone('-2logL') ; n2ll.Reset(); n2ll.SetBinContent(n2ll.FindFixBin(tf.n2LL), n2lls.GetMaximum()); 
    n2ll.SetFillColor(r.kBlue); n2lls.SetTitle("p-value: %0.4f"%tf.p_value)
    canvas.cd(2)
    n2lls.Draw()
    n2ll.Draw('same')

    #------3
    edges = range(len(tf.observed)+1)
    observed = utils.rHist("observed", tf.observed, edges, True)
    spars,stemplates = zip(*sorted(zip(tf.pars,tf.templates)))
    templates = [utils.rHist("template%d"%i, templ, edges) for i,templ in enumerate(stemplates) if i in [0,len(spars)-1,len(spars)/2]]
    observed.SetTitle("observed")
    observed.SetMarkerStyle(20)
    for i,templ in enumerate(templates) : templ.SetLineColor([r.kRed,r.kGreen,r.kBlue][i])
    maxHeight = max(h.GetMaximum() for h in [observed]+templates)
    for h in [observed]+templates : h.SetMaximum(1.1*maxHeight)
    canvas.cd(3)
    observed.Draw()
    for t in templates : t.Draw("same")

    #------4
    relMean = np.mean(tf.relResiduals)
    pull = utils.rHist("relative residuals", *np.histogram(tf.relResiduals,100,(relMean-5,relMean+5)))
    canvas.cd(4)
    pull.Draw()

    canvas.Update()
    return canvas,observed,templates,LL,fit,xMaxLL,n2lls,n2ll,pull
Beispiel #2
0
    def printSteps(self, steps, printAll=False) :
        if printAll and len(steps)>self.nLinesMax : self.printSteps(steps[:1-self.nLinesMax],printAll)
        self.canvas.cd(0)
        self.canvas.Clear()
        
        text = r.TText()
        text.SetNDC()
        text.SetTextFont(102)
        text.SetTextSize(0.45*text.GetTextSize())

        pageWidth = 111
        nSamples = len(self.someOrganizer.samples)
        if self.printRatios : nSamples += 1
        colWidth = min(25, pageWidth/nSamples)
        space = 1

        nametitle = "{0}:  {1:<%d}   {2}" % (3+max([len(s.name) for s in steps]))
        for i,step in enumerate(steps[-self.nLinesMax:]) :
            absI = i + (0 if len(steps) <= self.nLinesMax else len(steps)-self.nLinesMax)

            text.SetTextColor(self.rowColors[absI%len(self.rowColors)])
            letter = string.ascii_letters[absI]
            x = 0.01
            y = 0.98 - 0.33*(i+0.5+(absI/5) - ((absI-i)/5) )/self.nLinesMax
            text.DrawTextNDC(x, y, nametitle.format(letter, step.name, step.title ))
            self.cutDict[letter] = (step.name, step.title)

            nums = []
            ratios = [None]*len(self.samplesForRatios)
            for k,sample in zip(step.yields,self.someOrganizer.samples) :
                special = "lumi" in sample and not self.showErrorsOnDataYields
                s = utils.roundString(*k, width=(colWidth-space), noSci = self.noSci or special, noErr = special) if k else "-    "
                if sample["name"] in self.samplesForRatios : ratios[self.samplesForRatios.index(sample["name"])] = k
                nums.append(s.rjust(colWidth))

            if self.printRatios and len(ratios)==2 :
                s = "-    "
                if ratios[0] and ratios[1] and ratios[0][0] and ratios[1][0] :
                    value = ratios[0][0]/float(ratios[1][0])
                    error = value*math.sqrt((ratios[0][1]/float(ratios[0][0]))**2 + (ratios[1][1]/float(ratios[1][0]))**2)
                    ratio = (value, error)
                    s = utils.roundString(*ratio, width=(colWidth-space))
                nums.append(s.rjust(colWidth))
                
            text.DrawTextNDC(x, y-0.51, "%s: %s"%(letter, "".join(nums)))
            self.yieldDict[letter] = nums

        self.sampleList = [s["name"][:(colWidth-space)].rjust(colWidth) for s in self.someOrganizer.samples]
        if self.printRatios and len(self.samplesForRatios)==2 :
            self.sampleList += ("%s/%s"%self.sampleLabelsForRatios)[:(colWidth-space)].rjust(colWidth)
        text.SetTextColor(r.kBlack)
        text.DrawTextNDC(x, 0.5, "   "+"".join(self.sampleList))
        text.SetTextAlign(13)
        text.DrawTextNDC(0.05, 0.03, "events / %.3f pb^{-1}"% self.someOrganizer.lumi )
        self.flushPage()
Beispiel #3
0
def drawComponentSolver(cs, canvas = None) :
    if not canvas : canvas = r.TCanvas()
    canvas.cd(0)
    canvas.Divide(2,2)

    rTemplates = [utils.rHist("template%d"%i,d,range(len(d)+1)) for i,d in enumerate(cs.components)]
    rObs = utils.rHist("observed",cs.observed,range(len(d)+1),True)
    rObs.SetTitle("ML fractions:   "+", ".join(utils.roundString(f,e,noSci=True) for f,e in zip(cs.fractions,cs.errors) ))

    nlls = utils.rHist("-logLs", *np.histogram([-toy.logL for toy in cs.ensemble], 100) )
    nll = nlls.Clone('-logL') ; nll.Reset(); nll.SetBinContent(nll.FindFixBin(-cs.logL), nlls.GetMaximum()); 
    nll.SetFillColor(r.kBlue); nll.SetTitle("p-value: %0.4f"%cs.p_value)
    pulls = [ utils.rHist("relative residuals %d"%i, *np.histogram(pull,100,(-5,5))) for i,pull in enumerate(cs.relResiduals.transpose())]

    corr = cs.correlation
    corrH = r.TH2D("correlations","correlations", len(corr), -0.5, len(corr)-0.5, len(corr), -0.5, len(corr)-0.5)
    for i,j in itertools.product(range(len(corr)), repeat = 2) : corrH.SetBinContent(i+1,j+1,round(corr[i][j],3))
    corrH.SetMaximum(1)
    corrH.SetMinimum(-1)
    canvas.cd(3)
    corrH.Draw("colztext")

    stats = []
    for i,a,t in zip(range(len(cs.fractions)),pulls,rTemplates) : 
        t.SetFillColor(i+2)
        t.SetLineColor(i+2)
        a.SetLineColor(i+2)
        a.SetMaximum(1.1*max(h.GetMaximum() for h in pulls))
        canvas.cd(4); a.Draw("sames" if i else "")
        canvas.Update()
        st = a.GetListOfFunctions().FindObject("stats")
        st.SetOptStat(1101)
        st.SetLineColor(i+2)
        st.SetY1NDC(0.85-0.16*i)
        st.SetY2NDC(1.0-0.16*i)
        stats.append( st.Clone("stats%d"%i) )
    for s in stats : s.Draw()

    canvas.cd(2) ; nll.Draw(); nlls.Draw("histsame")
    rObs.SetMarkerStyle(20)

    def draw(i,logY = False) :
        canvas.cd(i).SetLogy(logY)
        rObs.Draw("e")
        for t in rTemplates : t.Draw("histsame")
        rObs.Draw("esame")

    base = utils.rHist("base",cs.base,range(len(cs.base)+1)) ; base.SetFillColor(r.kGray)
    rTemplates = sorted(rTemplates,key=lambda t: -t.Integral()) + [base]
    for t,h in reversed(zip(rTemplates[:-1],rTemplates[1:])) : t.Add(h)
    draw(1, logY = False)
    #draw(3, logY = True)
    canvas.Update()
    return [canvas,rObs,rTemplates,stats,pulls,nlls,nll,corrH]
Beispiel #4
0
    def printSteps(self, steps, printAll=False) :
        if printAll and len(steps)>self.nLinesMax : self.printSteps(steps[:1-self.nLinesMax],printAll)
        self.canvas.cd(0)
        self.canvas.Clear()
        
        text = r.TText()
        text.SetNDC()
        text.SetTextFont(102)
        text.SetTextSize(0.45*text.GetTextSize())

        pageWidth = 111
        colWidth = min(25, pageWidth/len(self.someOrganizer.samples))
        space = 1

        nametitle = "{0}:  {1:<%d}   {2}" % (3+max([len(s.name) for s in steps]))
        for i,step in enumerate(steps[-self.nLinesMax:]) :
            absI = i + (0 if len(steps) <= self.nLinesMax else len(steps)-self.nLinesMax)
            letter = string.ascii_letters[absI]
            x = 0.01
            y = 0.98 - 0.33*(i+0.5+absI/5)/self.nLinesMax
            text.DrawTextNDC(x, y, nametitle.format(letter, step.name, step.title ))
            self.cutDict[letter] = (step.name, step.title)
            
            nums = []
            for k,sample in zip(step.yields,self.someOrganizer.samples) :
                special = "lumi" in sample and not self.showErrorsOnDataYields
                s = utils.roundString(*k, width=(colWidth-space), noSci = self.noSci or special, noErr = special) if k else "-    "
                nums.append(s.rjust(colWidth))

            text.DrawTextNDC(x, y-0.49, "%s: %s"%(letter, "".join(nums)))
            self.yieldDict[letter] = nums

        self.sampleList = [s["name"][:(colWidth-space)].rjust(colWidth) for s in self.someOrganizer.samples]
        text.DrawTextNDC(x, 0.5, "   "+"".join(self.sampleList))
        text.SetTextAlign(13)
        text.DrawTextNDC(0.05, 0.03, "events / %.3f pb^{-1}"% self.someOrganizer.lumi )
        self.flushPage()
Beispiel #5
0
    def printSteps(self, steps, printAll=False) :
        if printAll and len(steps)>self.nLinesMax : self.printSteps(steps[:1-self.nLinesMax],printAll)
        self.canvas.cd(0)
        self.canvas.Clear()
        
        text = r.TText()
        text.SetNDC()
        text.SetTextFont(102)
        text.SetTextSize(0.40*text.GetTextSize())

        pageWidth = 120
        nSamples = len(self.someOrganizer.samples) + len(self.foms)
        colWidth = min(25, pageWidth/nSamples)
        space = 1

        nametitle = "{0}:  {1:<%d}   {2}" % (3+max([len(s.name) for s in steps]))
        for i,step in enumerate(steps[-self.nLinesMax:]) :
            absI = i + (0 if len(steps) <= self.nLinesMax else len(steps)-self.nLinesMax)

            text.SetTextColor(self.rowColors[absI%len(self.rowColors)])
            letter = string.ascii_letters[absI]
            x = 0.02
            y = 0.98 - 0.34*(i+0.5+(absI/self.rowCycle) - ((absI-i)/self.rowCycle) )/self.nLinesMax

            nums = []
            ratios = [None]*len(self.samplesForRatios)
            for k,sample in zip(step.yields,self.someOrganizer.samples) :
                special = "lumi" in sample and not self.showErrorsOnDataYields
                s = utils.roundString(*k, width=(colWidth-space), noSci = self.noSci or special, noErr = special) if k else "-    "
                if sample["name"] in self.samplesForRatios : ratios[self.samplesForRatios.index(sample["name"])] = k
                nums.append(s.rjust(colWidth))

            if len(ratios)==2 and ratios[0] and ratios[1]:
                num = float(ratios[0][0])
                den = float(ratios[1][0])
                numUnc = float(ratios[0][1])
                denUnc = float(ratios[1][1])

                for fom in self.foms:
                    s = "-    "
                    if num and den:
                        value = fom["value"](num, den)
                        error = value*fom["uncRel"](num, den, numUnc, denUnc)
                        s = utils.roundString(value, error, width=(colWidth-space))
                    nums.append(s.rjust(colWidth))

            if step.name in ['master','label']: self.pdfOptions = step.title
            if step.name=='label' :
                text.SetTextColor(r.kBlack)
                font = text.GetTextFont()
                text.SetTextFont(62)
                label = "[  %s  ]"%step.title
                text.DrawTextNDC(0.01, y, label)
                text.DrawTextNDC(0.01, y-0.51, label )
                text.SetTextFont(font)
            else:
                text.DrawTextNDC(x, y-0.00, nametitle.format(letter, step.name, step.title ))
                text.DrawTextNDC(x, y-0.51, "%s: %s"%(letter, "".join(nums)))
                self.cutDict[letter] = (step.name, step.title)
                self.yieldDict[letter] = nums

            if absI > self.formerMaxAbsI :
                text.SetTextColor(r.kBlack)
                text.DrawTextNDC(0.008,y-0.00,'|')
                text.DrawTextNDC(0.008,y-0.51,'|')

        self.formerMaxAbsI = absI
        self.sampleList = [s["name"][:(colWidth-space)].rjust(colWidth) for s in self.someOrganizer.samples]
        if len(self.samplesForRatios)==2:
            for fom in self.foms:
                self.sampleList += (fom["label"](*self.sampleLabelsForRatios))[:(colWidth-space)].rjust(colWidth)
        text.SetTextColor(r.kBlack)
        text.DrawTextNDC(x, 0.5, "   "+"".join(self.sampleList))
        text.SetTextAlign(13)
        text.DrawTextNDC(0.05, 0.03, "events / %.0f fb^{-1}" % (self.someOrganizer.lumi/1.0e3) )
        self.flushPage()
Beispiel #6
0
    '''Test the template fitter.'''
    r.gStyle.SetPalette(1)
    r.gROOT.SetStyle("Plain")

    if len(sys.argv)<2 : print "Usage: templateFit [trueParValue=0] [ScaleFactor=100]"
    truePar = float(sys.argv[1]) if len(sys.argv)>1 else 0
    norm = int(sys.argv[2]) if len(sys.argv)>2 else 100

    def template(p) : return np.array([100+norm*math.exp(-0.5*(x-p)**2) for x in range(-5,5)])

    templates = [(p,template(p)) for p in np.arange(-1.0,1.1,0.1)]
    observed = np.array([np.random.poisson(mu) for mu in template(truePar)])

    TF = templateFitter(observed, *templates)
    print "true value: ", truePar
    print "measured : ", utils.roundString(TF.value,TF.error)
    canvas = drawTemplateFitter(TF)
    
    print "p-value :", TF.p_value
    print "bias : ", TF.bias
    print "pull : ", TF.pull
    
    raw_input()

    def format(d) : return "[ %s ]"%', '.join("%.3f"%f for f in d)
            
    ensembles = templateEnsembles(500, *templates )
    print "pars : ".rjust(20), format(ensembles.pars)
    print "biases : ".rjust(20), format(ensembles.biases)
    print "pulls : ".rjust(20), format(ensembles.pulls)
    print "meanErrors : ".rjust(20), format(ensembles.meanError)