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)
Nzj = zmumuj_data.Get('TotEvts').GetVal()*ztautauj.Get('NormEvts').GetVal()/zmumuj.Get('NormEvts').GetVal() #Nwt = (Nevts - (Nqcd + Nzj))*(wtOttbar/(1+wtOttbar)) Nwt = powheg_predictions.Get("Wt_dr_xsec").GetVal() * L * totaleff_wt Nsig = Nevts - Nqcd - Nzj - Nwt 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)
def __call__(self, population, signalYield, signalSample, backgroundYield, backgroundSample): # Histogram holders signalHistogram = TH1F('signalHistogram', 'signal', self.nbins, 0, 1) backgroundHistogram = TH1F('backgroundHistogram', 'background', self.nbins, 0, 1) # Loop over the chromosomes in the population for genome in population: # Reset histograms signalHistogram.Reset() backgroundHistogram.Reset() # Get a nn describe by the chromosome (feed foreward) net = nn.create_ffphenotype(genome) # Loop over the events creating signal histogram for event in signalSample: # Extract variables and weight variables = event[1:] weight = event[0] # Not strictly necessary in feedforward nets net.flush() # Net output output = net.sactivate(variables)[0] # Filling histograms signalHistogram.Fill(output, weight) # Signal overall normalization scale signalScale = signalYield / len(signalSample) # Loop over the events creating background histogram for event in backgroundSample: # Extract variables and weight variables = event[1:] weight = event[0] # Not strictly necessary in feedforward nets net.flush() # Net output output = net.sactivate(variables)[0] # Filling histograms backgroundHistogram.Fill(output, weight) # Background overall normalization scale backgroundScale = backgroundYield / len(backgroundSample) # Random generators rcount = TRandom3(int(random.uniform(0, 65535))) rsignal = TRandom3(int(random.uniform(0, 65535))) rbackground = TRandom3(int(random.uniform(0, 65535))) zscore = 0. sqweight = 0. # Computing weighted z-score for bin in xrange(1, signalHistogram.GetNbinsX() + 1): newz = 0. oldz = 0. # Computing the zvalue per bin for point in xrange(1, self.mpoints + 1): # Sample background background = Math.gamma_quantile( rbackground.Uniform(), (backgroundHistogram.GetBinContent(bin) / backgroundScale) + 1., backgroundScale) # Background larger that zero if background > 0.: # Sampling signal signal = Math.gamma_quantile( rsignal.Uniform(), (signalHistogram.GetBinContent(bin) / signalScale) + 1., signalScale) # Sampling count count = rcount.Poisson(signal + background) # Computing pvalue pvalue = Math.poisson_cdf_c( count, background) + Math.poisson_pdf( count, background) # Computing zvalue zvalue = self.minz if pvalue < 1.0: zvalue = Math.normal_quantile_c(pvalue, 1) # zvalue iterative average newz = (zvalue + (point - 1) * oldz) / point # Computing relative difference error = math.fabs((newz - oldz) / newz) # Convergency criteria if error < self.error: break # Updating oldz oldz = newz if point == self.mpoints: self.message( 'Warning reach maximum number of integration %s points.' % point) weight = self.weight(signalHistogram.GetBinCenter(bin)) zscore = zscore + weight * newz sqweight = sqweight + weight**2 # Fitness function is zscore transform back to 1 - pvalue # Set the fitness value to the chomosome genome.fitness = 1. - Math.normal_cdf_c( zscore / Math.sqrt(sqweight))
def __call__(self, population, signalYield, signalSample, backgroundYield, backgroundSample): # Histogram holders signalHistogram = TH1F('signalHistogram', 'signal', self.nbins, 0, 1) backgroundHistogram = TH1F('backgroundHistogram', 'background', self.nbins, 0, 1) # Loop over the chromosomes in the population for genome in population: # Reset histograms signalHistogram.Reset() backgroundHistogram.Reset() # Get a nn describe by the chromosome (feed foreward) net = nn.create_ffphenotype(genome) # Loop over the events creating signal histogram for event in signalSample: # Extract variables and weight variables = event[1:] weight = event[0] # Not strictly necessary in feedforward nets net.flush() # Net output output = net.sactivate(variables)[0] # Filling histograms signalHistogram.Fill(output, weight) # Signal overall normalization scale signalScale = signalYield/len(signalSample) # Loop over the events creating background histogram for event in backgroundSample: # Extract variables and weight variables = event[1:] weight = event[0] # Not strictly necessary in feedforward nets net.flush() # Net output output = net.sactivate(variables)[0] # Filling histograms backgroundHistogram.Fill(output, weight) # Background overall normalization scale backgroundScale = backgroundYield/len(backgroundSample) # Random generators rcount = TRandom3(int(random.uniform(0,65535))) rsignal = TRandom3(int(random.uniform(0,65535))) rbackground = TRandom3(int(random.uniform(0,65535))) zscore = 0.; sqweight = 0. # Computing weighted z-score for bin in xrange(1,signalHistogram.GetNbinsX()+1): newz = 0.; oldz = 0. # Computing the zvalue per bin for point in xrange(1,self.mpoints+1): # Sample background background = Math.gamma_quantile(rbackground.Uniform(), (backgroundHistogram.GetBinContent(bin)/backgroundScale)+1., backgroundScale ) # Background larger that zero if background > 0.: # Sampling signal signal = Math.gamma_quantile(rsignal.Uniform(), (signalHistogram.GetBinContent(bin)/signalScale)+1., signalScale ) # Sampling count count = rcount.Poisson(signal+background) # Computing pvalue pvalue = Math.poisson_cdf_c(count,background) + Math.poisson_pdf(count,background) # Computing zvalue zvalue = self.minz if pvalue < 1.0: zvalue = Math.normal_quantile_c(pvalue,1) # zvalue iterative average newz = (zvalue + (point - 1)*oldz)/point # Computing relative difference error = math.fabs((newz - oldz)/newz) # Convergency criteria if error < self.error: break # Updating oldz oldz = newz if point == self.mpoints: self.message('Warning reach maximum number of integration %s points.' % point) weight = self.weight(signalHistogram.GetBinCenter(bin)) zscore = zscore + weight * newz sqweight = sqweight + weight**2 # Fitness function is zscore transform back to 1 - pvalue # Set the fitness value to the chomosome genome.fitness = 1. - Math.normal_cdf_c(zscore/Math.sqrt(sqweight))