def writeFullUnc(pred_file): ''' Update the input root file, add a hist with total prediction and full uncertainty. ''' f = rt.TFile(pred_file, 'UPDATE') h = TGraphAsymmErrors(f.Get(pred_total_name).Clone('bkgtotal_unc_sr')) h_syst = TGraphAsymmErrors( f.Get(pred_total_name).Clone('bkgtotal_syst_unc_sr')) h_pieces = {} h_syst_pieces = {} for hname, sample in zip(graph_names, all_samples): h_pieces[sample] = TGraphAsymmErrors( f.Get(hname).Clone(sample + '_unc_sr')) h_syst_pieces[sample + "_up"] = TH1F(sample + '_syst_up', sample + '_syst_up', 183, 0, 183) h_syst_pieces[sample + "_dn"] = TH1F(sample + '_syst_dn', sample + '_syst_dn', 183, 0, 183) print "%30s %10s %16s" % ('bin', 'total pred', 'total unc.') for ibin in xrange(0, h.GetN()): bin = binlist[ibin] val = h.GetY()[ibin] e_low, e_up = fullUnc[bin] h.SetPointEYlow(ibin, e_low) h.SetPointEYhigh(ibin, e_up) print "%30s %10.4f +%8.4f -%8.4f" % (bin, val, e_up, e_low) allVals[bin] = {'bkg': (val, e_low, e_up)} # Test for only syst histograms val = h_syst.GetY()[ibin] e_low, e_up = systUnc[bin] h_syst.SetPointEYlow(ibin, e_low) h_syst.SetPointEYhigh(ibin, e_up) for sample in all_samples: val = yields[bin][sample] e_low, e_up = fullUnc_pieces[sample][bin] #print "%11s %30s %10.4f +%8.4f -%8.4f" % (sample, bin, val, e_up, e_low) h_pieces[sample].SetPointEYlow(ibin, e_low) h_pieces[sample].SetPointEYhigh(ibin, e_up) allVals[bin][sample] = (val, e_low, e_up) # Test for only syst histograms e_low, e_up = systUnc_rel_pieces[sample][bin] #if sample in test_samp and bin in test_bin and type in test_type and debug: #if 'TTZ' in sample and e_up > 8: # print("%11s %30s %10.4f +%8.4f -%8.4f" % (sample, bin, val, e_up, e_low)) h_syst_pieces[sample + "_up"].SetBinContent(ibin + 1, e_up) h_syst_pieces[sample + "_dn"].SetBinContent(ibin + 1, e_low) h_syst_pieces[sample + "_up"].SetBinError(ibin + 1, 0) h_syst_pieces[sample + "_dn"].SetBinError(ibin + 1, 0) h.Write('bkgtotal_unc_sr', rt.TObject.kOverwrite) h.Write('bkgtotal_syst_unc_sr', rt.TObject.kOverwrite) for sample in all_samples: h_pieces[sample].Write(sample + '_unc_sr', rt.TObject.kOverwrite) h_syst_pieces[sample + "_up"].Write(sample + '_syst_up', rt.TObject.kOverwrite) h_syst_pieces[sample + "_dn"].Write(sample + '_syst_dn', rt.TObject.kOverwrite) f.Close()
def numericalInvertPlot(graph): #pick up point by point pl #loop on all data points nPoints = graph.GetN() newGraph = TGraphAsymmErrors(nPoints) #x=array('f') #y=array('f') #ey=array('f') for iPoint in xrange(0, nPoints): #get info on data point dataPointX = Double(0) dataPointY = Double(0) graph.GetPoint(iPoint, dataPointX, dataPointY) dataErrorX = graph.GetErrorX(iPoint) dataErrorY = graph.GetErrorY(iPoint) #numerical-invert the X newDataPointX = dataPointX * dataPointY newErrorXLeft = fabs(newDataPointX - (dataPointX - dataErrorX)) newErrorXRight = fabs(newDataPointX - (dataPointX + dataErrorX)) #setting the new graph (with asymm errors this time) newGraph.SetPoint(iPoint, newDataPointX, dataPointY) newGraph.SetPointEXhigh(iPoint, newErrorXRight) newGraph.SetPointEXlow(iPoint, newErrorXLeft) newGraph.SetPointEYhigh(iPoint, dataErrorY) newGraph.SetPointEYlow(iPoint, dataErrorY) print dataPointY, newDataPointX #check that the numerical-inverted X is still in the previous bin - otherwise, ERROR! binRangeLow = dataPointX - dataErrorX binRangeHigh = dataPointX + dataErrorX if newDataPointX < binRangeLow or newDataPointX > binRangeHigh: print "Warning! Data point should not be here!" print "Old data point: ", dataPointX print "New NI data point:", newDataPointX print "XLow: ", binRangeLow print "XHigh: ", binRangeHigh newGraph.SetPoint(iPoint, dataPointX, 0.0000000000001) newGraph.SetPointEXhigh(iPoint, dataErrorX) newGraph.SetPointEXlow(iPoint, dataErrorX) newGraph.SetPointEYhigh(iPoint, dataErrorY) newGraph.SetPointEYlow(iPoint, dataErrorY) return newGraph
def writeFullUnc(pred_file): ''' Update the input root file, add a hist with total prediction and full uncertainty. ''' f = rt.TFile(pred_file, 'UPDATE') h = TGraphAsymmErrors(f.Get(pred_total_name).Clone('bkgtotal_unc_sr')) h_pieces = {} for hname, sample in zip(graph_names, all_samples): h_pieces[sample] = TGraphAsymmErrors( f.Get(hname).Clone(sample + '_unc_sr')) print "%30s %10s %16s" % ('bin', 'total pred', 'total unc.') for ibin in xrange(0, h.GetN()): bin = binlist[ibin] val = h.GetY()[ibin] e_low, e_up = fullUnc[bin] h.SetPointEYlow(ibin, e_low) h.SetPointEYhigh(ibin, e_up) print "%30s %10.2f +%8.2f -%8.2f" % (bin, val, e_up, e_low) allVals[bin] = {'bkg': (val, e_low, e_up)} for sample in all_samples: val = yields[bin][sample] e_low, e_up = fullUnc_pieces[sample][bin] h_pieces[sample].SetPointEYlow(ibin, e_low) h_pieces[sample].SetPointEYhigh(ibin, e_up) allVals[bin][sample] = (val, e_low, e_up) h.Write('bkgtotal_unc_sr', rt.TObject.kOverwrite) for sample in all_samples: h_pieces[sample].Write(sample + '_unc_sr', rt.TObject.kOverwrite) f.Close()
def convertToPoisson(h): graph = TGraphAsymmErrors() q = (1-0.6827)/2. for i in range(1,h.GetNbinsX()+1): x=h.GetXaxis().GetBinCenter(i) xLow =h.GetXaxis().GetBinLowEdge(i) xHigh =h.GetXaxis().GetBinUpEdge(i) y=h.GetBinContent(i) yLow=0 yHigh=0 if y !=0.0: yLow = y-Math.chisquared_quantile_c(1-q,2*y)/2. yHigh = Math.chisquared_quantile_c(q,2*(y+1))/2.-y graph.SetPoint(i-1,x,y) graph.SetPointEYlow(i-1,yLow) graph.SetPointEYhigh(i-1,yHigh) graph.SetPointEXlow(i-1,0.0) graph.SetPointEXhigh(i-1,0.0) graph.SetMarkerStyle(20) graph.SetLineWidth(2) graph.SetMarkerSize(1.) graph.SetMarkerColor(kBlack) return graph
def makeResidHist(data, bkg): pulls = TGraphAsymmErrors(data.GetN()) pulls.SetName("Pulls") pulls.SetLineWidth(data.GetLineWidth()) pulls.SetLineStyle(data.GetLineStyle()) pulls.SetLineColor(data.GetLineColor()) pulls.SetMarkerSize(data.GetMarkerSize()) pulls.SetMarkerStyle(data.GetMarkerStyle()) pulls.SetMarkerColor(data.GetMarkerColor()) pulls.SetFillStyle(data.GetFillStyle()) pulls.SetFillColor(data.GetFillColor()) # Add histograms, calculate Poisson confidence interval on sum value for i in range(data.GetN()): x = data.GetX()[i] dyl = data.GetErrorYlow(i) dyh = data.GetErrorYhigh(i) yy = data.GetY()[i] - bkg.Interpolate(x) #bkg.GetBinContent(i+1) norm = dyl if yy > 0. else dyh if norm == 0.: yy, dyh, dyl = 0., 0., 0. else: yy /= norm dyh /= norm dyl /= norm pulls.SetPoint(i, x, yy) pulls.SetPointEYhigh(i, dyh) pulls.SetPointEYlow(i, dyl) return pulls
def apply_centers(hPt, hCen): #bin center points according to the data cen = get_centers_from_toyMC(hCen) gSig = TGraphAsymmErrors(hPt.GetNbinsX()) for i in xrange(hPt.GetNbinsX()): #center point #xcen = hPt.GetBinCenter(i+1) xcen = cen[i]["val"] #cross section value gSig.SetPoint(i, xcen, hPt.GetBinContent(i + 1)) #vertical error gSig.SetPointEYlow(i, hPt.GetBinErrorLow(i + 1)) gSig.SetPointEYhigh(i, hPt.GetBinErrorUp(i + 1)) #horizontal error gSig.SetPointEXlow(i, cen[i]["err"]) gSig.SetPointEXhigh(i, cen[i]["err"]) return gSig
def fixData(hist, useGarwood=True, cutGrass=False, maxPoisson=False): if hist == None: return varBins = False data = TGraphAsymmErrors() alpha = 1 - 0.6827 for i in list(reversed(range(0, hist.GetNbinsX()))): #print "bin", i, "x:", hist.GetX()[i], "y:", hist.GetY()[i] # X error bars to 0 - do not move this, otherwise the first bin will disappear, thanks Wouter and Rene! N = max(hist.GetBinContent(i + 1), 0.) # Avoid unphysical bins data.SetPoint(i, hist.GetXaxis().GetBinCenter(i + 1), N) if not varBins: data.SetPointEXlow(i, 0) data.SetPointEXhigh(i, 0) # Garwood confidence intervals if (useGarwood): L = ROOT.Math.gamma_quantile(alpha / 2, N, 1.) if N > 0 else 0. U = ROOT.Math.gamma_quantile_c(alpha / 2, N + 1, 1) # maximum between Poisson and Sumw2 error bars EL = N - L if not maxPoisson else max(N - L, hist.GetBinErrorLow(i)) EU = U - N if not maxPoisson else max(U - N, hist.GetBinErrorHigh(i)) data.SetPointEYlow(i, EL) data.SetPointEYhigh(i, EU) else: data.SetPointEYlow(i, math.sqrt(N)) data.SetPointEYhigh(i, math.sqrt(N)) # Cut grass if cutGrass and data.GetY()[i] > 0.: cutGrass = False # Treatment for 0 bins # if abs(hist.GetY()[i])<=1.e-6: # if cutGrass: hist.SetPointError(i, hist.GetErrorXlow(i), hist.GetErrorXhigh(i), 1.e-6, 1.e-6, ) # if (hist.GetX()[i]>65 and hist.GetX()[i]<135 and hist.GetY()[i]==0): hist.SetPointError(i, hist.GetErrorXlow(i), hist.GetErrorXhigh(i), 1.e-6, 1.e-6, ) # hist.SetPoint(i, hist.GetX()[i], -1.e-4) # X error bars #if hist.GetErrorXlow(i)<1.e-4: # binwidth = hist.GetX()[1]-hist.GetX()[0] # hist.SetPointEXlow(i, binwidth/2.) # hist.SetPointEXhigh(i, binwidth/2.) data.SetMarkerColor(hist.GetMarkerColor()) data.SetMarkerStyle(hist.GetMarkerStyle()) data.SetMarkerSize(hist.GetMarkerSize()) #data.SetLineSize(hist.GetLineSize()) return data
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 normalizeGraph(graph, binwidth): xsecSum = 0. for pt in range(1, graph.GetN()): xsecSum += graph.GetY()[pt] * binwidth[pt] normGraph = TGraphAsymmErrors(graph.GetN() - 1) for pt in range(0, normGraph.GetN()): normGraph.SetPoint(pt, graph.GetX()[pt + 1], graph.GetY()[pt + 1] / xsecSum) normGraph.SetPointEYhigh(pt, graph.GetErrorYhigh(pt + 1) / xsecSum) normGraph.SetPointEYlow(pt, graph.GetErrorYlow(pt + 1) / xsecSum) return normGraph
def histToGraph(hist, name='', keepErrors=True, poissonErrors=True): ## Helper method to convert a histogram to a corresponding graph # @hist TH1 object # @name name of the graph (default is name of histogram) # @keepErrors decide if the y-errors should be propagated to the graph # @poissonErrors decide if the y-errors should be calculated as Poisson errors # @return graph if not name: name = 'g%s' % (hist.GetName()) from ROOT import TGraphAsymmErrors nBins = hist.GetNbinsX() graph = TGraphAsymmErrors(nBins) graph.SetNameTitle(name, hist.GetTitle()) xAxis = hist.GetXaxis() for i in xrange(nBins): xVal = xAxis.GetBinCenter(i + 1) yVal = hist.GetBinContent(i + 1) graph.SetPoint(i, xVal, yVal) graph.SetPointEXlow(i, abs(xVal - xAxis.GetBinLowEdge(i + 1))) graph.SetPointEXhigh(i, abs(xVal - xAxis.GetBinUpEdge(i + 1))) if keepErrors: if poissonErrors: lo, hi = calculatePoissonErrors(yVal) graph.SetPointEYlow(i, lo) graph.SetPointEYhigh(i, hi) else: graph.SetPointEYlow(i, hist.GetBinErrorLow(i + 1)) graph.SetPointEYhigh(i, hist.GetBinErrorUp(i + 1)) # copy the style graph.SetMarkerStyle(hist.GetMarkerStyle()) graph.SetMarkerColor(hist.GetMarkerColor()) graph.SetMarkerSize(hist.GetMarkerSize()) graph.SetLineStyle(hist.GetLineStyle()) graph.SetLineColor(hist.GetLineColor()) graph.SetLineWidth(hist.GetLineWidth()) graph.SetFillColor(hist.GetFillColor()) graph.SetFillStyle(hist.GetFillStyle()) return graph
def diffGraph(self, g, h, opt): gdiff = TGraphAsymmErrors(g) gdiff.SetName(g.GetName() + h.GetName() + '_diff') for i in range(0, gdiff.GetN()): x = Double(0.) y = Double(0.) g.GetPoint(i, x, y) gdiff.SetPoint(i, x, y - h.GetBinContent(i + 1)) if opt == 1: # keep bin errors pass elif opt == 2: gdiff.SetPointEYhigh( i, math.sqrt(g.GetErrorYhigh(i)**2 + h.GetBinError(i + 1)**2)) return gdiff
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 fixed_centers(hPt): #fixed bin centers gSig = TGraphAsymmErrors(hPt.GetNbinsX()) for i in xrange(hPt.GetNbinsX()): #cross section value gSig.SetPoint(i, hPt.GetBinCenter(i + 1), hPt.GetBinContent(i + 1)) #vertical error gSig.SetPointEYlow(i, hPt.GetBinErrorLow(i + 1)) gSig.SetPointEYhigh(i, hPt.GetBinErrorUp(i + 1)) #horizontal error gSig.SetPointEXlow(i, hPt.GetBinWidth(i + 1) / 2.) gSig.SetPointEXhigh(i, hPt.GetBinWidth(i + 1) / 2.) return gSig
def totalBkgWithStatErrors( self ): total_bkg_hist = None low, high = None, None for p in self.__processes: if p.isSignal(): continue nbins = p.nominal().GetXaxis().GetNbins() if low is None: low = [0]*nbins if high is None: high = [0]*nbins if total_bkg_hist is None: total_bkg_hist = p.nominal().Clone() else: total_bkg_hist.Add( p.nominal() ) gr = None if p.name() in ['nonpromptDF']: gr = self.__dfGraph elif p.name() in ['nonpromptSF']: gr = self.__sfGraph if gr: for ib in range(nbins): low[ib] += math.pow(gr.GetEYlow()[ib], 2) high[ib] += math.pow(gr.GetEYhigh()[ib], 2) else: for ib in range(nbins): low[ib] += math.pow(p.nominal().GetBinError(ib), 2) high[ib] += math.pow(p.nominal().GetBinError(ib), 2) for ib in range(len(low)): low[ib] = math.sqrt(low[ib]) high[ib] = math.sqrt(high[ib]) total_bkg_graph = TGraphAsymmErrors(total_bkg_hist) for ib in range(total_bkg_graph.GetN()): total_bkg_graph.SetPointEYlow(ib, low[ib]) total_bkg_graph.SetPointEYhigh(ib, high[ib]) return [total_bkg_hist, total_bkg_graph]
alpha = 1. - 0.6827 nevents = 0 for b in range(h14G.GetN()): if unfoldedData: N = origh14.GetBinContent(b + 1) else: N = 1. / pow( h14.GetBinError(b + 1) / h14.GetBinContent(b + 1), 2) print N nevents += N L = 0 if N > 0: L = ROOT.Math.gamma_quantile(alpha / 2., N, 1.) U = ROOT.Math.gamma_quantile_c(alpha / 2., N + 1, 1.) h14G.SetPointEYlow(b, (N - L) / N * h14.GetBinContent(b + 1)) h14G.SetPointEYhigh(b, (U - N) / N * h14.GetBinContent(b + 1)) print "data events:", nevents h14Gsys = h14G.Clone(histname + "sys") new_hists += [h14Gsys] h14Gsysstat = h14G.Clone(histname + "sysstat") new_hists += [h14Gsysstat] filename = "datacard_shapelimit13TeV_QCD_chi2016_backup.root" print filename fsys = TFile.Open(filename) new_hists += [fsys] uncertaintynames = ["jer", "jes", "pdf", "scale"] #uncertaintynames=["jer","jes","scale"] uncertainties = [] for u in uncertaintynames:
def make_plots_ROOT(histograms, category, save_path, histname, channel): global variable, translateOptions, k_value, b_tag_bin, maximum ROOT.TH1.SetDefaultSumw2(False) ROOT.gROOT.SetBatch(True) ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;') plotting.setStyle() gStyle.SetTitleYOffset(2.) ROOT.gROOT.ForceStyle() canvas = Canvas(width=700, height=500) canvas.SetLeftMargin(0.18) canvas.SetBottomMargin(0.15) canvas.SetTopMargin(0.05) canvas.SetRightMargin(0.05) legend = plotting.create_legend(x0=0.6, y1=0.5) hist_data = histograms['unfolded'] hist_data.GetXaxis().SetTitle(translate_options[variable] + ' [GeV]') hist_data.GetYaxis().SetTitle('#frac{1}{#sigma} #frac{d#sigma}{d' + translate_options[variable] + '} [GeV^{-1}]') hist_data.GetXaxis().SetTitleSize(0.05) hist_data.GetYaxis().SetTitleSize(0.05) hist_data.SetMinimum(0) hist_data.SetMaximum(maximum[variable]) hist_data.SetMarkerSize(1) hist_data.SetMarkerStyle(8) plotAsym = TGraphAsymmErrors(hist_data) plotStatErr = TGraphAsymmErrors(hist_data) xsections = read_unfolded_xsections(channel) bins = variable_bins_ROOT[variable] assert (len(bins) == len(xsections['central'])) for bin_i in range(len(bins)): scale = 1 # / width centralresult = xsections['central'][bin_i] fit_error = centralresult[1] uncertainty = calculateTotalUncertainty(xsections, bin_i) uncertainty_total_plus = uncertainty['Total+'][0] uncertainty_total_minus = uncertainty['Total-'][0] uncertainty_total_plus, uncertainty_total_minus = symmetriseErrors( uncertainty_total_plus, uncertainty_total_minus) error_up = sqrt(fit_error**2 + uncertainty_total_plus**2) * scale error_down = sqrt(fit_error**2 + uncertainty_total_minus**2) * scale plotStatErr.SetPointEYhigh(bin_i, fit_error * scale) plotStatErr.SetPointEYlow(bin_i, fit_error * scale) plotAsym.SetPointEYhigh(bin_i, error_up) plotAsym.SetPointEYlow(bin_i, error_down) gStyle.SetEndErrorSize(20) plotAsym.SetLineWidth(2) plotStatErr.SetLineWidth(2) hist_data.Draw('P') plotStatErr.Draw('same P') plotAsym.Draw('same P Z') legend.AddEntry(hist_data, 'unfolded', 'P') hist_measured = histograms['measured'] hist_measured.SetMarkerSize(1) hist_measured.SetMarkerStyle(20) hist_measured.SetMarkerColor(2) #hist_measured.Draw('same P') #legend.AddEntry(hist_measured, 'measured', 'P') for key, hist in sorted(histograms.iteritems()): if not 'unfolded' in key and not 'measured' in key: hist.SetLineStyle(7) hist.SetLineWidth(2) # setting colours if 'POWHEG' in key or 'matchingdown' in key: hist.SetLineColor(kBlue) elif 'MADGRAPH' in key or 'matchingup' in key: hist.SetLineColor(kRed + 1) elif 'MCATNLO' in key or 'scaleup' in key: hist.SetLineColor(kGreen - 3) elif 'scaledown' in key: hist.SetLineColor(kMagenta + 3) hist.Draw('hist same') legend.AddEntry(hist, translate_options[key], 'l') legend.Draw() mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC") channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC") if 'electron' in histname: channelLabel.AddText( "e, %s, %s, k = %s" % ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value)) elif 'muon' in histname: channelLabel.AddText( "#mu, %s, %s, k = %s" % ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value)) else: channelLabel.AddText( "combined, %s, %s, k = %s" % ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value)) mytext.AddText("CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" % (5.8)) mytext.SetFillStyle(0) mytext.SetBorderSize(0) mytext.SetTextFont(42) mytext.SetTextAlign(13) channelLabel.SetFillStyle(0) channelLabel.SetBorderSize(0) channelLabel.SetTextFont(42) channelLabel.SetTextAlign(13) mytext.Draw() channelLabel.Draw() canvas.Modified() canvas.Update() path = save_path + '/' + variable + '/' + category make_folder_if_not_exists(path) canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.png') canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.pdf')
def uncertainty_band(process, region, calculation, uncertainty, estimation): """Calculates an uncertainty band (TGraphAsymmErrors) for a specific uncertainty. Any uncertainties (except statistical) that have a shape component will have the shape component converted to an overall component (considered in addition to any existing overall component). NOTE: CURRENTLY ROOT'S STATISTICAL ERRORS ARE USED AND THIS METHOD IS DISABLED NOTE: The statistical error calculated is the statistical error on the estimate given the poisson statistics of the unweighted samples. This is calculated per-bin as: uncertainty = sqrt(unweighted) * weighted / unweighted = weighted / sqrt(unweighted) For samples such as data, where there is no weighting applied, this just reduces to sqrt(weighted) = sqrt(unweighted), which is the usual uncertainty applied by ROOT. NOTE: The y-component of the uncertainty band will NOT be set to bin content because this leads to errors in usage when combining the bands and is only really necessary when computing the final combined band, so instead simply pass a base for the error band when calling combined_uncertainty_band. Args: process: The process to consider region: The region to consider calculation: The calculation, which should return a histogram uncertainty: The Uncertainty subclass to consider, or None to compute statistical uncertainty of Monte Carlo samples estimation: The Estimation subclass to consider Returns: A TGraphAsymmErrors representing the error band. """ # Compute the nominal histogram nominal = estimation(calculation)(process, region) # Compute and unpack variations if uncertainty is not None: # Perform the uncertainty estimation variations = estimation(uncertainty(calculation))(process, region) # Unpack variations overall_up, overall_down, shape_up, shape_down = variations # Convert any shape variations to overall if shape_up is None: shape_overall_up = None else: shape_overall_up = to_overall(shape_up, nominal) shape_up = None if shape_down is None: shape_overall_down = None else: shape_overall_down = to_overall(shape_down, nominal) shape_down = None else: # We're computing statistical variation, so we don't need these overall_up = overall_down = None shape_up = shape_down = None shape_overall_up = shape_overall_down = None # TODO: What's the idea here? This doesn't work as it is. # For computing the uncertainty of weighted MC samples, we need the # unweighted histogram #unweighted = estimation(calculation)( #process, #region.weighted(False), #weighted_combination = False #) # Create the error band. We pass it the nominal histogram just to get # the binning correct. The graph will also extract values and errors # from the histogram, but that's okay because we'll overwrite them # below. band = TGraphAsymmErrors(nominal) # Get the number of bins in the histogram bins = nominal.GetNbinsX() # Go through each point in the graph and 0-out the Y-value and Y-error. # Unfortunately we can't set the Y-value individually (which would have # been great since the X-values would already be at bin centers). # Anyway, no big deal, X-values are easy to set. The X-error will have # already bin set to bin width. for bin in xrange(0, bins): band.SetPoint(bin, band.GetX()[bin], 0) band.SetPointEYhigh(bin, 0.0) band.SetPointEYlow(bin, 0.0) # Loop over all bins and compute uncertainties for bin, point in zip(range(1, bins + 1), range(0, bins)): # Get the bin content content = nominal.GetBinContent(bin) # If the content is 0, there are no uncertainties, because we only # consider overall and statistical uncertainties if content == 0.0: band.SetPointEYhigh(point, 0.0) band.SetPointEYlow(point, 0.0) continue # Create a list of fractional variations for this bin. These lists # will hold FRACTIONAL variations, i.e. variations normalized to bin # content, and will be converted to absolute variations below when they # are set as errors. up_variations = [] down_variations = [] # Add any overall variations if overall_up is not None: up_variations.append(overall_up - 1.0) if overall_down is not None: down_variations.append(1.0 - overall_down) if shape_overall_up is not None: up_variations.append(shape_overall_up - 1.0) if shape_overall_down is not None: down_variations.append(1.0 - shape_overall_down) # TODO: What's the point of using the unweighted distribution? It # makes no sense to me. # Add the statistical variation if uncertainty is None. Note that we # compute this for the statistics of the unweighted Monte Carlo and not # the weighted bin count. #if uncertainty is None: ## Get the unweighted content #unweighted_content = unweighted.GetBinContent(bin) ## Calculate error if possible #if content > 0.0 and unweighted_content > 0.0: ## The extra factor of 1/content is just because we normalize ## everything to content for combining together. It has nothing ## to do with the derivation of the uncertainty, and it is ## multipled out below. #statistical_variation = ( #content / sqrt(unweighted_content) #) / content #up_variations.append(statistical_variation) #down_variations.append(statistical_variation) # Statistical error; use the error from the distribution directly if uncertainty is None: error = nominal.GetBinError(bin) band.SetPointEYhigh(point, error) band.SetPointEYlow(point, error) else: # Set the point and error. Note that, since we sum things in # quadrature, it really doesn't matter how we compute the # differences above. band.SetPointEYhigh(point, sum_quadrature(up_variations) * content) band.SetPointEYlow(point, sum_quadrature(down_variations) * content) # All done return band
def make_ratioplot(name, ttbar_file=0, qcd_file=0, signal_files=[], histo=0, rebin=1, minx=0, maxx=0, miny=0, maxy=0, logy=False, xtitle='', ytitle='', textsizefactor=1, signal_legend=[], outfile=0, signal_colors=[], signal_zoom=1, qcd_zoom=1, ttbar_zoom=1, ttbar_legend='t#bar{t}', qcd_legend='QCD from MC', dosys=False, docms=True, legendtitle=''): ###canvas setting up canvas = 0 canvas = TCanvas(name, '', 0, 0, 600, 600) canvas.SetLeftMargin(0.15) canvas.SetRightMargin(0.05) canvas.SetTopMargin(0.10) canvas.SetBottomMargin(0.10) charsize = 0.04 offset = 1.9 ###latex label latex = 0 latex = TLatex(0.6, 0.7, '13 TeV, 2.69 fb^{-1}') latex.SetTextSize(charsize) latex.SetNDC(1) latex.SetTextFont(42) ###legend setting up #legend=TLegend(0.0,0.75,0.99,1.04) legend = TLegend(0.4, 0.6, 0.94, 0.95) legend.SetNColumns(2) legend.SetHeader('') legend.SetFillStyle(0) legend.SetBorderSize(0) ###mc stack stack = THStack(name + '_stack', '') qcd_histo = qcd_file.Get(histo).Clone(name + '_make_plot') qcd_histo.Rebin(rebin) ttbar_histo = ttbar_file.Get(histo).Clone() ttbar_histo.Rebin(rebin) ttbar_histo.SetFillColor(kRed - 9) ttbar_histo.SetLineColor(kRed - 9) ttbar_histo.SetMarkerColor(kRed - 9) if ttbar_zoom != 1: ttbar_histo.Scale(ttbar_zoom) legend.AddEntry(ttbar_histo, ttbar_legend, 'f') qcd_histo.SetFillColor(kOrange - 5) qcd_histo.SetLineColor(kOrange - 5) qcd_histo.SetMarkerColor(kOrange - 5) if qcd_zoom != 1: qcd_histo.Scale(qcd_zoom) legend.AddEntry(qcd_histo, qcd_legend, 'f') sum_mc = qcd_histo.Clone(histo + 'tmp') sum_mc.Add(ttbar_histo) stack.Add(ttbar_histo) stack.Add(qcd_histo) sum_mc.SetLineColor(kBlack) sum_mc.SetFillStyle(0) err = TGraphAsymmErrors(sum_mc) legend.AddEntry(err, 'Total uncertainty', 'f') if legendtitle == '': legend.AddEntry(0, "", '') legend.AddEntry(0, "g_{RS} #rightarrow t#bar{t} (2pb)", '') else: legend.AddEntry(0, "", '') legend.AddEntry(0, legendtitle, '') ###signal setting up signal_histos = [] colors = [ kBlack, kRed, kOrange, kBlue, kGreen + 3, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 ] styles = [ 1, 3, 5, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] if signal_colors != []: colors = signal_colors for i in range(len(signal_files)): signal_histos.append(signal_files[i].Get(histo).Clone()) signal_histos[i].SetLineWidth(3) signal_histos[i].SetLineStyle(styles[i]) signal_histos[i].SetLineColor(colors[i]) signal_histos[i].SetMarkerColor(colors[i]) signal_histos[i].Rebin(rebin) if signal_zoom != 1: signal_histos[i].Scale(signal_zoom) legend.AddEntry(signal_histos[i], signal_legend[i], 'l') ###mc shape line ttbar_line = 0 ttbar_line = ttbar_histo.Clone() ttbar_line.SetLineColor(kBlack) ttbar_line.SetFillStyle(0) ###mc errors if dosys: sys_diff_qcd = [] sys_diff_ttbar = [] for imtt in range(1, ttbar_histo.GetNbinsX() + 1): sys_diff_qcd.append([]) sys_diff_ttbar.append([]) #adding stat uncertainties <--removed # for imtt in range(1,ttbar_histo.GetNbinsX()+1): # sys_diff_ttbar[imtt-1].append(ttbar_histo.GetBinError(imtt)) # sys_diff_ttbar[imtt-1].append(-ttbar_histo.GetBinError(imtt)) # sys_diff_qcd[imtt-1].append(qcd_histo.GetBinError(imtt)) # sys_diff_qcd[imtt-1].append(-qcd_histo.GetBinError(imtt)) #adding flat uncertainties for imtt in range(1, ttbar_histo.GetNbinsX() + 1): #ttbar for i in [ 2.4, #pdf 10.0, #mu 3.0, #xsec 6.0, #toppt 1.0, #lumi 3.5, #jec 3.0, #jer 10.0, #btag #3.0,#trig 10.0, #toptag 3.0 ]: #pileup sys_diff_ttbar[imtt - 1].append( i / 100.0 * ttbar_histo.GetBinContent(imtt)) sys_diff_ttbar[imtt - 1].append( -i / 100.0 * ttbar_histo.GetBinContent(imtt)) closureunc = 5.0 # if '1b' in histo: # closureunc=5.0 # elif '2b' in histo: # closureunc=10.0 for i in [ 2.0, #modmass closureunc ]: #closure sys_diff_qcd[imtt - 1].append(i / 100.0 * qcd_histo.GetBinContent(imtt)) sys_diff_qcd[imtt - 1].append(-i / 100.0 * qcd_histo.GetBinContent(imtt)) # #3% trigger # sys_diff_ttbar[imtt-1].append(0.03*ttbar_histo.GetBinContent(imtt)) # sys_diff_ttbar[imtt-1].append(-0.03*ttbar_histo.GetBinContent(imtt)) # #2.7% lumi # sys_diff_ttbar[imtt-1].append(0.023*ttbar_histo.GetBinContent(imtt)) # sys_diff_ttbar[imtt-1].append(-0.023*ttbar_histo.GetBinContent(imtt)) # #15% ttbar # #sys_diff_ttbar[imtt-1].append(0.15*ttbar_histo.GetBinContent(imtt)) # #sys_diff_ttbar[imtt-1].append(-0.15*ttbar_histo.GetBinContent(imtt)) # #2.8% QCD # sys_diff_qcd[imtt-1].append(0.028*qcd_histo.GetBinContent(imtt)) # sys_diff_qcd[imtt-1].append(-0.028*qcd_histo.GetBinContent(imtt)) #combining uncertainties sys_tot_ttbar = [] sys_tot_qcd = [] sys_tot = [] sys_global_ttbar = [0.0, 0.0] sys_global_qcd = [0.0, 0.0] nevt_global = [0.0, 0.0, 0.0] for imtt in range(1, ttbar_histo.GetNbinsX() + 1): uperr_qcd = 0 downerr_qcd = 0 uperr_ttbar = 0 downerr_ttbar = 0 for error in sys_diff_ttbar[imtt - 1]: if error < 0: downerr_ttbar = downerr_ttbar + error * error else: uperr_ttbar = uperr_ttbar + error * error for error in sys_diff_qcd[imtt - 1]: if error < 0: downerr_qcd = downerr_qcd + error * error else: uperr_qcd = uperr_qcd + error * error sys_tot_ttbar.append( [math.sqrt(downerr_ttbar), math.sqrt(uperr_ttbar)]) sys_tot_qcd.append([math.sqrt(downerr_qcd), math.sqrt(uperr_qcd)]) sys_tot.append([ math.sqrt(downerr_qcd + downerr_ttbar), math.sqrt(uperr_qcd + uperr_ttbar) ]) sys_global_qcd[0] = sys_global_qcd[0] + downerr_qcd sys_global_qcd[1] = sys_global_qcd[1] + uperr_qcd sys_global_ttbar[0] = sys_global_ttbar[0] + downerr_ttbar sys_global_ttbar[1] = sys_global_ttbar[1] + uperr_ttbar # nevt_global[0]=nevt_global[0]+data_histo.GetBinContent(imtt) nevt_global[1] = nevt_global[1] + qcd_histo.GetBinContent(imtt) nevt_global[2] = nevt_global[2] + ttbar_histo.GetBinContent(imtt) #print 'ttbar+qcd',math.sqrt(uperr_qcd+uperr_ttbar),math.sqrt(downerr_qcd+downerr_ttbar) #print 'qcd',math.sqrt(uperr_qcd),math.sqrt(downerr_qcd) #print 'ttbar',math.sqrt(uperr_ttbar),math.sqrt(downerr_ttbar) err.SetPointEYhigh(imtt - 1, math.sqrt(uperr_qcd + uperr_ttbar)) err.SetPointEYlow(imtt - 1, math.sqrt(downerr_qcd + downerr_ttbar)) sys_global = [0.0, 0.0] sys_global[0] = math.sqrt(sys_global_qcd[0] + sys_global_ttbar[0]) sys_global[1] = math.sqrt(sys_global_qcd[1] + sys_global_ttbar[1]) sys_global_qcd[0] = math.sqrt(sys_global_qcd[0]) sys_global_qcd[1] = math.sqrt(sys_global_qcd[1]) sys_global_ttbar[0] = math.sqrt(sys_global_ttbar[0]) sys_global_ttbar[1] = math.sqrt(sys_global_ttbar[1]) # print name # print "\hline" # print "Multijet QCD & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[1],sys_global_qcd[1],sys_global_qcd[0]) # print "SM ttbar & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[2],sys_global_ttbar[1],sys_global_ttbar[0]) # print "\hline" # print "Total background & $%.0f^{+%.0f}_{-%.0f}$ \\\\" % (nevt_global[1]+nevt_global[2],sys_global[1],sys_global[0]) # print 'DATA & %.0f' %nevt_global[0] err.SetFillStyle(3145) err.SetFillColor(kGray + 1) ###drawing top canvas.cd() stack.Draw('hist') stack.GetXaxis().SetTitle(ttbar_histo.GetXaxis().GetTitle()) stack.GetYaxis().SetTitle(ttbar_histo.GetYaxis().GetTitle()) stack.GetXaxis().SetLabelSize(charsize) stack.GetXaxis().SetTitleSize(charsize) stack.GetYaxis().SetLabelSize(charsize) stack.GetYaxis().SetTitleSize(charsize) stack.GetYaxis().SetTitleOffset(offset) if minx != 0 or maxx != 0: stack.GetXaxis().SetRangeUser(minx, maxx) #else: # stack.GetXaxis().SetRangeUser(0,4000) if miny != 0 or maxy != 0: stack.SetMaximum(maxy) stack.SetMinimum(miny) else: if logy: stack.SetMaximum(stack.GetMaximum() * 10) stack.SetMinimum(0.2) else: stack.SetMaximum(stack.GetMaximum() * 2.0) stack.SetMinimum(0.001) err.Draw('2') sum_mc.Draw('samehist') if ttbar_file != 0: ttbar_line.Draw('samehist') for i in signal_histos: i.Draw('samehist') if logy: canvas.SetLogy() legend.Draw() latex2text = '' if 'ldy_0b' in name: latex2text = '#Deltay < 1; 0 b tag' elif 'ldy_1b' in name: latex2text = '#Deltay < 1; 1 b tag' elif 'ldy_2b' in name: latex2text = '#Deltay < 1; 2 b tag' elif 'hdy_0b' in name: latex2text = '#Deltay > 1; 0 b tag' elif 'hdy_1b' in name: latex2text = '#Deltay > 1; 1 b tag' elif 'hdy_2b' in name: latex2text = '#Deltay > 1; 2 b tag' latex2 = TLatex(0.19, 0.7, latex2text) latex2.SetTextSize(0.03) latex2.SetNDC(1) latex2.SetTextFont(42) latex2.Draw() if docms: if '3000' in name: CMS_lumi.CMS_lumi(canvas, 3, 11) elif '1000' in name: CMS_lumi.CMS_lumi(canvas, 2, 11) elif '300' in name: CMS_lumi.CMS_lumi(canvas, 1, 11) elif '36' in name: CMS_lumi.CMS_lumi(canvas, 0, 11) ###saving canvas.SaveAs('pdf/' + name + '.pdf') if outfile != 0: canvas.Write()
def nuisance_plot(input_file_, orien_, sticker_, oname_): pars = get_parameters_from_file(input_file_) #adjust_parameters(pars) N = len(pars) g68 = TGraph(2 * N + 7) g95 = TGraph(2 * N + 7) gPR = TGraphAsymmErrors(N) for i in range(0, N): x = pars[i].value y = i + 1.5 xerr = pars[i].error yerr = 0. if orien_ == 'h': x, y = y, x xerr, yerr = yerr, xerr gPR.SetPoint(i, x, y) gPR.SetPointEXlow(i, xerr) gPR.SetPointEYlow(i, yerr) gPR.SetPointEXhigh(i, xerr) gPR.SetPointEYhigh(i, yerr) for a in range(0, N + 3): if orien_ == 'h': g68.SetPoint(a, a, -1) g95.SetPoint(a, a, -2) g68.SetPoint(a + 1 + N + 2, N + 2 - a, 1) g95.SetPoint(a + 1 + N + 2, N + 2 - a, 2) else: g68.SetPoint(a, -1, a) g95.SetPoint(a, -2, a) g68.SetPoint(a + 1 + N + 2, 1, N + 2 - a) g95.SetPoint(a + 1 + N + 2, 2, N + 2 - a) gPR.SetLineStyle(1) gPR.SetLineWidth(1) gPR.SetLineColor(1) gPR.SetMarkerStyle(21) gPR.SetMarkerSize(1.25) g68.SetFillColor(kGreen) g95.SetFillColor(kYellow) if orien_ == 'h': text_TL = TPaveText(0.100, 0.925, 0.440, 0.995, 'NDC') text_TR = TPaveText(0.587, 0.925, 0.999, 0.993, 'NDC') else: text_TL = TPaveText(0.370, 0.945, 0.590, 0.995, 'NDC') text_TR = TPaveText(0.600, 0.945, 0.995, 0.993, 'NDC') text_TL.AddText(label_TL) text_TL.SetFillColor(0) text_TL.SetTextAlign(12) text_TL.SetTextSize(0.06) text_TL.SetTextFont(42) text_TR.AddText(sticker_) text_TR.SetFillColor(0) text_TR.SetTextAlign(32) text_TR.SetTextSize(0.05) text_TR.SetTextFont(42) if orien_ == 'h': c = TCanvas('c', 'c', 1000, 700) c.SetTopMargin(0.08) c.SetRightMargin(0.02) c.SetBottomMargin(0.16) c.SetLeftMargin(0.11) else: c = TCanvas('c', 'c', 700, 1000) c.SetTopMargin(0.06) c.SetRightMargin(0.02) c.SetBottomMargin(0.12) c.SetLeftMargin(0.35 * 700 / 650) c.SetTickx() c.SetTicky() c.Update() g95.Draw('AF') g68.Draw('F') gPR.Draw('P') text_TL.Draw('same') text_TR.Draw('same') ax_1 = g95.GetHistogram().GetYaxis() ax_2 = g95.GetHistogram().GetXaxis() if orien_ == 'h': ax_1, ax_2 = ax_2, ax_1 ax_1.Set(N + 2, 0, N + 2) ax_1.SetNdivisions(-414) for i in range(0, N): ax_1.SetBinLabel(i + 2, pars[i].name) g95.SetTitle('') ax_2.SetTitle('post-fit nuisance parameters values') #ax_2.SetTitle('deviation in units of #sigma') ax_1.SetTitleSize(0.050) ax_2.SetTitleSize(0.050) ax_1.SetTitleOffset(1.4) ax_2.SetTitleOffset(1.0) ax_1.SetLabelSize(0.05) #ax_2.SetLabelSize(0.05) ax_1.SetRangeUser(0, N + 2) ax_2.SetRangeUser(-2.4, 2.4) g95.GetHistogram().Draw('axis,same') c.SaveAs(oname_ + '.pdf') c.Close()
def makeplot_single( h1_sig=None, h1_bkg=None, h1_data=None, sig_legends_=None, bkg_legends_=None, sig_colors_=None, bkg_colors_=None, hist_name_=None, sig_scale_=1.0, dir_name_="plots", output_name_=None, extraoptions=None ): if h1_sig == None or h1_bkg == None: print("nothing to plot...") return os.system("mkdir -p "+dir_name_) os.system("cp index.php "+dir_name_) s_color = [632, 617, 839, 800, 1] b_color = [920, 2007, 2005, 2003, 2001, 2011] if sig_colors_: s_color = sig_colors_ if bkg_colors_: b_color = bkg_colors_ for idx in range(len(h1_sig)): h1_sig[idx].SetLineWidth(3) h1_sig[idx].SetLineColor(s_color[idx]) for idx in range(len(h1_bkg)): h1_bkg[idx].SetLineWidth(2) h1_bkg[idx].SetLineColor(b_color[idx]) h1_bkg[idx].SetFillColorAlpha(b_color[idx], 1) if h1_data: h1_data.SetBinErrorOption(1) h1_data.SetLineColor(1) h1_data.SetLineWidth(2) h1_data.SetMarkerColor(1) h1_data.SetMarkerStyle(20) myC = r.TCanvas("myC","myC", 600, 600) myC.SetTicky(1) pad1 = r.TPad("pad1","pad1", 0.05, 0.33,0.95, 0.97) pad1.SetBottomMargin(0.027) pad1.SetRightMargin( rightMargin ) pad1.SetLeftMargin( leftMargin ) pad2 = r.TPad("pad2","pad2", 0.05, 0.04, 0.95, 0.31) pad2.SetBottomMargin(0.4) pad2.SetTopMargin(0.05) pad2.SetRightMargin( rightMargin ) pad2.SetLeftMargin( leftMargin ) pad2.Draw() pad1.Draw() pad1.cd() for idx in range(len(h1_sig)): print("before signal scaling",h1_sig[idx].Integral()) h1_sig[idx].Scale(sig_scale_) print("after signal scaling",h1_sig[idx].Integral()) stack = r.THStack("stack", "stack") nS = np.zeros(h1_bkg[0].GetNbinsX()) eS = np.zeros(h1_bkg[0].GetNbinsX()) #hist_all is used to make the data/mc ratio. remove signal for the moment due to signal is scaled right now hist_all = h1_sig[0].Clone("hist_all") hist_all.Scale(0.0) hist_s = h1_sig[0].Clone("hist_s") hist_b = h1_bkg[0].Clone("hist_b") for idx in range(len(h1_bkg)): stack.Add(h1_bkg[idx]) for ib in range(h1_bkg[0].GetNbinsX()): nS[ib] += h1_bkg[idx].GetBinContent(ib+1) eS[ib] = math.sqrt(eS[ib]*eS[ib] + h1_bkg[idx].GetBinError(ib+1)*h1_bkg[idx].GetBinError(ib+1)) hist_all.Add(h1_bkg[idx]) if idx > 0: hist_b.Add(h1_bkg[idx]) for idx in range(len(h1_sig)): print("ggH signal yield: ", hist_s.Integral()) if idx > 0: hist_temp = h1_sig[idx].Clone(h1_sig[idx].GetName()+"_temp") #hist_all.Add(hist_temp) hist_s.Add(h1_sig[idx]) print("all signal yield: ", hist_s.Integral()) stack.SetTitle("") maxY = 0.0 if "stack_signal" in extraoptions and extraoptions["stack_signal"]: for idx in range(len(h1_sig)): h1_sig[idx].SetFillColorAlpha(s_color[idx], 1) stack.Add(h1_sig[idx]) for ib in range(h1_bkg[0].GetNbinsX()): nS[ib] += h1_sig[idx].GetBinContent(ib+1) eS[ib] = math.sqrt(eS[ib]*eS[ib] + h1_sig[idx].GetBinError(ib+1)*h1_sig[idx].GetBinError(ib+1)) if stack.GetMaximum() > maxY: maxY = stack.GetMaximum() #if "SR" in h.GetTitle(): stack.Draw("hist") else: stack.Draw("hist") if stack.GetMaximum() > maxY: maxY = stack.GetMaximum() for idx in range(len(h1_sig)): if h1_sig[idx].GetMaximum() > maxY: maxY = h1_sig[idx].GetMaximum() if "SR" in h1_bkg[0].GetTitle(): #h1_sig[idx].Draw("samehist") hist_s.Draw("samehist") ##draw stack total unc on top of total histogram box = r.TBox(0,0,1,1,) box.SetFillStyle(3002) box.SetLineWidth(0) box.SetFillColor(r.kBlack) for idx in range(h1_bkg[0].GetNbinsX()): box.DrawBox(h1_bkg[0].GetBinCenter(idx+1)-0.5*h1_bkg[0].GetBinWidth(idx+1), nS[idx]-eS[idx], h1_bkg[0].GetBinCenter(idx+1)+0.5*h1_bkg[0].GetBinWidth(idx+1), nS[idx]+eS[idx]) if h1_data: if h1_data.GetMaximum() > maxY: maxY = h1_data.GetMaximum()+np.sqrt(h1_data.GetMaximum()) #if not "SR" in h1_data.GetTitle() or "fail" in h1_data.GetTitle(): if True: #print("debug h1_data.GetName()",h1_data.GetName(), h1_data.GetTitle()) TGraph_data = TGraphAsymmErrors(h1_data) for i in range(TGraph_data.GetN()): #data point var_x, var_y = Double(0.), Double(0.) TGraph_data.GetPoint(i,var_x,var_y) if np.fabs(var_y) < 1e-5: TGraph_data.SetPoint(i,var_x,-1.0) TGraph_data.SetPointEYlow(i,-1) TGraph_data.SetPointEYhigh(i,-1) #print("zero bins in the data TGraph: bin",i+1) else: TGraph_data.SetPoint(i,var_x,var_y) err_low = var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y)) TGraph_data.SetPointEYlow(i, var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y))) TGraph_data.SetPointEYhigh(i, (0.5*TMath.ChisquareQuantile(1.-0.1586555,2.*(var_y+1))) - var_y) TGraph_data.SetMarkerColor(1) TGraph_data.SetMarkerSize(1) TGraph_data.SetMarkerStyle(20) TGraph_data.Draw("same P") stack.GetYaxis().SetTitle("Events") stack.GetYaxis().SetTitleOffset(1.05) stack.GetYaxis().SetTitleSize(0.08) stack.GetYaxis().SetLabelSize(0.06) #stack.GetYaxis().CenterTitle() stack.GetXaxis().SetLabelSize(0.) #stack.GetXaxis().SetLabelOffset(0.013) #if "xaxis_range" in extraoptions: # stack.GetXaxis().SetRangeUser(float(extraoptions["xaxis_range"][0]),float(extraoptions["xaxis_range"][1])) leg = r.TLegend(0.2, 0.60, 0.9, 0.88) leg.SetNColumns(3) leg.SetFillStyle(0) leg.SetBorderSize(0) leg.SetTextFont(42) leg.SetTextSize(0.05) for idx in range(len(h1_bkg)): leg.AddEntry(h1_bkg[idx], bkg_legends_[idx], "F") if "SR" in hist_s.GetTitle(): leg.AddEntry(hist_s, 'HH #times {:1.2}'.format(sig_scale_), "L") leg.AddEntry(box, "Total unc", "F") if h1_data: leg.AddEntry(h1_data, "Data", "ep") leg.Draw() pad2.cd() pad2.SetGridy(1) ratio = None ratio_Low = 0.0 ratio_High = 4 if h1_data: ratio = TGraphAsymmErrors(h1_data) for i in range(ratio.GetN()): #bkg prediction imc = Double(hist_all.GetBinContent(i+1)) #data point var_x, var_y = Double(0.), Double(0.) if not ("SR" in h1_data.GetTitle() and (i>5 and i<9)): ratio.GetPoint(i,var_x,var_y) if var_y == 0.: ratio.SetPoint(i,var_x,-1.0) ratio.SetPointEYlow(i,-1) ratio.SetPointEYhigh(i,-1) continue ratio.SetPoint(i,var_x,var_y/imc) err_low = (var_y - (0.5*TMath.ChisquareQuantile(0.1586555,2.*var_y)))/imc err_high = ((0.5*TMath.ChisquareQuantile(1.-0.1586555,2.*(var_y+1))) - var_y)/imc ratio.SetPointEYlow(i, err_low) ratio.SetPointEYhigh(i, err_high) ratio.SetMarkerColor(1) ratio.SetMarkerSize(1) ratio.SetMarkerStyle(20) ratio.GetXaxis().SetTitle("j_{2} regressed mass [GeV]") #myC.Update() if "ratio_range" in extraoptions: ratio_Low = extraoptions["ratio_range"][0] ratio_High = extraoptions["ratio_range"][1] ratio.GetYaxis().SetTitle("data/mc") ratio.GetYaxis().SetRangeUser(ratio_Low, ratio_High) ratio.GetXaxis().SetRangeUser(50, 220) ratio.SetTitle("") ratio.Draw("same AP") pad2.Update() print(ratio.GetTitle(),ratio.GetName(),"debug") else: ratio = h1_sig[0].Clone("ratio") ratio_High = 0.0 for ibin in range(1,ratio.GetNbinsX()+1): s = hist_s.GetBinContent(ibin) b = hist_b.GetBinContent(ibin) L = 0.0 if b > 0.0: L = s/math.sqrt(b) if L > ratio_High: ratio_High = L ratio.SetBinContent(ibin, L) if ratio_High > 1.0: ratio_High = 1.0 ratio.GetYaxis().SetRangeUser(ratio_Low, ratio_High*1.2) ratio.GetYaxis().SetTitle("S/#sqrt{B}") ratio.Draw("samehist") ratio.SetLineColor(1) ratio.SetLineWidth(2) ratio.SetMarkerStyle(20) ratio.SetMarkerColor(1) ratio.SetFillColorAlpha(1, 0) ratio.GetXaxis().SetTitleOffset(0.94) ratio.GetXaxis().SetTitleSize(0.18) ratio.GetXaxis().SetLabelSize(0.12) ratio.GetXaxis().SetLabelOffset(0.013) ratio.GetYaxis().SetTitleOffset(0.40) ratio.GetYaxis().SetTitleSize(0.17) ratio.GetYaxis().SetLabelSize(0.13) ratio.GetYaxis().SetTickLength(0.01) ratio.GetYaxis().SetNdivisions(505) #if "xaxis_range" in extraoptions: # ratio.GetXaxis().SetRangeUser(float(extraoptions["xaxis_range"][0]),float(extraoptions["xaxis_range"][1])) #draw stack total unc on the ratio plot to present the background uncertainty box_ratio = r.TBox(0,0,1,1,) box_ratio.SetFillStyle(3002) box_ratio.SetLineWidth(0) box_ratio.SetFillColor(r.kBlack) for idx in range(h1_bkg[0].GetNbinsX()): if np.fabs(nS[idx])> 1e-06: box_ratio.DrawBox(h1_bkg[0].GetBinCenter(idx+1)-0.5*h1_bkg[0].GetBinWidth(idx+1), (nS[idx]-eS[idx])/nS[idx], h1_bkg[0].GetBinCenter(idx+1)+0.5*h1_bkg[0].GetBinWidth(idx+1), (nS[idx]+eS[idx])/nS[idx]) else: print("blinded Higgs peak region") if "xaxis_label" in extraoptions and extraoptions["xaxis_label"] != None: x_title = extraoptions["xaxis_label"] ratio.GetXaxis().SetTitle(x_title) ratio.GetYaxis().CenterTitle() ##########draw CMS preliminary pad1.cd() tex1 = r.TLatex(leftMargin, 0.91, "CMS") tex1.SetNDC() tex1.SetTextFont(61) tex1.SetTextSize(0.070) tex1.SetLineWidth(2) tex1.Draw() tex2 = r.TLatex(leftMargin+0.12,0.912,"Internal") tex2.SetNDC() tex2.SetTextFont(52) tex2.SetTextSize(0.055) tex2.SetLineWidth(2) tex2.Draw() lumi_value = 137 if "lumi_value" in extraoptions: lumi_value = extraoptions["lumi_value"] tex3 = r.TLatex(0.72,0.912,"%d"%lumi_value+" fb^{-1} (13 TeV)") tex3.SetNDC() tex3.SetTextFont(42) tex3.SetTextSize(0.055) tex3.SetLineWidth(2) tex3.Draw() outFile = dir_name_ if output_name_: outFile = outFile + "/" +output_name_ else: outFile = outFile + "/" + hist_name_ #print("maxY = "+str(maxY)) stack.SetMaximum(maxY*1.7) #print everything into txt file text_file = open(outFile+"_linY.txt", "w") text_file.write("bin | x ") for idx in range(len(h1_bkg)): text_file.write(" | %21s"%bkg_legends_[idx]) text_file.write(" | %21s"%("total B")) for idx in range(len(sig_legends_)): text_file.write(" | %25s"%sig_legends_[idx]) if h1_data: text_file.write(" | data | data/mc") text_file.write("\n-------------") for idx in range(24*(len(h1_bkg) + 1)+ 29*len(sig_legends_)): text_file.write("-") if h1_data: text_file.write("-------") text_file.write("\n") for ibin in range(0,h1_sig[0].GetNbinsX()+1): text_file.write("%3d"%ibin+" ") text_file.write(" | %6.3f"%h1_data.GetBinCenter(ibin)+" ") for idx in range(len(h1_bkg)): text_file.write(" | %7.3f "%h1_bkg[idx].GetBinContent(ibin)+"$\\pm$"+ " %7.3f"%h1_bkg[idx].GetBinError(ibin)) text_file.write(" | %7.3f "%hist_b.GetBinContent(ibin)+"$\\pm$"+ " %7.3f"%hist_b.GetBinError(ibin)) for idx in range(len(sig_legends_)): text_file.write(" | %9.3f "%h1_sig[idx].GetBinContent(ibin)+"$\\pm$"+ " %9.3f"%h1_sig[idx].GetBinError(ibin)) if h1_data: text_file.write(" | %d"%h1_data.GetBinContent(ibin) + " | %7.3f "%h1_data.GetBinContent(ibin) +"$\\pm$"+ " %7.3f"%h1_data.GetBinError(ibin)) text_file.write("\n\n") #print yield table for AN text_file.write("print yield table for AN\n") bkg_all = 0 bkg_all_errsq = 0 for idx in range(len(h1_bkg)): bkg_tmp = h1_bkg[idx].GetBinContent(7)+h1_bkg[idx].GetBinContent(8)+h1_bkg[idx].GetBinContent(9) bkg_errsq_tmp = h1_bkg[idx].GetBinError(7)*h1_bkg[idx].GetBinError(7)+h1_bkg[idx].GetBinError(8)*h1_bkg[idx].GetBinError(8)+h1_bkg[idx].GetBinError(9)*h1_bkg[idx].GetBinError(9) bkg_all += bkg_tmp bkg_all_errsq += bkg_errsq_tmp text_file.write("%s"%(bkg_legends_[idx])+"& %7.2f"%(bkg_tmp)+"$\\pm$"+ "%7.2f"%np.sqrt(bkg_errsq_tmp)+"\n") text_file.write("total background & %7.2f"%(bkg_all)+"$\\pm$"+ "%7.2f"%np.sqrt(bkg_all_errsq)+"\n") text_file.write("\ggHH SM ($\kapl=1$) & %7.2f"%((h1_sig[0].GetBinContent(7)+h1_sig[0].GetBinContent(8)+h1_sig[0].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.1f"%(sig_scale_*np.sqrt(h1_sig[0].GetBinError(7)*h1_sig[0].GetBinError(7)+h1_sig[0].GetBinError(8)*h1_sig[0].GetBinError(8)+h1_sig[0].GetBinError(9)*h1_sig[0].GetBinError(9)))+"\n") text_file.write("\VBFHH SM ($\kapl=1$) & %7.2f"%((h1_sig[1].GetBinContent(7)+h1_sig[1].GetBinContent(8)+h1_sig[1].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.1f"%(sig_scale_*np.sqrt(h1_sig[1].GetBinError(7)*h1_sig[1].GetBinError(7)+h1_sig[1].GetBinError(8)*h1_sig[1].GetBinError(8)+h1_sig[1].GetBinError(9)*h1_sig[1].GetBinError(9)))+"\n") text_file.write("HH bin 8 value %s"%h1_sig[0].GetBinContent(8)+"\n") text_file.write("HH bin 9 value %s"%h1_sig[0].GetBinContent(9)+"\n") text_file.write("HH bin 7 value %s"%h1_sig[0].GetBinContent(7)+"\n") text_file.write("HH bin 8 error %s"%h1_sig[0].GetBinError(8)+"\n") text_file.write("HH bin 9 error %s"%h1_sig[0].GetBinError(9)+"\n") text_file.write("HH bin 7 error %s"%h1_sig[0].GetBinError(7)+"\n") text_file.write("total & %7.2f"%(bkg_all+(h1_sig[0].GetBinContent(7)+h1_sig[0].GetBinContent(8)+h1_sig[0].GetBinContent(9)+h1_sig[1].GetBinContent(7)+h1_sig[1].GetBinContent(8)+h1_sig[1].GetBinContent(9))/sig_scale_)+"$\\pm$"+ "%7.2f"%(np.sqrt((h1_sig[0].GetBinError(7)*h1_sig[0].GetBinError(7)+h1_sig[0].GetBinError(8)*h1_sig[0].GetBinError(8)+h1_sig[0].GetBinError(9)*h1_sig[0].GetBinError(9))/(sig_scale_*sig_scale_)+(h1_sig[1].GetBinError(7)*h1_sig[1].GetBinError(7)+h1_sig[1].GetBinError(8)*h1_sig[1].GetBinError(8)+h1_sig[1].GetBinError(9)*h1_sig[1].GetBinError(9))/(sig_scale_*sig_scale_)+bkg_all_errsq))+"\n") text_file.close() os.system("cp "+outFile+"_linY.txt "+outFile+"_logY.txt") pad1.RedrawAxis() myC.SaveAs(outFile+"_linY.png") myC.SaveAs(outFile+"_linY.pdf") myC.SaveAs(outFile+"_linY.C") pad1.cd() stack.SetMaximum(maxY*100.0) stack.SetMinimum(0.5) pad1.SetLogy() pad1.RedrawAxis() myC.SaveAs(outFile+"_logY.png") myC.SaveAs(outFile+"_logY.pdf") myC.SaveAs(outFile+"_logY.C") #save histogram and ratio to root file outFile_root = r.TFile(outFile+".root", "recreate") outFile_root.cd() for idx in range(len(h1_bkg)): h1_bkg[idx].Write() for idx in range(len(sig_legends_)): h1_sig[idx].Write() if h1_data: h1_data.Write() ratio.Write() #outFile_root.Write() outFile_root.Close()
ey_lo_ratio = 0.0 else: ey_lo_ratio = y_ratio * math.hypot(ey_lo_mu / y_mu, ey_lo_ele / y_ele) ey_hi_mu = grMu.GetErrorYhigh(i) ey_hi_ele = grEle.GetErrorYhigh(i) if y_mu < 1.e-9 or y_ele < 1.e-9: ey_hi_ratio = 0.0 else: ey_hi_ratio = y_ratio * math.hypot(ey_hi_mu / y_mu, ey_hi_ele / y_ele) grRatio.SetPoint(i, x, y_ratio) grRatio.SetPointEXlow(i, ex_lo) grRatio.SetPointEXhigh(i, ex_hi) grRatio.SetPointEYlow(i, ey_lo_ratio) grRatio.SetPointEYhigh(i, ey_hi_ratio) if True: grRatio.SetMarkerStyle(20) grRatio.SetMarkerSize(1.5) grRatio.SetMarkerColor(1) grRatio.SetLineStyle(1) grRatio.SetLineColor(1) grRatio.SetLineWidth(1) grRatio.GetXaxis().SetLabelSize(0.04) grRatio.GetXaxis().SetTitleSize(0.04) grRatio.GetXaxis().SetTitleOffset(1.25) grRatio.GetYaxis().SetLabelSize(0.04)