def calcAndDrawSignificance(SignalHist, BkgrHist, xtitle, legendNames, DataName, destination, year, ylog=False, customLabels=None, extraText=None, scaleSignalToBkgr=False, DivideByLine=None): GeneralSettings() #Make sure the code works for single backgrounds if not isinstance(BkgrHist, (list, )): BkgrHist = [BkgrHist] if not isinstance(SignalHist, (list, )): SignalHist = [SignalHist] BkgrHist, legendNames = orderHist(BkgrHist, legendNames, True) #Add all backgrounds totBkgr = BkgrHist[0].Clone("TotBkgr") for h in BkgrHist[1:]: totBkgr.Add(h) #Normalize signal to background if needed if scaleSignalToBkgr: for h in SignalHist: h.scale(totBkgr.GetSumOfWeights() / h.GetSumOfWeights) #Define a canvas Canv = TCanvas("Canv" + destination, "Canv" + destination, 1500, 1000) #Set Histogram Styles for h, n in zip(BkgrHist, legendNames): h.SetFillColor(TColor.GetColor(GetStackColorTauPOGbyName(n))) h.SetLineColor(TColor.GetColor(GetStackColorTauPOGbyName(n))) for i, h in enumerate(SignalHist): h.SetMarkerColor(TColor.GetColor(GetLineColor(i))) h.SetLineColor(TColor.GetColor(GetLineColor(i))) h.SetMarkerStyle(GetMarker(i)) list_of_significance_hists = [] for i, sh in enumerate(SignalHist): #Calculate significance total = totBkgr.Clone("Total") total.Add(sh) sqrt_total = total.Clone('Sqrt_Total') for xbin in xrange( 1, total.GetSize() - 1 ): #GetSize returns nbins + 2 (for overflow and underflow bin) sqrt_x = np.sqrt(total.GetBinContent(xbin)) sqrt_total.SetBinContent(xbin, sqrt_x) sqrt_total.SetBinError(xbin, 0.5 * total.GetBinError(xbin) / sqrt_x) significance = sh.Clone('Signal' + str(i)) significance.Divide(sqrt_total) list_of_significance_hists.append(significance) #First pad plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98) plotpad.SetBottomMargin(0.025) plotpad.Draw() plotpad.cd() #Create Stack (Change with most logical ordering) hs = THStack("hs", "hs") for h in BkgrHist: hs.Add(h) hs.Draw( "EHist" ) #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4 title = " ; ; Events" hs.SetTitle(title) # hs.GetHistogram().GetXaxis().SetTickLength(0) hs.GetHistogram().GetXaxis().SetLabelOffset(9999999) #hs.GetHistogram().SetMaximum(1) #Set range overallMin = GetOverallMinimum(BkgrHist + SignalHist, True) overallMax = GetOverallMaximum([totBkgr] + SignalHist) if ylog: if overallMin == 0.: overallMin = 0.1 ymin = 0.3 * overallMin ymax = 30 * overallMax plotpad.SetLogy() else: ymin = 0.7 * overallMin ymax = 1.3 * overallMax hs.SetMinimum(ymin) hs.SetMaximum(ymax) for h in SignalHist: h.Draw("EPSame") #Create Legend legend = TLegend(0.7, .7, .9, .9) for h, n in zip(BkgrHist, legendNames): legend.AddEntry(h, n) for h, n in zip(SignalHist, DataName): legend.AddEntry(h, n) legend.SetFillStyle(0) legend.SetBorderSize(0) legend.Draw() #Draw lines if needed if DivideByLine is not None: tdrStyle_Left_Margin = 0.16 tdrStyle_Right_Margin = 0.02 plot_size_hor = 1 - tdrStyle_Left_Margin - tdrStyle_Right_Margin #Option one, user provides the number of divisions and we divide equally if isinstance(DivideByLine[0], int): x_pos = np.linspace(totBkgr.GetXaxis().GetXmin(), totBkgr.GetXaxis().GetXmax(), DivideByLine[0] + 1) #Option two, user provides the specific boundaries if isinstance(DivideByLine[0], (list, )): x_pos = DivideByLine[0] #Draw the lines lines = [] for i, x in enumerate(x_pos[1:-1]): lines.append(TLine(x, ymin, x, ymax)) lines[i].SetLineColor(ROOT.kRed) lines[i].SetLineStyle(10) for line in lines: line.Draw('same') #Add extra text for i, name in enumerate(DivideByLine[1]): x = ((x_pos[i + 1] + x_pos[i]) / (2 * (x_pos[-1] - x_pos[0]) / plot_size_hor)) + tdrStyle_Left_Margin extraText.append(extraTextFormat(name, x, 0.1, None, 22)) #Draw extra text if needed if extraText is not None: DrawExtraText(plotpad, extraText) #Return to canvas Canv.cd() #Second pad ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3) ratiopad.SetTopMargin(0.05) ratiopad.SetBottomMargin(0.25) ratiopad.Draw() ratiopad.cd() #print list_of_significance_hists[0].GetMaximum(), list_of_significance_hists[1].GetMaximum(), list_of_significance_hists[2].GetMaximum() overallMin = GetOverallMinimum(list_of_significance_hists) overallMax = GetOverallMaximum(list_of_significance_hists) significance = list_of_significance_hists[0] #Prepare lines before changing maximum lines_bottom = [] for i, sig in enumerate(list_of_significance_hists): lines_bottom.append( TLine(sig.GetXaxis().GetXmin(), sig.GetMaximum(), sig.GetXaxis().GetXmax(), sig.GetMaximum())) lines_bottom[i].SetLineColor(TColor.GetColor(GetLineColor(i))) lines_bottom[i].SetLineStyle(3) #Set Style for bottom plot significance.SetTitle(";" + xtitle + "; S/#sqrt{S+B}") significance.GetXaxis().SetTitleSize(.12) significance.GetYaxis().SetTitleSize(.12) significance.GetYaxis().SetTitleOffset(.6) significance.GetXaxis().SetLabelSize(.12) significance.GetYaxis().SetLabelSize(.12) significance.SetMinimum(0.) significance.SetMaximum(1.3 * overallMax) significance.Draw("EP") for sig in list_of_significance_hists[1:]: sig.Draw('EPSame') for line in lines_bottom: line.Draw("same") #Set custom x labels xaxis = significance.GetXaxis() if customLabels != None: number_of_bins = significance.GetNbinsX() if number_of_bins != len(customLabels): if DivideByLine is not None: for i in range(number_of_bins): xaxis.SetBinLabel( i + 1, customLabels[i % len(customLabels)] ) #Only works when DivideByLine[0] is an integer else: print 'Please provide ' + str( number_of_bins) + ' labels instead of ' + str( len(customLabels)) return else: for i, label in zip(range(number_of_bins), customLabels): xaxis.SetBinLabel(i + 1, label) #Throw CMs lumi at it cl.CMS_lumi(Canv, 4, 11, year, 'Simulation Preliminary', True) #Save everything savePlots(Canv, destination) ROOT.SetOwnership( Canv, False ) #https://root-forum.cern.ch/t/tlatex-crashing-in-pyroot-after-many-uses/21638/4 return
def plotDataVSMC(DataHist, MCHist, xtitle, legendNames, DataName, destination, year, ytitle_bottom='Data/MC', ylog=False): GeneralSettings() Canv = TCanvas("Canv" + destination, "Canv" + destination, 1000, 1000) #Set Histogram Styles for i, h in enumerate(MCHist): h.SetFillColor( TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i]))) h.SetLineColor( TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i]))) DataHist.SetMarkerColor(ROOT.kBlack) DataHist.SetLineColor(ROOT.kBlack) DataHist.SetMarkerStyle(20) #Add all MC samples to use in ratios totBkgr = MCHist[0].Clone("totBkgr") for h in MCHist[1:]: totBkgr.Add(h) DataOverMC = DataHist.Clone("DataOverMC") DataOverMC.Divide(totBkgr) #Errors predStatError = totBkgr.Clone("PredictedStatError") predSystError = totBkgr.Clone("PredictedSystError") predTotError = totBkgr.Clone("PredictedTotalError") for b in xrange(predSystError.GetNbinsX() + 1): predSystError.SetBinError(b, 0.3 * totBkgr.GetBinContent(b)) syst = predSystError.GetBinError(b) stat = predStatError.GetBinError(b) predTotError.SetBinError(b, np.sqrt(stat * stat + syst * syst)) #predTotError.SetFillStyle(3013) #predTotError.SetFillColor(ROOT.kGray+2) #predTotError.SetMarkerStyle(0) #predTotError.Draw("E2 Same") #First pad plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98) plotpad.SetBottomMargin(0.025) plotpad.Draw() plotpad.cd() #Create Stack (Change with most logical ordering) hs = THStack("hs", "hs") for h in MCHist: hs.Add(h) hs.Draw( "EHist" ) #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4 title = " ; ; Events / " + str(MCHist[0].GetBinWidth(1)) + " GeV" hs.SetTitle(title) # hs.GetHistogram().GetXaxis().SetTickLength(0) hs.GetHistogram().GetXaxis().SetLabelOffset(9999999) hs.GetHistogram().SetMaximum(1) #Set range overallMin = GetOverallMinimum(MCHist + [DataHist]) overallMax = GetOverallMaximum([totBkgr] + [DataHist]) if ylog: plotpad.SetLogy() hs.SetMinimum(0.3 * overallMin) hs.SetMaximum(10 * overallMax) else: hs.SetMinimum(0.5 * overallMin) hs.SetMaximum(1.7 * overallMax) DataHist.Draw("EPSame") predTotError.SetFillStyle(3013) predTotError.SetFillColor(ROOT.kGray + 2) predTotError.SetMarkerStyle(0) predTotError.Draw("E2 Same") #Create Legend legend = TLegend(0.7, .7, .9, .9) for h, n in zip(MCHist, legendNames): legend.AddEntry(h, n) legend.AddEntry(DataHist, DataName) legend.SetFillStyle(0) legend.SetBorderSize(0) legend.Draw() #Return to canvas Canv.cd() #Second pad ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3) ratiopad.SetTopMargin(0.05) ratiopad.SetBottomMargin(0.25) ratiopad.Draw() ratiopad.cd() #Errors StatErrorRatio = predStatError.Clone("StatErrorRatio") StatErrorRatio.SetFillStyle(1001) StatErrorRatio.SetFillColor(TColor.GetColor('#6EF9F5')) TotErrorRatio = predTotError.Clone("SystErrorRatio") TotErrorRatio.SetFillColor(TColor.GetColor('#63E2C6')) TotErrorRatio.SetFillStyle(1001) for b in xrange(StatErrorRatio.GetNbinsX() + 1): if (StatErrorRatio.GetBinContent(b) != 0): StatErrorRatio.SetBinError( b, StatErrorRatio.GetBinError(b) / StatErrorRatio.GetBinContent(b)) TotErrorRatio.SetBinError( b, TotErrorRatio.GetBinError(b) / TotErrorRatio.GetBinContent(b)) StatErrorRatio.SetBinContent(b, 1.) TotErrorRatio.SetBinContent(b, 1.) else: StatErrorRatio.SetBinContent(b, 0) TotErrorRatio.SetBinContent(b, 0) #Set Style for bottom plot DataOverMC.SetTitle(";" + xtitle + "; " + ytitle_bottom) DataOverMC.GetXaxis().SetTitleSize(.12) DataOverMC.GetYaxis().SetTitleSize(.12) DataOverMC.GetYaxis().SetTitleOffset(.6) DataOverMC.GetXaxis().SetLabelSize(.12) DataOverMC.GetYaxis().SetLabelSize(.12) DataOverMC.SetMinimum(0.3) DataOverMC.SetMaximum(1.7) DataOverMC.Draw("EP") TotErrorRatio.Draw("E2 same") StatErrorRatio.Draw("E2 same") DataOverMC.Draw("EPsame") #Draw a guide for the eye line = TLine(DataOverMC.GetXaxis().GetXmin(), 1, DataOverMC.GetXaxis().GetXmax(), 1) line.SetLineColor(ROOT.kRed) line.SetLineWidth(1) line.SetLineStyle(1) line.Draw("Same") #Create Legend legend_bottom = TLegend(0.2, .8, .9, .9) legend_bottom.SetNColumns(3) legend_bottom.AddEntry(DataOverMC, "Obs./Pred.") legend_bottom.AddEntry(StatErrorRatio, "Stat. Unc.") legend_bottom.AddEntry(TotErrorRatio, "Tot. Unc.") legend_bottom.SetFillStyle(0) legend_bottom.SetBorderSize(0) legend_bottom.Draw() #Throw CMs lumi at it cl.CMS_lumi(Canv, 4, 11, year, 'Preliminary', True) print 'save' #Save everything savePlots(Canv, destination) print 'saved'
def plotRatio(name, h1, v_hist, hs, log): c = Canvas('c') h_sum = TH1F('h_sum','sum',h1.GetNbinsX(), h1.GetXaxis().GetXmin(), h1.GetXaxis().GetXmax()) for h in v_hist: h_sum.Add(h) pad1 = TPad('pad1', 'pad1', 0.0, 0.3, 1., 1.) pad1.SetBottomMargin(0.005) pad1.SetTicks(1,1) pad1.Draw() c.cd() pad2 = TPad('pad2', 'pad2', 0., 0.05, 1., 0.28) pad2.SetTopMargin(0.005) pad2.SetBottomMargin(0.3) pad2.SetTicks(1,1) pad2.Draw() pad1.cd() if log: pad1.SetLogy() stack = THStack('norm_stack','') h_mc_err = 0 for h in v_hist: stack.Add(h) if h_mc_err == 0: h_mc_err = h.Clone() else: h_mc_err.Add(h) stack.Draw('HIST') h_mc_err.Draw("e2 same") h_mc_err.SetMarkerSize(0) h_mc_err.SetFillColor(1) h_mc_err.SetFillStyle(3004) h_data = asym_error_bars(h1) h_data.SetLineColor(ROOT.kBlack) h_data.SetFillColor(ROOT.kBlack) h_data.SetLineWidth(2) h_data.Draw('p e2 same') hs.Draw('HIST same') ymax = h1.GetMaximum()*pow(10,1.0) if log else h1.GetMaximum()*1.5 stack.SetMaximum(ymax) if log: stack.SetMinimum(1) #stack.GetHistogram().GetYaxis().SetTitleFont(43) stack.GetHistogram().GetYaxis().SetTitleOffset(1.0) stack.GetHistogram().GetYaxis().SetTitleSize(0.05) stack.GetHistogram().GetYaxis().SetTitle('Events') pLabel, sLabel, lLabel = prelimLabel('left',log,h1.GetMaximum()), selectionLabel(lab,True,log,h1.GetMaximum()), lumiLabel(True,years) pLabel.Draw(), sLabel.Draw(), lLabel.Draw() legend = makeLegend(h1,v_hist,hs) legend.Draw() pad2.cd() h_ratio = h1.Clone('h_ratio') h_ratio.Sumw2() h_ratio.Divide(h_sum) h_ratio.SetMinimum(-0.499) h_ratio.SetMaximum(2.499) h_ratio.SetLineColor(ROOT.kBlack) h_ratio.SetMarkerStyle(20) h_ratio.SetMarkerColor(ROOT.kBlack) h_ratio.SetMarkerSize(0.7) h_ratio.Draw('p same') denom_err, denom_err2 = h_mc_err.Clone(), h_mc_err.Clone() denom_err2.Sumw2(False) denom_err.Divide(denom_err2) denom_err.Draw("e2same") denom_err.SetFillColor(1) denom_err.SetFillStyle(3004) l1 = TLine(h_ratio.GetXaxis().GetXmin(), 1, h_ratio.GetXaxis().GetXmax(), 1) l2 = TLine(h_ratio.GetXaxis().GetXmin(), 1.5, h_ratio.GetXaxis().GetXmax(), 1.5) l3 = TLine(h_ratio.GetXaxis().GetXmin(), 0.5, h_ratio.GetXaxis().GetXmax(), 0.5) l4 = TLine(h_ratio.GetXaxis().GetXmin(), 0., h_ratio.GetXaxis().GetXmax(), 0.) l5 = TLine(h_ratio.GetXaxis().GetXmin(), 2, h_ratio.GetXaxis().GetXmax(), 2.) l2.SetLineStyle(3), l3.SetLineStyle(3), l4.SetLineStyle(3), l5.SetLineStyle(3) l1.Draw(), l2.Draw(), l3.Draw(), l4.Draw(), l5.Draw() Prettify( h_ratio ) #ax = h_ratio.GetXaxis(); #ax.SetNdivisions(506); if len(years) == 1: c.SaveAs('plots/%s/%s_%s.%s' % (years[0],name,selection,extension)) else: c.SaveAs('plots/combined/%s_%s_%s.%s' % (name,selection,s_years,extension))
class BinnedAndIncl(plotterBase): def __init__(self, cvs_params): leg_size = cvs_params["leg_size"] logy = cvs_params["logy"] grid = cvs_params["grid"] super().__init__(cvs_type="ratio", leg_size=leg_size, logy=logy, grid=grid) def get_hists(self, hist_incl, hists_binned, hist_params): rebin = hist_params["rebin"] self.hist_incl = None self.hists_binned = {} self.stack = THStack("stack", "") self.syst = None self.ratio = None self.ratio_syst = None # Store histograms print("INFO: Storing histograms...") print("INFO: histograms automatically normalized to L = 150 fb^-1") self.hist_incl = self.__rebin(hist_incl, hist_params) for name, hist in hists_binned.items(): self.hists_binned[name] = self.__rebin(hist, hist_params) self.__decorate_hists(hist_params) self.__make_stack_and_syst() self.__make_ratio(hist_params) def combine(self, info_params): info = info_params["info"] cmsText = info_params["cms_text"] extraText = info_params["extra_text"] super().pad_up().cd() self.hist_incl.Draw("p&hist") self.stack.Draw("hist & pfc & same") self.syst.Draw("e2 & f & same") self.hist_incl.Draw("p&hist&same") self.hist_incl.Draw("e1 & same") super().legend().Draw() super().info().DrawLatexNDC(0.63, 0.91, info) super().logo().DrawLatexNDC(0.15, 0.83, cmsText) super().extra_logo().DrawLatexNDC(0.15, 0.78, extraText) super().pad_down().cd() self.ratio.Draw("p & hist") self.ratio_syst.Draw("e2&f&same") super().cvs().cd() super().pad_up().Draw() super().pad_down().Draw() def __rebin(self, hist, hist_params): rebin = hist_params["rebin"] if rebin == -1: pass else: hist.Rebin(rebin) if "x_range" in hist_params.keys(): x_range = hist_params["x_range"] hist.GetXaxis().SetRangeUser(x_range[0], x_range[1]) return hist def __decorate_hists(self, hist_params): y_title = hist_params["y_title"] # y axis scale is just the Maximum of inclusive sample print("INFO: y axis range set to be maximum of inclusive plot...") y_range = self.hist_incl.GetMaximum() # decorate self.hist_incl self.hist_incl.SetStats(0) self.hist_incl.SetMarkerStyle(8) self.hist_incl.SetMarkerSize(0.5) self.hist_incl.SetMarkerColor(1) # X axis self.hist_incl.GetXaxis().SetLabelSize(0) # Y axis self.hist_incl.GetYaxis().SetTitle(y_title) self.hist_incl.GetYaxis().SetRangeUser(0., y_range*1.2) if self.logy: self.hist_incl.GetYaxis().SetRangeUser(1., y_range*100.) for name, hist in self.hists_binned.items(): hist.GetXaxis().SetLabelSize(0) # add to legend super().legend().AddEntry(self.hist_incl, "Incl", "lep") def __make_stack_and_syst(self): print("WARNING: Make sure that histograms are properly scaled") for name, hist in self.hists_binned.items(): hist.GetXaxis().SetLabelSize(0) self.stack.Add(hist) super().legend().AddEntry(hist, name, "f") if self.syst == None: self.syst = hist.Clone("syst") else: self.syst.Add(hist) self.stack.Draw() self.stack.GetHistogram().GetXaxis().SetLabelSize(0) self.syst.SetStats(0) self.syst.SetFillColorAlpha(12, 0.6) self.syst.SetFillStyle(3144) self.syst.GetXaxis().SetLabelSize(0) super().legend().AddEntry(self.syst, "stat err", "f") def __make_ratio(self, hist_params): error_range = hist_params["error_range"] x_title = hist_params["x_title"] self.ratio = self.hist_incl.Clone("ratio") self.ratio.Divide(self.syst) self.ratio_syst = self.ratio.Clone("ratio_syst") self.ratio.SetStats(0) self.ratio.SetTitle("") # y axis self.ratio.GetYaxis().SetRangeUser(error_range[0], error_range[1]) self.ratio.GetYaxis().SetTitle("Incl / binned") self.ratio.GetYaxis().SetTitleSize(0.08) self.ratio.GetYaxis().SetTitleOffset(0.5) self.ratio.GetYaxis().SetLabelSize(0.08) # x axis self.ratio.GetXaxis().SetTitle(x_title) self.ratio.GetXaxis().SetTitleSize(0.1) self.ratio.GetXaxis().SetTitleOffset(0.8) self.ratio.GetXaxis().SetLabelSize(0.08) self.ratio_syst.SetStats(0) self.ratio_syst.SetFillColorAlpha(12, 0.6) self.ratio_syst.SetFillStyle(3144)
def drawHisto(histlist,histoD,xTitle,yTitle,outName,uncHists=""): legend = TLegend(0.35, 0.72, 0.85, 0.92,"") #,"brNDC" legend.SetFillStyle(0) legend.SetTextSize(0.045) legend.SetNColumns(2) myStack = THStack("myStack","") for hist in histlist: myStack.Add(hist,"hist") histoErr = histlist[0].Clone() for iHist in range(1,len(histlist)): histoErr.Add(histlist[iHist]) MCCount = myStack.GetStack().Last().Integral() DataCount = histoD.Integral() MCNormFactor = DataCount/MCCount # myStack.Delete() myStack = THStack("myStack","") for hist in histlist: hist.Scale(MCNormFactor) myStack.Add(hist,"hist") histoErr.Scale(MCNormFactor) if uncHists!="": MCMean = myStack.GetStack().Last().Clone() MCErr = MCMean.Clone() MCErr.Reset() for ibin in range(1,MCMean.GetNbinsX()+1): thisbinunc = 0 for ihist in uncHists: thisbinunc += ihist.GetBinContent(ibin)**2 #sum assuming correlated sfunc = thisbinunc**0.5*MCNormFactor if args.nostat: MCMean.SetBinError(ibin, sfunc) MCErr.SetBinContent(ibin, sfunc) else: MCMean.SetBinError(ibin, math.sqrt(sfunc**2 + histoErr.GetBinError(ibin)**2)) MCErr.SetBinContent(ibin, math.sqrt(sfunc**2 + histoErr.GetBinError(ibin)**2)) c = TCanvas("main","main",1200,1200) c.SetCanvasSize(1200,1200) upperCanvas = TPad("up","up",0,0.24,1,1) upperCanvas.SetBottomMargin(0.03) upperCanvas.SetLeftMargin(0.12) upperCanvas.SetTopMargin(0.06) # upperCanvas.SetLogy(isLog) upperCanvas.Draw() upperCanvas.cd() myStack.Draw() myStack.GetYaxis().SetTitle(yTitle) myStack.GetHistogram().GetZaxis().SetTitle() myStack.GetYaxis().SetLabelSize(0.048) myStack.GetYaxis().SetTitleSize(0.07) myStack.GetYaxis().SetTitleOffset(0.78) myStack.GetYaxis().SetTitleFont(42) legend.Draw("same") if uncHists!="": MCMean.Draw("e2 same") MCMean.SetFillColor(kGreen) MCMean.SetLineColor(kGreen) MCMean.SetMarkerSize(0) MCMean.SetFillStyle(3013) if not args.nostat: histoErr.Draw("e2 same") # histoErr.Sumw2() histoErr.SetFillColor(kGray+3) histoErr.SetLineColor(kGray+3) histoErr.SetMarkerSize(0) histoErr.SetFillStyle(3013) histoMC = myStack.GetStack().Last() histoBkg= myStack.GetStack().Before(histoMC) print "Total MC:", histoMC.Integral(), ", Data:",histoD.Integral() histoD.Draw("same p e") legend.AddEntry(histoD,"Data","PE") for hist in histlist: legend.AddEntry(hist,hist.GetName().replace('uds','udsg').replace('b','bottom').replace('c','charm'),'f') legend.AddEntry(histoErr,"MC Stat. Unc.",'f') if uncHists!="": legend.AddEntry(MCMean,"SF Unc.",'f') maxY = histoD.GetMaximum() #if myStack.GetMinimum() >= 0: myStack.SetMinimum(1e-3) myStack.SetMaximum(maxY*1.35) c.cd() lowerCanvas = TPad("down","down",0,0,1,0.26) lowerCanvas.Draw() lowerCanvas.cd() lowerCanvas.SetTicky(1) lowerCanvas.SetLeftMargin(0.1) lowerCanvas.SetRightMargin(0.1) lowerCanvas.SetTopMargin(0.0) lowerCanvas.SetBottomMargin(0.4) lowerCanvas.SetLeftMargin(0.12) lowerCanvas.SetFrameFillStyle(0) lowerCanvas.SetFrameBorderMode(0) lowerCanvas.SetGridy() histoRatio = histoD.Clone() histoRatio.Divide(histoMC) for ib in range(1,histoRatio.GetNbinsX()+1): if histoD.GetBinContent(ib) != 0: histoRatio.SetBinError(ib, histoD.GetBinError(ib)/histoD.GetBinContent(ib)*histoRatio.GetBinContent(ib)) else: histoRatio.SetBinError(ib,0.) histoRatio.GetYaxis().SetTitle("Data/MC") histoRatio.GetYaxis().SetTitleSize(0.15) histoRatio.GetYaxis().SetTitleOffset(0.38) histoRatio.GetYaxis().SetTitleFont(42) histoRatio.GetYaxis().SetLabelSize(0.14) histoRatio.GetYaxis().CenterTitle() histoRatio.GetYaxis().SetLabelFont(42) histoRatio.GetYaxis().SetNdivisions(5) histoRatio.GetXaxis().SetTitle(xTitle) histoRatio.GetXaxis().SetLabelSize(0.14) histoRatio.GetXaxis().SetTitleSize(0.19) histoRatio.GetXaxis().SetTitleOffset(0.88) histoRatio.GetXaxis().SetTitleFont(42) histoRatio.GetXaxis().SetTickLength(0.07) histoRatio.GetXaxis().SetLabelFont(42) histoRatio.SetTitle("") histoRatio.Draw("P e") histoRatio.SetMaximum(1.49) histoRatio.SetMinimum(0.51) if uncHists!="": RatioErr = MCErr.Clone() RatioErr.Divide(histoMC) RatioErrVals = RatioErr.Clone() for ibin in range(1,RatioErr.GetNbinsX()+1): RatioErrVals.SetBinContent(ibin,1.) RatioErrVals.SetBinError(ibin,RatioErr.GetBinContent(ibin)) RatioErrVals.Draw("e2 same") RatioErrVals.SetFillColor(kGreen) RatioErrVals.SetLineColor(kGreen) RatioErrVals.SetMarkerSize(0) RatioErrVals.SetFillStyle(3013) if not args.nostat: RatioStatUnc = histoMC.Clone() for ibin in range(1,RatioStatUnc.GetNbinsX()+1): RatioStatUnc.SetBinContent(ibin,1) if histoMC.GetBinContent(ibin) != 0: RatioStatUnc.SetBinError(ibin,histoMC.GetBinError(ibin)/histoMC.GetBinContent(ibin)) else: RatioStatUnc.SetBinError(ibin,0) RatioStatUnc.Draw("e2 same") RatioStatUnc.SetFillColor(kGray+3) RatioStatUnc.SetLineColor(kGray+3) RatioStatUnc.SetMarkerSize(0) RatioStatUnc.SetFillStyle(3013) histoRatio.Draw("P e same") # To bring on top hLine = TLine(-0.2,1,1,1) hLine.SetLineColor(kRed) hLine.Draw() # if drawDataMCRatioLine: # MCCount = histoMC.Integral() # if MCCount > 0.: # DataCount = histoD.Integral() # MCNormFactor = DataCount/MCCount # hLine2 = TLine(start,MCNormFactor,end,MCNormFactor) # hLine2.SetLineColor(kBlue) # hLine2.Draw() # ---------------------------------------------------------- # ======================== LaTeX ========================== texTL = TLatex() texTL.SetTextSize(0.07) texTL.SetTextAlign(13) texTR = TLatex() texTR.SetTextSize(0.05) texTR.SetTextAlign(31) # if dataset=="" or noRatio: # texTL.DrawLatexNDC(0.13,0.87, "CMS #it{#bf{Preliminary}}") # texTR.DrawLatexNDC(0.89,0.91, "#bf{"+str(lumi/1000.)+" fb^{-1} (13 TeV)}") # else: upperCanvas.cd() texTL.DrawLatexNDC(0.16,0.92, "CMS") # #it{#bf{Preliminary}}") if args.prelim: texTL2 = TLatex() texTL2.SetTextSize(0.05) texTL2.SetTextAlign(13) suff = "#it{#bf{Preliminary}}" texTL2.DrawLatexNDC(0.16,0.85, suff) texTR.DrawLatexNDC(0.89,0.95, "#bf{"+str(lumi/1000.)+" fb^{-1} (13 TeV)}") # ---------------------------------------------------------- c.SaveAs(outName+".pdf") c.SaveAs(outName+".png")
def plotDataVSMC(DataHist, MCHist, xtitle, legendNames, DataName, destination, ytitle_bottom='Data/MC'): GeneralSettings() Canv = TCanvas("Canv" + destination, "Canv" + destination, 1000, 1000) #Set Histogram Styles for i, h in enumerate(MCHist): h.SetFillColor( TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i]))) h.SetLineColor( TColor.GetColor(GetStackColorTauPOGbyName(legendNames[i]))) DataHist.SetMarkerColor(ROOT.kBlack) DataHist.SetLineColor(ROOT.kBlack) DataHist.SetMarkerStyle(20) #Add all MC samples to use in ratios totBkgr = MCHist[0].Clone("totBkgr") for h in MCHist[1:]: totBkgr.Add(h) DataOverMC = DataHist.Clone("DataOverMC") DataOverMC.Divide(totBkgr) #First pad plotpad = TPad("plotpad", "plotpad", 0, .3, 1, 0.98) plotpad.SetBottomMargin(0.025) plotpad.Draw() plotpad.cd() #Create Stack (Change with most logical ordering) hs = THStack("hs", "hs") for h in MCHist: hs.Add(h) hs.Draw( "EHist" ) #Draw before using GetHistogram, see https://root-forum.cern.ch/t/thstack-gethistogram-null-pointer-error/12892/4 title = " ; ; Events / " + str(MCHist[0].GetBinWidth(1)) + " GeV" hs.SetTitle(title) # hs.GetHistogram().GetXaxis().SetTickLength(0) hs.GetHistogram().GetXaxis().SetLabelOffset(9999999) hs.GetHistogram().SetMaximum(1) #Set range overallMin = GetOverallMinimum(MCHist + [DataHist]) overallMax = GetOverallMaximum([totBkgr] + [DataHist]) hs.SetMinimum(0.5 * overallMin) hs.SetMaximum(1.2 * overallMax) DataHist.Draw("EPSame") #Create Legend legend = TLegend(0.7, .7, .9, .9) for h, n in zip(MCHist, legendNames): legend.AddEntry(h, n) legend.AddEntry(DataHist, DataName) legend.SetFillStyle(0) legend.SetBorderSize(0) legend.Draw() #Return to canvas Canv.cd() #Second pad ratiopad = TPad("ratiopad", "ratiopad", 0, 0.05, 1, .3) ratiopad.SetTopMargin(0.05) ratiopad.SetBottomMargin(0.25) ratiopad.Draw() ratiopad.cd() #Set Style for bottom plot DataOverMC.SetTitle(";" + xtitle + "; " + ytitle_bottom) DataOverMC.GetXaxis().SetTitleSize(.12) DataOverMC.GetYaxis().SetTitleSize(.12) DataOverMC.GetYaxis().SetTitleOffset(.6) DataOverMC.GetXaxis().SetLabelSize(.12) DataOverMC.GetYaxis().SetLabelSize(.12) DataOverMC.SetMinimum(0.6) DataOverMC.SetMaximum(1.4) DataOverMC.Draw("EP") #Draw a guide for the eye line = TLine(DataOverMC.GetXaxis().GetXmin(), 1, DataOverMC.GetXaxis().GetXmax(), 1) line.SetLineColor(ROOT.kRed) line.SetLineWidth(1) line.SetLineStyle(1) line.Draw("Same") #Throw CMs lumi at it cl.CMS_lumi(Canv, 4, 11, 'Preliminary', True) print 'save' #Save everything savePlots(Canv, destination) print 'saved'