def draw(pad, hists, label=('','')) : pad.Draw() pad.cd() h_data = hists[dataSample()] stack = r.THStack('stack_'+h_data.GetName(), '') leg = topRightLegend(pad, 0.275, 0.475, shift=-0.025) leg.SetBorderSize(0) leg.AddEntry(h_data, dataSample(), 'P') for s in mcSamples() : h = hists[s] h.SetMarkerSize(0) h.SetFillColor(colors[s]) h.SetLineColor(h.GetFillColor()) h.SetDrawOption('bar') stack.Add(h) for s in mcSamples()[::-1] : leg.AddEntry(hists[s], s, 'F') # stack goes b-t, legend goes t-b h_data.SetMarkerStyle(r.kFullDotLarge) stack.Draw('hist') h_data.Draw('p same') leg.Draw('same') tex = r.TLatex() tex.SetNDC(True) label = "#splitline{%s}{%s}"%(label[0], label[1]) if len(label)==2 else label tex.DrawLatex(0.25, 0.95, label) pad.Update() # force stack to create padMaster padMaster = stack.GetHistogram() pMin, pMax = getMinMax([padMaster, h_data]) stack.SetMaximum(pMax) pad._graphical_objects = [stack, h_data, leg, tex] + [h for h in stack.GetStack()] pad.Update()
def plotStackedHistos(histos={}, datakey=None, stackkeys=[], outputDir='', region='', colors={}, verbose=False): "input: a dictionary of histos[group]" mkdirIfNeeded(outputDir) bkg_histos = dict([(k, h) for k, h in histos.iteritems() if k in stackkeys]) tot_bkg = summedHisto(bkg_histos.values(), label='') err_band = None # tmp disable # err_band = buildErrBandGraph(tot_bkg, computeStatErr2(tot_bkg)) empty_bkg = tot_bkg.Integral() == 0 if empty_bkg: if verbose: print "empty backgrounds, skip %s" % tot_bkg.GetName() return histoname = tot_bkg.GetName() can = r.TCanvas('c_' + histoname, histoname, 800, 600) can.cd() pm = tot_bkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_' + tot_bkg.GetName(), '') can.Update() r.SetOwnership(stack, False) for s, h in bkg_histos.iteritems(): h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') # err_band.Draw('E2 same') data = histos[datakey] if datakey and datakey in histos else None if data and data.GetEntries(): data.SetMarkerStyle(r.kFullDotLarge) data.Draw('p same') if verbose: print "data : nEntries {:.1f} totWeight {:.1f} ".format( data.GetEntries(), data.Integral()) yMin, yMax = getMinMax([h for h in [tot_bkg, data, err_band] if h]) # pm.SetMinimum(0.5) pm.SetMaximum(1.1 * yMax) can.Update() # can.SetLogy() topRightLabel(can, "#splitline{%s}{%s}" % (histoname, region), xpos=0.125, align=13) drawLegendWithDictKeys(can, dictSum(bkg_histos, {'stat err': err_band}), opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()] + [data] can.Update() if verbose: print os.path.join(outputDir, histoname + '.png') can.SaveAs(os.path.join(outputDir, histoname + '.png'))
def plot1dEfficiencies(effs={}, canvasName='', outputDir='./', frameTitle='title;p_{T} [GeV]; efficiency', zoomIn=False) : can = r.TCanvas(canvasName, '', 800, 600) can.cd() padMaster = None colors, markers = SampleUtils.colors, SampleUtils.markers for s,h in effs.iteritems() : h.SetLineColor(colors[s] if s in colors else r.kBlack) h.SetMarkerColor(h.GetLineColor()) h.SetMarkerStyle(markers[s] if s in markers else r.kFullCircle) drawOpt = 'ep same' if padMaster else 'ep' h.Draw(drawOpt) if not padMaster : padMaster = h minY, maxY = getMinMax(effs.values()) if zoomIn else (0.0, 1.0) padMaster.GetYaxis().SetRangeUser(min([0.0, minY]), 1.1*maxY) padMaster.SetMinimum(0.0) padMaster.SetMaximum(1.1*maxY) padMaster.SetMaximum(0.25 if (maxY < 0.25 and zoomIn) else 1.1) padMaster.SetTitle(frameTitle) padMaster.SetStats(False) drawLegendWithDictKeys(can, effs) can.Update() for ext in ['png','eps'] : outFilename = outputDir+'/'+canvasName+'.'+ext rmIfExists(outFilename) can.SaveAs(outFilename)
def plotPerSourceEff(histosPerVar={}, outputDir='', lepton='', region='', sample='', verbose=False, zoomIn=True): "plot efficiency for each source (and 'anysource') as a function of each var; expect histos[var][source][loose,tight]" variables = histosPerVar.keys() sources = [s for s in first(histosPerVar).keys() if s!='real'] # only fake eff really need a scale factor colors = colorsLineSources mkdirIfNeeded(outputDir) for var in filter(lambda x : x in ['pt1', 'eta1'], histosPerVar.keys()): histosPerSource = dict((s, histosPerVar[var][s]) for s in sources) canvasBasename = region+'_efficiency_'+lepton+'_'+var+("_%s"%sample if sample else '') missingSources = [s for s, h in histosPerSource.iteritems() if not h['loose'] or not h['tight']] if missingSources: if verbose : print "skip %s, missing histos for %s"%(var, str(missingSources)) continue anySourceLoose = summedHisto([h['loose'] for h in histosPerSource.values()]) anySourceTight = summedHisto([h['tight'] for h in histosPerSource.values()]) anySourceLoose.SetName(histoNamePerSource(var, 'any', 'loose', region)) anySourceTight.SetName(histoNamePerSource(var, 'any', 'tight', region)) histosPerSource['any'] = { 'loose' : anySourceLoose, 'tight' : anySourceTight } emptyBkg = anySourceLoose.Integral()==0 or anySourceTight.Integral()==0 if emptyBkg: if verbose : print "empty backgrounds, skip %s"%canvasBasename continue def computeEfficiencies(histosPerSource={}) : sources = histosPerSource.keys() num = dict((s, histosPerSource[s]['tight']) for s in sources) den = dict((s, histosPerSource[s]['loose']) for s in sources) eff = dict((s, h.Clone(h.GetName().replace('tight', 'tight_over_loose'))) for s, h in num.iteritems()) [eff[s].Divide(den[s]) for s in sources] return eff effs = computeEfficiencies(histosPerSource) can = r.TCanvas('c_'+canvasBasename, canvasBasename, 800, 600) can.cd() pm = first(effs) # pad master pm.SetStats(False) pm.Draw('axis') can.Update() for s, h in effs.iteritems() : h.SetMarkerColor(colors[s] if s in colors else r.kBlack) h.SetLineColor(h.GetMarkerColor()) h.SetLineWidth(2*h.GetLineWidth()) h.SetMarkerStyle(markersSources[s] if s in markersSources else r.kDot) h.Draw('ep same') h.SetDirectory(0) #pprint.pprint(effs) yMin, yMax = getMinMax(effs.values()) pm.SetMinimum(0.0) pm.SetMaximum(0.25 if yMax < 0.5 and zoomIn else 1.1) can.Update() topRightLabel(can, canvasBasename, xpos=0.125, align=13) drawLegendWithDictKeys(can, effs, opt='lp') can.RedrawAxis() can._histos = effs can.Update() outFname = os.path.join(outputDir, canvasBasename+'.png') utils.rmIfExists(outFname) can.SaveAs(outFname)
def plot_emu_mue_with_ratio(canvas=None, h_mue=None, h_emu=None, h_ratio=None, filename='', figformats=['png', 'eps']): c = canvas c.Clear() c._graphics = [] c.cd() botPad, topPad = buildBotTopPads(c, splitFraction=0.375) topPad.Draw() topPad.cd() h_mue.SetStats(0) h_emu.SetStats(0) h_emu.SetLineColor(r.kBlue) h_mue.SetLineColor(r.kRed) h_mue.Draw() h_emu.Draw('same') pm = h_mue yMin, yMax = getMinMax([h_mue, h_emu]) pm.SetMinimum(0.0) pm.SetMaximum(1.1 * yMax) xax = pm.GetXaxis() yax = pm.GetYaxis() xax.SetLabelSize(0) xax.SetTitleSize(0) leg = topLeftLegend(c, 0.275, 0.275, shift=0.05) leg.SetBorderSize(0) leg.SetHeader('non-prompt prediction') leg.AddEntry(h_mue, '#mue', 'L') leg.AddEntry(h_emu, 'e#mu', 'L') leg.Draw() c._graphics.append(leg) c.cd() botPad.Draw() botPad.cd() h_ratio.SetLineColor(r.kBlack) h_ratio.SetTitle('') xax = h_ratio.GetXaxis() yax = h_ratio.GetYaxis() yax.SetRangeUser(0.0, 2.0) yax.SetTitle('e#mu / #mue ratio') xA, yA = h_ratio.GetXaxis(), h_ratio.GetYaxis() textScaleUp = 1.0 / botPad.GetHNDC() yA.SetNdivisions(-104) yA.CenterTitle() yA.SetTitleOffset(yA.GetTitleOffset() / textScaleUp) for a in [xA, yA]: a.SetLabelSize(a.GetLabelSize() * textScaleUp) a.SetTitleSize(a.GetTitleSize() * textScaleUp) h_ratio.Draw() refline = referenceLine(xA.GetXmin(), xA.GetXmax()) refline.Draw() c._graphics.append(refline) c.Update() for ext in figformats: c.SaveAs("{0}.{1}".format(filename, ext))
def plotStackedHistosSources(histosPerVar={}, outputDir='', region='', verbose=False): variables = histosPerVar.keys() sources = first(histosPerVar).keys() colors = colorsFillSources mkdirIfNeeded(outputDir) for var in variables: for lOrT in ['loose', 'tight']: histos = dict((s, histosPerVar[var][s][lOrT]) for s in sources) canvasBasename = region + '_region_' + var + '_' + lOrT missingSources = [s for s, h in histos.iteritems() if not h] if missingSources: if verbose: print "skip %s, missing histos for %s" % ( var, str(missingSources)) continue totBkg = summedHisto(histos.values()) err_band = None # buildErrBandGraph(totBkg, computeStatErr2(totBkg)) emptyBkg = totBkg.Integral() == 0 if emptyBkg: if verbose: print "empty backgrounds, skip %s" % canvasBasename continue can = r.TCanvas('c_' + canvasBasename, canvasBasename, 800, 600) can.cd() pm = totBkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_' + canvasBasename, '') can.Update() r.SetOwnership(stack, False) for s, h in histos.iteritems(): h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') # err_band.Draw('E2 same') yMin, yMax = getMinMax( [h for h in [totBkg, err_band] if h is not None]) pm.SetMinimum(0.0) pm.SetMaximum(1.1 * yMax) can.Update() topRightLabel(can, canvasBasename, xpos=0.125, align=13) # drawLegendWithDictKeys(can, dictSum(histos, {'stat err':err_band}), opt='f') drawLegendWithDictKeys(can, histos, opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()] can.Update() outFname = os.path.join(outputDir, canvasBasename + '.png') utils.rmIfExists(outFname) can.SaveAs(outFname)
def plot_emu_mue_with_ratio(canvas=None, h_mue=None, h_emu=None, h_ratio=None, filename='', figformats=['png', 'eps'], label=''): c = canvas c.Clear() c._graphics = [] c.cd() botPad, topPad = buildBotTopPads(c, splitFraction=0.375) topPad.Draw() topPad.cd() h_mue.SetStats(0) h_emu.SetStats(0) h_emu.SetLineColor(r.kBlue) h_mue.SetLineColor(r.kRed) h_mue.Draw() h_emu.Draw('same') pm = h_mue yMin, yMax = getMinMax([h_mue, h_emu]) pm.SetMinimum(0.0) pm.SetMaximum(1.1 * yMax) xax = pm.GetXaxis() yax = pm.GetYaxis() xax.SetLabelSize(0) xax.SetTitleSize(0) leg = topRightLegend(c, 0.275, 0.275, shift=0.05) leg.SetBorderSize(0) leg.SetHeader(label) leg.AddEntry(h_mue, '#mue', 'L') leg.AddEntry(h_emu, 'e#mu', 'L') leg.Draw() c._graphics.append(leg) c.cd() botPad.Draw() botPad.cd() h_ratio.SetLineColor(r.kBlack) h_ratio.SetTitle('') xax = h_ratio.GetXaxis() yax = h_ratio.GetYaxis() yax.SetRangeUser(0.0, 2.0) yax.SetTitle('e#mu / #mue ratio') xA, yA = h_ratio.GetXaxis(), h_ratio.GetYaxis() textScaleUp = 1.0/botPad.GetHNDC() yA.SetNdivisions(-104) yA.CenterTitle() yA.SetTitleOffset(yA.GetTitleOffset()/textScaleUp) for a in [xA, yA] : a.SetLabelSize(a.GetLabelSize()*textScaleUp) a.SetTitleSize(a.GetTitleSize()*textScaleUp) h_ratio.Draw() refline = referenceLine(xA.GetXmin(), xA.GetXmax()) refline.Draw() c._graphics.append(refline) c.Update() for ext in figformats: c.SaveAs("{0}.{1}".format(filename, ext)) print "{0}.{1}".format(filename, ext)
def plotStackedHistos(histosPerGroup={}, outputDir='', region='', verbose=False): groups = histosPerGroup.keys() variables = first(histosPerGroup).keys() leptonTypes = first(first(histosPerGroup)).keys() colors = SampleUtils.colors mkdirIfNeeded(outputDir) histosPerName = dict([(region+'_'+var+'_'+lt, # one canvas for each histo, so key with histoname w/out group dict([(g, histosPerGroup[g][var][lt]) for g in groups])) for var in variables for lt in leptonTypes]) for histoname, histosPerGroup in histosPerName.iteritems(): missingGroups = [g for g, h in histosPerGroup.iteritems() if not h] if missingGroups: if verbose : print "skip %s, missing histos for %s"%(histoname, str(missingGroups)) continue bkgHistos = dict([(g, h) for g, h in histosPerGroup.iteritems() if isBkgSample(g)]) totBkg = summedHisto(bkgHistos.values()) err_band = buildErrBandGraph(totBkg, computeStatErr2(totBkg)) emptyBkg = totBkg.Integral()==0 if emptyBkg: if verbose : print "empty backgrounds, skip %s"%histoname continue can = r.TCanvas('c_'+histoname, histoname, 800, 600) can.cd() pm = totBkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_'+histoname,'') can.Update() r.SetOwnership(stack, False) for s, h in bkgHistos.iteritems() : h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') err_band.Draw('E2 same') data = histosPerGroup['data'] if data and data.GetEntries(): data.SetMarkerStyle(r.kFullDotLarge) data.Draw('p same') yMin, yMax = getMinMax([h for h in [totBkg, data, err_band] if h]) pm.SetMinimum(0.0) pm.SetMaximum(1.1*yMax) can.Update() topRightLabel(can, histoname, xpos=0.125, align=13) drawLegendWithDictKeys(can, dictSum(bkgHistos, {'stat err':err_band}), opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()]+[data] can.Update() outFname = os.path.join(outputDir, histoname+'.png') utils.rmIfExists(outFname) can.SaveAs(outFname)
def plotStackedHistosWithData(histosPerGroup={}, outputDir='', canvasname='', canvastitle='', colors={}, verbose=False): "histosPerGroup[group], where group=data is treated as special" groups = histosPerGroup.keys() mkdirIfNeeded(outputDir) missingGroups = [g for g, h in histosPerGroup.iteritems() if not h] if missingGroups: if verbose : print "skip %s, missing histos for %s"%(histoname, str(missingGroups)) return bkgHistos = dict([(g, h) for g, h in histosPerGroup.iteritems() if not isDataSample(g)]) totBkg = summedHisto(bkgHistos.values()) err_band = buildErrBandGraph(totBkg, computeStatErr2(totBkg)) emptyBkg = totBkg.Integral()==0 histoname, region = totBkg.GetName(), 'emu' # tmp replacement vars, to be fixed if emptyBkg: if verbose : print "empty backgrounds, skip %s"%histoname return can = r.TCanvas(canvasname, canvastitle, 800, 600) can.cd() pm = totBkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_'+histoname,'') can.Update() r.SetOwnership(stack, False) for s, h in bkgHistos.iteritems() : h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') err_band.Draw('E2 same') data = histosPerGroup['data'] if 'data' in histosPerGroup else None if data and data.GetEntries(): data.SetMarkerStyle(r.kFullDotLarge) data.Draw('p same') if verbose : print "integrals : {0} tot.bkg.: {1}, data: {2}".format(histoname, totBkg.Integral(), data.Integral()) else: print "no data" yMin, yMax = getMinMax([h for h in [totBkg, data, err_band] if h]) pm.SetMinimum(0.0) pm.SetMaximum(1.1*yMax) can.Update() topRightLabel(can, "#splitline{%s}{%s}"%(histoname, region), xpos=0.15, ypos=(1.0-0.5*can.GetTopMargin()), align=13) drawLegendWithDictKeys(can, dictSum(bkgHistos, {'stat err':err_band}), opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()]+[data] can.Update() filename=os.path.join(outputDir, histoname+'.png') rmIfExists(filename) can.SaveAs(filename)
def drawTop(pad, hists, err_band, label=('','')) : pad.Draw() pad.cd() h_data = hists[dataSample()] h_bkg = hists['sm'] stack = r.THStack('stack_'+h_data.GetName(), '') leg = topRightLegend(pad, 0.275, 0.475, shift=-0.025) leg.SetBorderSize(0) leg.AddEntry(h_data, dataSample(), 'P') leg.AddEntry(h_bkg, 'sm', 'L') counters = dict() if 'nbjets' in h_data.GetName() : counters['data'] = integralAndError(h_data) counters['sm'] = integralAndError(h_bkg) for s in bkSamples() : h = hists[s] h.SetMarkerSize(0) h.SetFillColor(colors[s]) h.SetLineColor(h.GetFillColor()) h.SetDrawOption('bar') if 'nbjets' in h.GetName() : counters[s] = integralAndError(h) stack.Add(h) for s in bkSamples()[::-1] : leg.AddEntry(hists[s], s, 'F') # stack goes b-t, legend goes t-b h_data.SetMarkerStyle(r.kFullDotLarge) stack.Draw('hist') h_bkg.Draw('hist same') err_band.Draw('E2 same') h_data.Draw('p same') leg.AddEntry(err_band, 'Uncertainty', 'F') leg.Draw('same') tex = r.TLatex() tex.SetNDC(True) label = "#splitline{%s}{%s}"%(label[0], label[1]) if len(label)==2 else label tex.DrawLatex(0.50, 0.85, label) pad.Update() # force stack to create padMaster padMaster = stack.GetHistogram() pMin, pMax = getMinMax([h_bkg, h_data, err_band]) stack.SetMaximum(pMax) xAx, yAx = padMaster.GetXaxis(), padMaster.GetYaxis() xAx.SetTitle('') xAx.SetLabelSize(0) textScaleUp = 1.0/pad.GetHNDC() yAx.SetLabelSize(textScaleUp*yAx.GetLabelSize()) pad._graphical_objects = [stack, h_data, h_bkg, err_band, leg, tex] + [h for h in stack.GetStack()] pad.Update() if 'nbjets' in h_data.GetName() : print h_data.GetName() print " | ".join(["%12s"%k for k,v in sorted(counters.items())]) print " | ".join(["%12s"%("%.1f +/- %.1f"%v) for k,v in sorted(counters.items())])
def plotStackedHistosSources(histosPerVar={}, outputDir='', region='', verbose=False): variables = histosPerVar.keys() sources = first(histosPerVar).keys() colors = colorsFillSources mkdirIfNeeded(outputDir) for var in variables: for lOrT in ['loose', 'tight']: histos = dict((s, histosPerVar[var][s][lOrT]) for s in sources) canvasBasename = region+'_region_'+var+'_'+lOrT missingSources = [s for s, h in histos.iteritems() if not h] if missingSources: if verbose : print "skip %s, missing histos for %s"%(var, str(missingSources)) continue totBkg = summedHisto(histos.values()) err_band = None # buildErrBandGraph(totBkg, computeStatErr2(totBkg)) emptyBkg = totBkg.Integral()==0 if emptyBkg: if verbose : print "empty backgrounds, skip %s"%canvasBasename continue can = r.TCanvas('c_'+canvasBasename, canvasBasename, 800, 600) can.cd() pm = totBkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_'+canvasBasename,'') can.Update() r.SetOwnership(stack, False) for s, h in histos.iteritems() : h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') # err_band.Draw('E2 same') yMin, yMax = getMinMax([h for h in [totBkg, err_band] if h is not None]) pm.SetMinimum(0.0) pm.SetMaximum(1.1*yMax) can.Update() topRightLabel(can, canvasBasename, xpos=0.125, align=13) # drawLegendWithDictKeys(can, dictSum(histos, {'stat err':err_band}), opt='f') drawLegendWithDictKeys(can, histos, opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()] can.Update() outFname = os.path.join(outputDir, canvasBasename+'.png') utils.rmIfExists(outFname) can.SaveAs(outFname)
def plotStackedHistos(histos={}, datakey=None, stackkeys=[], outputDir='', region='', colors={}, verbose=False): "input: a dictionary of histos[group]" mkdirIfNeeded(outputDir) bkg_histos = dict([(k,h) for k,h in histos.iteritems() if k in stackkeys]) tot_bkg = summedHisto(bkg_histos.values(), label='') err_band = None # tmp disable # err_band = buildErrBandGraph(tot_bkg, computeStatErr2(tot_bkg)) empty_bkg = tot_bkg.Integral()==0 if empty_bkg: if verbose : print "empty backgrounds, skip %s"%tot_bkg.GetName() return histoname = tot_bkg.GetName() can = r.TCanvas('c_'+histoname, histoname, 800, 600) can.cd() pm = tot_bkg # pad master pm.SetStats(False) pm.Draw('axis') can.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_'+tot_bkg.GetName(),'') can.Update() r.SetOwnership(stack, False) for s, h in bkg_histos.iteritems() : h.SetFillColor(colors[s] if s in colors else r.kOrange) h.SetDrawOption('bar') h.SetDirectory(0) stack.Add(h) stack.Draw('hist same') # err_band.Draw('E2 same') data = histos[datakey] if datakey and datakey in histos else None if data and data.GetEntries(): data.SetMarkerStyle(r.kFullDotLarge) data.Draw('p same') if verbose: print "data : nEntries {:.1f} totWeight {:.1f} ".format(data.GetEntries(), data.Integral()) yMin, yMax = getMinMax([h for h in [tot_bkg, data, err_band] if h]) # pm.SetMinimum(0.5) pm.SetMaximum(1.1*yMax) can.Update() # can.SetLogy() topRightLabel(can, "#splitline{%s}{%s}"%(histoname, region), xpos=0.125, align=13) drawLegendWithDictKeys(can, dictSum(bkg_histos, {'stat err':err_band}), opt='f') can.RedrawAxis() can._stack = stack can._histos = [h for h in stack.GetHists()]+[data] can.Update() if verbose : print os.path.join(outputDir, histoname+'.png') can.SaveAs(os.path.join(outputDir, histoname+'.png'))
def plotHisto(inputFiles={}, histoname='', canvasname='', outdir='./') : can = r.TCanvas(canvasname, histoname, 800, 600) can.cd() backds = [b for b in backgrounds if b in inputFiles] stackBkgds = filter(lambda x : x in backds, stackedBackgrounds) h_bkgs = dict((b, inputFiles[b].Get(histoname)) for b in backds) h_btot = inputFiles['allBkg'].Get(histoname) if 'allBkg' in inputFiles else None h_bnoHf = inputFiles['allBkgButHf'].Get(histoname) if 'allBkgButHf' in inputFiles else None h_data = inputFiles['data'].Get(histoname) if 'data' in inputFiles else None stack = r.THStack('stack_'+histoname, '') leg = topRightLegend(can, 0.275, 0.475, shift=-0.025) if h_data : leg.AddEntry(h_data, "data: %.1f"%h_data.Integral(), 'P') if h_btot : leg.AddEntry(h_btot, "tot bkg %.1f"%h_btot.Integral(), 'l') if h_bnoHf : leg.AddEntry(h_bnoHf, "bkgNoHf: %.1f"%h_bnoHf.Integral(), 'l') for b in stackBkgds : h = h_bkgs[b] if not h : print 'missing h for ',b continue h.SetMarkerSize(0) h.SetFillColor(colors[b]) h.SetLineColor(h.GetFillColor()) h.SetDrawOption('bar') stack.Add(h) for s in stackBkgds[::-1] : leg.AddEntry(h_bkgs[s], "%s: %.1f"%(s, h_bkgs[s].Integral()), 'F') # stack goes b-t, legend goes t-b stack.Draw('hist') if h_btot : h_btot.SetLineWidth(2*h_btot.GetLineWidth()) h_btot.Draw('hist same') if h_bnoHf : h_bnoHf.SetLineWidth(2*h_bnoHf.GetLineWidth()) h_bnoHf.SetLineStyle(2) h_bnoHf.Draw('hist same') if h_data : h_data.SetMarkerStyle(r.kFullDotLarge) h_data.Draw('p same') leg.Draw('same') yMin, yMax = getMinMax([h for h in [stack.GetHistogram(), h_btot, h_bnoHf, h_data] if h is not None]) stack.SetMaximum(1.1*yMax) tex = r.TLatex() tex.SetNDC(True) tex.DrawLatex(0.15, 0.95, histoname) can.Update() for ext in ['png'] : can.SaveAs(outdir+'/'+canvasname+'.'+ext)
def plotHistos(histoData=None, histoSignal=None, histoTotBkg=None, histosBkg={}, statErrBand=None, systErrBand=None, # these are TGraphAsymmErrors canvasName='canvas', outdir='./', options=None, stack_order=[], topLabel='', drawStatErr=False, drawSystErr=False, drawYieldAndError=False, printYieldSummary=False) : "Note: blinding can be required for only a subrange of the histo, so it is taken care of when filling" verbose = options.verbose formatAuxMaterial = options.format_aux setAtlasStyle() padMaster = histoData if verbose : print "plotting ",padMaster.GetName(),' (',padMaster.GetEntries(),' entries)' can = r.TCanvas(canvasName, padMaster.GetTitle(), 800, 800) botPad, topPad = buildBotTopPads(can, squeezeMargins=False) can.cd() topPad.Draw() # draw top topPad.cd() topPad._hists = [padMaster] if formatAuxMaterial: for ax in [padMaster.GetXaxis(), padMaster.GetYaxis()]: ax.SetTitle(prettify(ax.GetTitle())) padMaster.Draw('axis') topPad.Update() # necessary to fool root's dumb object ownership of the stack stack = r.THStack('stack_'+padMaster.GetName(), '') r.SetOwnership(stack, False) topPad._hists.append(stack) leg = topRightLegend(can, 0.300 if formatAuxMaterial else 0.225, 0.400 if formatAuxMaterial else 0.325, shiftX=-0.1 if formatAuxMaterial else 0.0, shiftY=-0.1 if formatAuxMaterial else 0.0) topPad._leg = leg leg.SetBorderSize(0) leg.SetTextFont(padMaster.GetTitleFont()) leg._reversedEntries = [] def integralWou(h): "Integral with underflow and overflow" return h.Integral(0, h.GetNbinsX()+1) for group, histo in sortedAs(histosBkg, stack_order) : histo.SetFillColor(getGroupColor(group)) histo.SetLineWidth(2) histo.SetLineColor(r.kBlack) stack.Add(histo) topPad._hists.append(histo) leg._reversedEntries.append((histo, prettify(group) if formatAuxMaterial else "{0}: {1:.2f}".format(group, integralWou(histo)), 'F')) if not formatAuxMaterial: leg._reversedEntries.append((dummyHisto(), "{0}, {1:.2f}".format('bkg', sum([integralWou(h) for h in stack.GetHists()])), 'l')) if statErrBand and drawStatErr : statErrBand.SetFillStyle(3006) leg._reversedEntries.append((statErrBand, 'stat', 'f')) if systErrBand and drawSystErr : systErrBand.SetFillStyle(3007) leg._reversedEntries.append((systErrBand, 'syst', 'f')) leg._reversedEntries.append((histoData, "Data {0}".format(prettify(topLabel)) if formatAuxMaterial else "{0}, {1:.2f}".format('data', integralWou(histoData)), 'p')) for h, g, o in leg._reversedEntries[::-1] : leg.AddEntry(h, g, o) # stack goes b-t, legend goes t-b stack.Draw('hist same') histoData.SetMarkerStyle(r.kFullCircle) histoData.SetLineWidth(2) dataGraph = graphWithPoissonError(histoData) dataGraph.Draw('same p') isRightSignal = False if histoSignal: histoSignal.SetFillStyle(0) histoSignal.SetFillColor(0) histoSignal.SetLineColor(getGroupColor('signal')) histoSignal.SetLineWidth(3) isRightSignal = (all(s in histoSignal.GetName() for s in ['signaltaumu', 'sr_mue']) or all(s in histoSignal.GetName() for s in ['signaltaue', 'sr_emu'])) if isRightSignal: histoSignal.Draw('histo same') if statErrBand and drawStatErr : statErrBand.SetFillStyle(3006) statErrBand.Draw('E2 same') leg.AddEntry(statErrBand, 'stat', 'f') if systErrBand and drawSystErr : systErrBand.SetFillStyle(3007) systErrBand.Draw('E2 same') leg.AddEntry(systErrBand, 'syst', 'f') totErrBand = systUtils.addErrorBandsInQuadrature(statErrBand, systErrBand) if totErrBand : totErrBand.Draw('E2 same') totErrBand.SetFillStyle(3005) leg.AddEntry(totErrBand, 'stat+syst', 'f') if printYieldSummary: print_total_error = False print ("{}:".format(topLabel if topLabel else dataGraph.GetName())+ (" expected {:.2f}^{{+{:.2f}}}_{{{:.2f}}}".format(totErrBand.GetY()[0], totErrBand.GetErrorYhigh(0), totErrBand.GetErrorYlow(0)) if print_total_error else " expected {:.2f}^{{+{:.2f}}}_{{{:.2f}}} (stat) ^{{+{:.2f}}}_{{{:.2f}}} (syst)" .format(totErrBand.GetY()[0], statErrBand.GetErrorYhigh(0) if statErrBand else 0.0, statErrBand.GetErrorYlow(0) if statErrBand else 0.0, systErrBand.GetErrorYhigh(0) if systErrBand else 0.0, systErrBand.GetErrorYlow(0) if systErrBand else 0.0) )+ " obs {:.2f}".format(dataGraph.GetY()[0])) if histoSignal and isRightSignal: hname = histoSignal.GetName() label = ('H#rightarrow#mu#tau' if 'signaltaumu' in hname else 'H#rightarrowe#tau' if 'signaltaue' in hname else 'signal') label = ("{}, BR=1%".format(label) if formatAuxMaterial else "{}, BR=1%, {:.2f}".format(label, integralWou(histoSignal))) leg.AddEntry(histoSignal, label, 'l') leg.Draw('same') topPad.Update() tex = r.TLatex() tex.SetTextSize(0.5 * tex.GetTextSize()) tex.SetNDC(True) label = "%s tot bkg : "%(can.GetName()) label += "%.3f #pm %.3f (stat)"%(integralAndError(histoTotBkg)) if systErrBand : sysUp, sysDo = systUtils.totalUpDownVariation(systErrBand) label += "#pm #splitline{%.3f}{%.3f} (syst)"%(sysUp, sysDo) if drawYieldAndError : tex.DrawLatex(0.10, 0.95, label) topPad.SetTopMargin(2.0*topPad.GetTopMargin()) atlasLabel = drawAtlasLabel(can, align=13, scale=0.75, xpos=0.175 if formatAuxMaterial else 0.125, ypos=0.945 if formatAuxMaterial else None, public=True) if topLabel and not formatAuxMaterial : topRightLabel(can, topLabel, ypos=1.0) yMin, yMax = getMinMax([histoData, dataGraph, histoTotBkg, histoSignal, totErrBand]) padMaster.SetMinimum(0.0) padMaster.SetMaximum(1.1 * yMax) padMaster.GetXaxis().SetLabelSize(0) padMaster.GetXaxis().SetTitleSize(0) increaseAxisFont(padMaster.GetXaxis()) increaseAxisFont(padMaster.GetYaxis()) topPad.RedrawAxis() topPad.Update() # force stack to create padMaster # draw bot (ratio) can.cd() botPad.Draw() botPad.cd() ratio = systUtils.buildAsymmRatioGraph(dataGraph, totErrBand) ratioPadMaster = padMaster.Clone(padMaster.GetName()+'_ratio') ratioPadMaster.SetDirectory(0) ratioPadMaster.Clear() yMin, yMax = 0.0, 2.0 ratioPadMaster.SetMinimum(yMin) ratioPadMaster.SetMaximum(yMax) ratioPadMaster.SetStats(0) ratioPadMaster.Draw('axis') x_lo, x_hi = getXrange(ratioPadMaster) refLines = [referenceLine(x_lo, x_hi, y, y) for y in [0.5, 1.0, 1.5]] for l in refLines : l.Draw() err_band_r = systUtils.buildErrBandRatioGraph(totErrBand) err_band_r.Draw('E2 same') ratio.Draw('ep') xA, yA = ratioPadMaster.GetXaxis(), ratioPadMaster.GetYaxis() textScaleUp = 0.75*1.0/botPad.GetHNDC() # if xaxis_title : xA.SetTitle(xaxis_title) yA.SetNdivisions(-104) yA.SetTitle('Data/Bkg') yA.CenterTitle() yA.SetTitleOffset(yA.GetTitleOffset()/textScaleUp) xA.SetTitleSize(yA.GetTitleSize()) # was set to 0 for padmaster, restore it xA.SetLabelSize(yA.GetLabelSize()) for a in [xA, yA] : a.SetLabelSize(a.GetLabelSize()*textScaleUp) a.SetTitleSize(a.GetTitleSize()*textScaleUp) botPad._graphical_objects = [ratio, ratioPadMaster, err_band_r] + refLines # avoid garbage collection botPad.Update() can.Update() for ext in ['png','eps'] : can.SaveAs(outdir+'/'+can.GetName()+'.'+ext)
def plotPerSourceEff(histosPerVar={}, outputDir='', lepton='', region='', sample='', verbose=False, zoomIn=True): "plot efficiency for each source (and 'anysource') as a function of each var; expect histos[var][source][loose,tight]" variables = histosPerVar.keys() sources = [s for s in first(histosPerVar).keys() if s != 'real'] # only fake eff really need a scale factor colors = colorsLineSources mkdirIfNeeded(outputDir) for var in filter(lambda x: x in ['pt1', 'eta1'], histosPerVar.keys()): histosPerSource = dict((s, histosPerVar[var][s]) for s in sources) canvasBasename = region + '_efficiency_' + lepton + '_' + var + ( "_%s" % sample if sample else '') missingSources = [ s for s, h in histosPerSource.iteritems() if not h['loose'] or not h['tight'] ] if missingSources: if verbose: print "skip %s, missing histos for %s" % (var, str(missingSources)) continue anySourceLoose = summedHisto( [h['loose'] for h in histosPerSource.values()]) anySourceTight = summedHisto( [h['tight'] for h in histosPerSource.values()]) anySourceLoose.SetName(histoNamePerSource(var, 'any', 'loose', region)) anySourceTight.SetName(histoNamePerSource(var, 'any', 'tight', region)) histosPerSource['any'] = { 'loose': anySourceLoose, 'tight': anySourceTight } emptyBkg = anySourceLoose.Integral() == 0 or anySourceTight.Integral( ) == 0 if emptyBkg: if verbose: print "empty backgrounds, skip %s" % canvasBasename continue def computeEfficiencies(histosPerSource={}): sources = histosPerSource.keys() num = dict((s, histosPerSource[s]['tight']) for s in sources) den = dict((s, histosPerSource[s]['loose']) for s in sources) eff = dict( (s, h.Clone(h.GetName().replace('tight', 'tight_over_loose'))) for s, h in num.iteritems()) [eff[s].Divide(den[s]) for s in sources] return eff effs = computeEfficiencies(histosPerSource) can = r.TCanvas('c_' + canvasBasename, canvasBasename, 800, 600) can.cd() pm = first(effs) # pad master pm.SetStats(False) pm.Draw('axis') can.Update() for s, h in effs.iteritems(): h.SetMarkerColor(colors[s] if s in colors else r.kBlack) h.SetLineColor(h.GetMarkerColor()) h.SetLineWidth(2 * h.GetLineWidth()) h.SetMarkerStyle(markersSources[s] if s in markersSources else r.kDot) h.Draw('ep same') h.SetDirectory(0) #pprint.pprint(effs) yMin, yMax = getMinMax(effs.values()) pm.SetMinimum(0.0) pm.SetMaximum(0.25 if yMax < 0.5 and zoomIn else 1.1) can.Update() topRightLabel(can, canvasBasename, xpos=0.125, align=13) drawLegendWithDictKeys(can, effs, opt='lp') can.RedrawAxis() can._histos = effs can.Update() outFname = os.path.join(outputDir, canvasBasename + '.png') utils.rmIfExists(outFname) can.SaveAs(outFname)
def plotHistos( histoData=None, histoSignal=None, histoTotBkg=None, histosBkg={}, statErrBand=None, systErrBand=None, # these are TGraphAsymmErrors canvasName='canvas', outdir='./', options=None, stack_order=[], topLabel='', drawStatErr=False, drawSystErr=False, drawYieldAndError=False, printYieldSummary=False): "Note: blinding can be required for only a subrange of the histo, so it is taken care of when filling" verbose = options.verbose formatAuxMaterial = options.format_aux setAtlasStyle() padMaster = histoData if verbose: print "plotting ", padMaster.GetName(), ' (', padMaster.GetEntries( ), ' entries)' can = r.TCanvas(canvasName, padMaster.GetTitle(), 800, 800) botPad, topPad = buildBotTopPads(can, squeezeMargins=False) can.cd() topPad.Draw() # draw top topPad.cd() topPad._hists = [padMaster] if formatAuxMaterial: for ax in [padMaster.GetXaxis(), padMaster.GetYaxis()]: ax.SetTitle(prettify(ax.GetTitle())) padMaster.Draw('axis') topPad.Update( ) # necessary to fool root's dumb object ownership of the stack stack = r.THStack('stack_' + padMaster.GetName(), '') r.SetOwnership(stack, False) topPad._hists.append(stack) leg = topRightLegend(can, 0.300 if formatAuxMaterial else 0.225, 0.400 if formatAuxMaterial else 0.325, shiftX=-0.1 if formatAuxMaterial else 0.0, shiftY=-0.1 if formatAuxMaterial else 0.0) topPad._leg = leg leg.SetBorderSize(0) leg.SetTextFont(padMaster.GetTitleFont()) leg._reversedEntries = [] def integralWou(h): "Integral with underflow and overflow" return h.Integral(0, h.GetNbinsX() + 1) for group, histo in sortedAs(histosBkg, stack_order): histo.SetFillColor(getGroupColor(group)) histo.SetLineWidth(2) histo.SetLineColor(r.kBlack) stack.Add(histo) topPad._hists.append(histo) leg._reversedEntries.append( (histo, prettify(group) if formatAuxMaterial else "{0}: {1:.2f}".format(group, integralWou(histo)), 'F')) if not formatAuxMaterial: leg._reversedEntries.append((dummyHisto(), "{0}, {1:.2f}".format( 'bkg', sum([integralWou(h) for h in stack.GetHists()])), 'l')) if statErrBand and drawStatErr: statErrBand.SetFillStyle(3006) leg._reversedEntries.append((statErrBand, 'stat', 'f')) if systErrBand and drawSystErr: systErrBand.SetFillStyle(3007) leg._reversedEntries.append((systErrBand, 'syst', 'f')) leg._reversedEntries.append( (histoData, "Data {0}".format(prettify(topLabel)) if formatAuxMaterial else "{0}, {1:.2f}".format('data', integralWou(histoData)), 'p')) for h, g, o in leg._reversedEntries[::-1]: leg.AddEntry(h, g, o) # stack goes b-t, legend goes t-b stack.Draw('hist same') histoData.SetMarkerStyle(r.kFullCircle) histoData.SetLineWidth(2) dataGraph = graphWithPoissonError(histoData) dataGraph.Draw('same p') isRightSignal = False if histoSignal: histoSignal.SetFillStyle(0) histoSignal.SetFillColor(0) histoSignal.SetLineColor(getGroupColor('signal')) histoSignal.SetLineWidth(3) isRightSignal = (all(s in histoSignal.GetName() for s in ['signaltaumu', 'sr_mue']) or all(s in histoSignal.GetName() for s in ['signaltaue', 'sr_emu'])) if isRightSignal: histoSignal.Draw('histo same') if statErrBand and drawStatErr: statErrBand.SetFillStyle(3006) statErrBand.Draw('E2 same') leg.AddEntry(statErrBand, 'stat', 'f') if systErrBand and drawSystErr: systErrBand.SetFillStyle(3007) systErrBand.Draw('E2 same') leg.AddEntry(systErrBand, 'syst', 'f') totErrBand = systUtils.addErrorBandsInQuadrature(statErrBand, systErrBand) if totErrBand: totErrBand.Draw('E2 same') totErrBand.SetFillStyle(3005) leg.AddEntry(totErrBand, 'stat+syst', 'f') if printYieldSummary: print_total_error = False print( "{}:".format(topLabel if topLabel else dataGraph.GetName()) + (" expected {:.2f}^{{+{:.2f}}}_{{{:.2f}}}".format( totErrBand.GetY()[0], totErrBand.GetErrorYhigh(0), totErrBand.GetErrorYlow(0)) if print_total_error else " expected {:.2f}^{{+{:.2f}}}_{{{:.2f}}} (stat) ^{{+{:.2f}}}_{{{:.2f}}} (syst)" .format(totErrBand.GetY()[0], statErrBand.GetErrorYhigh(0) if statErrBand else 0.0, statErrBand.GetErrorYlow(0) if statErrBand else 0.0, systErrBand.GetErrorYhigh(0) if systErrBand else 0.0, systErrBand.GetErrorYlow(0) if systErrBand else 0.0)) + " obs {:.2f}".format(dataGraph.GetY()[0])) if histoSignal and isRightSignal: hname = histoSignal.GetName() label = ('H#rightarrow#mu#tau' if 'signaltaumu' in hname else 'H#rightarrowe#tau' if 'signaltaue' in hname else 'signal') label = ("{}, BR=1%".format(label) if formatAuxMaterial else "{}, BR=1%, {:.2f}".format(label, integralWou(histoSignal))) leg.AddEntry(histoSignal, label, 'l') leg.Draw('same') topPad.Update() tex = r.TLatex() tex.SetTextSize(0.5 * tex.GetTextSize()) tex.SetNDC(True) label = "%s tot bkg : " % (can.GetName()) label += "%.3f #pm %.3f (stat)" % (integralAndError(histoTotBkg)) if systErrBand: sysUp, sysDo = systUtils.totalUpDownVariation(systErrBand) label += "#pm #splitline{%.3f}{%.3f} (syst)" % (sysUp, sysDo) if drawYieldAndError: tex.DrawLatex(0.10, 0.95, label) topPad.SetTopMargin(2.0 * topPad.GetTopMargin()) atlasLabel = drawAtlasLabel(can, align=13, scale=0.75, xpos=0.175 if formatAuxMaterial else 0.125, ypos=0.945 if formatAuxMaterial else None, public=True) if topLabel and not formatAuxMaterial: topRightLabel(can, topLabel, ypos=1.0) yMin, yMax = getMinMax( [histoData, dataGraph, histoTotBkg, histoSignal, totErrBand]) padMaster.SetMinimum(0.0) padMaster.SetMaximum(1.1 * yMax) padMaster.GetXaxis().SetLabelSize(0) padMaster.GetXaxis().SetTitleSize(0) increaseAxisFont(padMaster.GetXaxis()) increaseAxisFont(padMaster.GetYaxis()) topPad.RedrawAxis() topPad.Update() # force stack to create padMaster # draw bot (ratio) can.cd() botPad.Draw() botPad.cd() ratio = systUtils.buildAsymmRatioGraph(dataGraph, totErrBand) ratioPadMaster = padMaster.Clone(padMaster.GetName() + '_ratio') ratioPadMaster.SetDirectory(0) ratioPadMaster.Clear() yMin, yMax = 0.0, 2.0 ratioPadMaster.SetMinimum(yMin) ratioPadMaster.SetMaximum(yMax) ratioPadMaster.SetStats(0) ratioPadMaster.Draw('axis') x_lo, x_hi = getXrange(ratioPadMaster) refLines = [referenceLine(x_lo, x_hi, y, y) for y in [0.5, 1.0, 1.5]] for l in refLines: l.Draw() err_band_r = systUtils.buildErrBandRatioGraph(totErrBand) err_band_r.Draw('E2 same') ratio.Draw('ep') xA, yA = ratioPadMaster.GetXaxis(), ratioPadMaster.GetYaxis() textScaleUp = 0.75 * 1.0 / botPad.GetHNDC() # if xaxis_title : xA.SetTitle(xaxis_title) yA.SetNdivisions(-104) yA.SetTitle('Data/Bkg') yA.CenterTitle() yA.SetTitleOffset(yA.GetTitleOffset() / textScaleUp) xA.SetTitleSize( yA.GetTitleSize()) # was set to 0 for padmaster, restore it xA.SetLabelSize(yA.GetLabelSize()) for a in [xA, yA]: a.SetLabelSize(a.GetLabelSize() * textScaleUp) a.SetTitleSize(a.GetTitleSize() * textScaleUp) botPad._graphical_objects = [ratio, ratioPadMaster, err_band_r ] + refLines # avoid garbage collection botPad.Update() can.Update() for ext in ['png', 'eps']: can.SaveAs(outdir + '/' + can.GetName() + '.' + ext)
def plotHistos(histoData=None, histoSignal=None, histoTotBkg=None, histosBkg={}, statErrBand=None, systErrBand=None, # these are TGraphAsymmErrors canvasName='canvas', outdir='./', verbose=False, drawStatErr=False, drawSystErr=False, drawYieldAndError=False) : "Note: blinding can be required for only a subrange of the histo, so it is taken care of when filling" #setWhPlotStyle() setAtlasStyle() padMaster = histoData if verbose : print "plotting ",padMaster.GetName() can = r.TCanvas(canvasName, padMaster.GetTitle(), 800, 600) can.cd() can._hists = [padMaster] padMaster.Draw('axis') can.Update() # necessary to fool root's dumb object ownership of the stack stack = r.THStack('stack_'+padMaster.GetName(), '') r.SetOwnership(stack, False) can._hists.append(stack) leg = topRightLegend(can, 0.225, 0.325) can._leg = leg leg.SetBorderSize(0) leg._reversedEntries = [] for group, histo in sortedAs(histosBkg, stackedGroups()) : histo.SetFillColor(getGroupColor(group)) histo.SetLineWidth(2) histo.SetLineColor(r.kBlack) stack.Add(histo) can._hists.append(histo) leg._reversedEntries.append((histo, group, 'F')) for h, g, o in leg._reversedEntries[::-1] : leg.AddEntry(h, g, o) # stack goes b-t, legend goes t-b stack.Draw('hist same') histoData.SetMarkerStyle(r.kFullCircle) histoData.SetLineWidth(2) dataGraph = graphWithPoissonError(histoData) dataGraph.Draw('same p') if histoSignal : histoSignal.SetLineColor(getGroupColor('signal')) histoSignal.SetLineWidth(2) histoSignal.Draw('histo same') leg.AddEntry(histoSignal, '(m_{C1},m_{N1})=(130, 0)GeV', 'l') if statErrBand and drawStatErr : statErrBand.SetFillStyle(3006) statErrBand.Draw('E2 same') leg.AddEntry(statErrBand, 'stat', 'f') if systErrBand and drawSystErr : systErrBand.SetFillStyle(3007) systErrBand.Draw('E2 same') leg.AddEntry(systErrBand, 'syst', 'f') totErrBand = systUtils.addErrorBandsInQuadrature(statErrBand, systErrBand) if totErrBand : totErrBand.Draw('E2 same') totErrBand.SetFillStyle(3005) leg.AddEntry(totErrBand, 'stat+syst', 'f') leg.Draw('same') can.Update() tex = r.TLatex() tex.SetTextSize(0.5 * tex.GetTextSize()) tex.SetNDC(True) label = "%s tot bkg : "%(can.GetName()) label += "%.3f #pm %.3f (stat)"%(integralAndError(histoTotBkg)) if systErrBand : sysUp, sysDo = systUtils.totalUpDownVariation(systErrBand) label += "#pm #splitline{%.3f}{%.3f} (syst)"%(sysUp, sysDo) if drawYieldAndError : tex.DrawLatex(0.10, 0.95, label) can.SetTopMargin(2.0*can.GetTopMargin()) drawAtlasLabel(can, xpos=0.125, align=13) yMin, yMax = getMinMax([histoData, dataGraph, histoTotBkg, histoSignal, totErrBand]) padMaster.SetMinimum(0.0) padMaster.SetMaximum(1.1 * yMax) increaseAxisFont(padMaster.GetXaxis()) increaseAxisFont(padMaster.GetYaxis()) can.RedrawAxis() can.Update() # force stack to create padMaster for ext in ['png','eps'] : can.SaveAs(outdir+'/'+can.GetName()+'.'+ext)