def addHistToTGraphPoisson(self, h, g, w=1.): for i in range(0, g.GetN()): # shifted by +1, i.e. over/underflow err = h.GetBinError(i + 1) 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) if n != 0. else 0. g.SetPointEYlow( i, math.sqrt(((n - l) / binWidth * w)**2 + g.GetErrorYlow(i)**2)) g.SetPointEYhigh( i, math.sqrt(((u - n) / binWidth * w)**2 + g.GetErrorYhigh(i)**2)) gx = Double(0.) gy = Double(0.) g.GetPoint(i, gx, gy) g.SetPoint(i, gx, y + gy)
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() ) )
def calculatePoissonErrors(n, confidenceInterval=0.6827): ## Calcultes the Poisson error for a given numer # n number of entries # confidenceInterval probability covered inside the error band from ROOT import Math n = round(n) invIntegral = (1. - confidenceInterval) / 2. lo = Math.gamma_quantile(invIntegral, n, 1.) if n != 0 else 0. hi = Math.gamma_quantile_c(invIntegral, n + 1, 1.) return n - lo, hi - n
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
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
def addHistToTGraphPoisson(self, h, g, w=1.): for i in range(0, g.GetN()): # shifted by +1, i.e. over/underflow err = h.GetBinError(i+1) 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) if n != 0. else 0. g.SetPointEYlow(i, math.sqrt(((n-l)/binWidth*w)**2 + g.GetErrorYlow(i)**2)) g.SetPointEYhigh(i, math.sqrt(((u-n)/binWidth*w)**2 + g.GetErrorYhigh(i)**2)) gx = Double(0.) gy = Double(0.) g.GetPoint(i, gx, gy) g.SetPoint(i, gx, y + gy)
Nbkg = Nqcd + Nzj + Nwt acc = TFile("/user2/sfarry/workspaces/top/tuples/ttbar_acc.root") A = acc.Get('acc').GetVal() A_err = acc.Get('acc_err').GetVal() xsec = Nsig * A / (totaleff * L ) from math import floor #poisson uncertainties alpha = 1 - 0.68268942 Nwt_err_lo = Nwt - Math.gamma_quantile(alpha/2.0, floor(Nwt),1) Nzj_err_lo = Nzj - Math.gamma_quantile(alpha/2.0, floor(Nzj),1) Nqcd_err_lo = Nqcd - Math.gamma_quantile(alpha/2.0, floor(Nqcd),1) Nbkg_err_lo = Nbkg - Math.gamma_quantile(alpha/2.0, floor(Nbkg),1) Nwt_err_hi = Math.gamma_quantile_c(alpha/2.0, floor(Nwt)+1,1) - Nwt Nzj_err_hi = Math.gamma_quantile_c(alpha/2.0, floor(Nzj)+1,1) - Nzj Nqcd_err_hi = Math.gamma_quantile_c(alpha/2.0, floor(Nqcd)+1,1) - Nqcd Nbkg_err_hi = Math.gamma_quantile_c(alpha/2.0, floor(Nbkg)+1,1) - Nbkg stat_err = xsec / sqrt(Nevts) syst_err = xsec * sqrt(pow(totaleff_err / totaleff, 2) + pow(A_err / A, 2) + pow(Nbkg_err_hi/(Nevts - Nbkg),2)) lumi_err = xsec * 0.039 print "Number of selected events: %f +/- %f" %(Nevts, sqrt(Nevts)) print "Same sign background : %f + %f - %f" %(Nqcd, Nqcd_err_hi, Nqcd_err_lo) print "Z+jets background : %f + %f - %f" %(Nzj, Nzj_err_hi, Nzj_err_lo) print "Wt background : %f + %f - %f" %(Nwt, Nwt_err_hi, Nwt_err_lo) print "Background Events : %f + %f - %f" %(Nbkg, Nbkg_err_hi, Nbkg_err_lo) print "Lumi : %f +/- %f" %(L, L_err)