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 drawBottom(pad, totBkg, bkgHistos, sigHisto, llnjvar) : pad.cd() totBkg.SetStats(False) totBkg.SetMinimum(0.) # force this to avoid negative fluct due to fake totBkg.Draw('axis') pad.Update() # necessary to fool root's dumb object ownership stack = r.THStack('stack_'+llnjvar,'') pad.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') pad.Update() sigHisto.SetLineColor(r.kRed) sigHisto.SetLineWidth(2*sigHisto.GetLineWidth()) sigHisto.Draw('same') pad.Update() topRightLabel(pad, llnjvar, xpos=0.125, align=13) drawLegendWithDictKeys(pad, dictSum(bkgHistos, {'signal' : sigHisto}), opt='f') pad.RedrawAxis() pad._stack = stack pad._histos = [h for h in stack.GetHists()] pad.Update()
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 plotHistRatioAndFit(histos, ratio, fitfunc, outfname, graphics_attributes={}) : can = r.TCanvas('can_'+outfname, outfname, 800, 600) botPad, topPad = buildBotTopPads(can, splitFraction=0.35) can.cd() topPad.Draw() topPad.cd() pm = first(histos) pm.Draw('axis') xAx, yAx = pm.GetXaxis(), pm.GetYaxis() xAx.SetTitle('') xAx.SetLabelSize(0) yAx.SetRangeUser(0.0, 1.2) yAx.SetNdivisions(505) # for some reason some of the inputs are already ratios with -201 textScaleUp = 1.0/topPad.GetHNDC() yAx.SetLabelSize(textScaleUp*0.04) yAx.SetTitleSize(textScaleUp*0.04) yAx.SetTitle(graphics_attributes['ytitle']) yAx.SetTitleOffset(yAx.GetTitleOffset()/textScaleUp) for k, h in histos.iteritems() : h.SetMarkerStyle(graphics_attributes['markers'][k]) h.SetMarkerColor(graphics_attributes['colors'][k]) h.SetLineColor(graphics_attributes['colors'][k]) h.Draw('same') labels = graphics_attributes['labels'] drawLegendWithDictKeys(topPad, dict([(labels[s], histos[s]) for s in histos.keys()]), legWidth=0.4) can.cd() botPad.Draw() botPad.cd() ratio.Draw('axis') textScaleUp = 1.0/botPad.GetHNDC() xAx, yAx = ratio.GetXaxis(), ratio.GetYaxis() yAx.SetRangeUser(0.0, 2.0) xAx.SetTitle(graphics_attributes['xtitle']) yAx.SetNdivisions(-202) yAx.SetTitle('Data/Sim') yAx.CenterTitle() for a in [xAx, yAx] : if a.GetLabelSize()>0.04 : continue a.SetLabelSize(a.GetLabelSize()*textScaleUp) a.SetTitleSize(a.GetTitleSize()*textScaleUp) a.SetTitleOffset(a.GetTitleOffset()/textScaleUp) ratio.SetMarkerStyle(graphics_attributes['markers']['data']) fitfunc.SetLineWidth(2) fitfunc.SetLineStyle(2) fitfunc.Draw('same') ratio.Draw('same') tex = r.TLatex() tex.SetNDC(True) p0, p0Err, chi2, ndf = fitResults(fitfunc) fitParLabel = "Const. fit : %s #pm %s"%(pdgRound(p0, p0Err)) fitGoodLabel = "#chi^{2}/DOF : %.2f / %d"%(chi2, ndf) tex.SetTextSize(yAx.GetTitleSize()) tex.SetTextFont(yAx.GetTitleFont()) tex.DrawLatex(0.15, 0.40, "#splitline{%s}{%s}"%(fitParLabel, fitGoodLabel)) can.Update() outfname = outfname+'.png' rmIfExists(outfname) # avoid root warnings can.SaveAs(outfname)
def plotStackedHistos(histosPerGroup={}, outputDir='', region='', verbose=False): groups = histosPerGroup.keys() variables = first(histosPerGroup).keys() leptonTypes = first(first(histosPerGroup)).keys() colors = getGroupColor() 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 g not in ['data', 'signal']]) totBkg = summedHisto(bkgHistos.values()) err_band = None # 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]) # fixme with err_band yMin, yMax = 0.0, data.GetMaximum() 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') drawLegendWithDictKeys(can, bkgHistos, 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 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 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 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 plotComparison(histo1, histo2, canvas, outname, label1, label2, verbose): h1, h2 = histo1, histo2 if not h1.Integral() and not h2.Integral(): return canvas.cd() canvas.Clear() h1.SetMarkerColor(r.kBlack) h2.SetMarkerColor(r.kRed) h1.SetMarkerStyle(r.kFullCircle) h2.SetMarkerStyle(r.kOpenCircle) h1.SetMaximum(1.1 * max([h.GetMaximum() for h in [h1, h2]])) h1.SetStats(0) h1.SetStats(0) h1.Draw() h2.Draw('same') ks = h1.KolmogorovTest(h2) if h2.Integral() and h1.Integral() else 0.0 leg = drawLegendWithDictKeys(canvas, { label1: h1, label2: h2, }, legWidth=0.35, legHeight=0.275) header = "%s : KS=%.3f" % (h1.GetName(), ks) leg.SetHeader(header) if ks < 0.05: print header canvas.Update() canvas.SaveAs(outname + '.png') if verbose: print "saving %s" % outname
def plotComparison(histo1, histo2, canvas, outname, label1, label2, verbose) : h1, h2 = histo1, histo2 if not h1.Integral() and not h2.Integral() : return canvas.cd() canvas.Clear() h1.SetMarkerColor(r.kBlack) h2.SetMarkerColor(r.kRed) h1.SetMarkerStyle(r.kFullCircle) h2.SetMarkerStyle(r.kOpenCircle) # h1.SetMaximum(1.1*max([h.GetMaximum() for h in [h1, h2]])) # h1.SetMinimum(0.5*max([h.GetMinimum() for h in [h1, h2]])) h1.SetMaximum(1.1) h1.SetMinimum(0.0) h1.SetStats(0) h1.SetStats(0) h1.Draw() h2.Draw('same') ks = h1.KolmogorovTest(h2) if h2.Integral() and h1.Integral() else 0.0 leg = drawLegendWithDictKeys(canvas, {label1 : h1, label2 : h2, }, legWidth=0.35, legHeight=0.275) header = "%s : KS=%.3f"%(h1.GetName(), ks) leg.SetHeader(header) if ks<0.05 : print header canvas.Update() canvas.SaveAs(outname+'.png') if verbose : print "saving %s"%outname
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 plotHistos(histos1=[], histos2=[], histosRatio=[], label1='label1', label2='label2', canvas=None, canPrefix='', scaleXlabelsBot=1.0, colors={}, markers={},lineStyle1=1, lineStyle2=2, splitFraction=0.80) : "Assume again that the histos are in dict[sample]" can = canvas if canvas is not None else r.TCanvas(canPrefix+'percent_histos','') can.Clear() can.cd() padTop, padBot = getPad(can, splitFraction, top=True), getPad(can, splitFraction, bot=True) # top pad with ratios can.cd() padTop.Draw() padTop.cd() markersr = dict(zip(colors.keys(), len(colors.keys())*[r.kOpenDiamond])) for h in histosRatio.values() : yAx = h.GetYaxis() yAx.SetRangeUser(0.0, 2.0) yAx.SetNdivisions(-202) yAx.SetLabelSize(1.0/(1.0-splitFraction)*yAx.GetLabelSize()) h.SetTitle('') h.SetStats(0) #print 'fh: ',firstHisto(histos1).GetName(),' nratios :',len(histosRatio) # debug def bc(h) : return ["%.2f"%h.GetBinContent(b) for b in xrange(1, h.GetNbinsX()+1)] # print '\n'.join(["%s : %s"%(s, bc(h)) for s,h in histosRatio.iteritems()]) # debug draw(padTop, histosRatio, colors, markersr, asFirst=True) drawUnitLine(padTop, histosRatio) labelR = "%s/%s ratio"%(label1[0], label2[0]) drawLegendWithDictKeys(padTop, {label1 : firstHisto(histos1), label2 : firstHisto(histos2), labelR : firstHisto(histosRatio) }, legWidth=0.225, legHeight=0.75) # bot pad with histos can.cd() padBot.Draw() padBot.cd() markers1 = dict(zip(colors.keys(), len(colors.keys())*[r.kOpenTriangleUp])) markers2 = dict(zip(colors.keys(), len(colors.keys())*[r.kOpenTriangleDown])) for h in histos1.values()+histos2.values() : h.GetYaxis().SetRangeUser(0.0, 1.08) h.GetXaxis().SetLabelSize(scaleXlabelsBot*h.GetXaxis().GetLabelSize()) h.SetStats(0) draw(padBot, histos1, colors, markers1, lineStyle1) draw(padBot, histos2, colors, markers2, lineStyle2, asFirst=False) drawLegendWithDictKeys(padBot, histos1, legWidth=0.225) padBot.Update() return can
def plot(histos, var) : c = r.TCanvas('c_'+var,'') c.cd() pm = first(histos) pm.SetMaximum(1.1*max([h.GetMaximum() for h in histos.values()])) pm.Draw('axis') markers = dict(zip(histos.keys(), [r.kPlus, r.kCircle, r.kMultiply, r.kOpenSquare, r.kOpenTriangleUp, r.kOpenTriangleDown])) for s,h in histos.iteritems() : h.SetLineColor(colors[s] if s in colors else r.kBlack) h.SetMarkerColor(h.GetLineColor()) h.SetLineWidth(2*h.GetLineWidth()) h.SetMarkerStyle(markers[s]) h.Draw('same') leg = drawLegendWithDictKeys(c, histos) leg.Draw() c.Update() c.SaveAs(var+'.png')
def plot(histos, var): c = r.TCanvas('c_' + var, '') c.cd() pm = first(histos) pm.SetMaximum(1.1 * max([h.GetMaximum() for h in histos.values()])) pm.Draw('axis') markers = dict( zip(histos.keys(), [ r.kPlus, r.kCircle, r.kMultiply, r.kOpenSquare, r.kOpenTriangleUp, r.kOpenTriangleDown ])) for s, h in histos.iteritems(): h.SetLineColor(colors[s] if s in colors else r.kBlack) h.SetMarkerColor(h.GetLineColor()) h.SetLineWidth(2 * h.GetLineWidth()) h.SetMarkerStyle(markers[s]) h.Draw('same') leg = drawLegendWithDictKeys(c, histos) leg.Draw() c.Update() c.SaveAs(var + '.png')
def plotHistRatioAndFit(histos, ratio, fitfunc, outfname, graphics_attributes={}): can = r.TCanvas('can_' + outfname, outfname, 800, 600) botPad, topPad = buildBotTopPads(can, splitFraction=0.35) can.cd() topPad.Draw() topPad.cd() pm = first(histos) pm.Draw('axis') xAx, yAx = pm.GetXaxis(), pm.GetYaxis() xAx.SetTitle('') xAx.SetLabelSize(0) yAx.SetRangeUser(0.0, 1.2) yAx.SetNdivisions( 505) # for some reason some of the inputs are already ratios with -201 textScaleUp = 1.0 / topPad.GetHNDC() yAx.SetLabelSize(textScaleUp * 0.04) yAx.SetTitleSize(textScaleUp * 0.04) yAx.SetTitle(graphics_attributes['ytitle']) yAx.SetTitleOffset(yAx.GetTitleOffset() / textScaleUp) for k, h in histos.iteritems(): h.SetMarkerStyle(graphics_attributes['markers'][k]) h.SetMarkerColor(graphics_attributes['colors'][k]) h.SetLineColor(graphics_attributes['colors'][k]) h.Draw('same') labels = graphics_attributes['labels'] drawLegendWithDictKeys(topPad, dict([(labels[s], histos[s]) for s in histos.keys()]), legWidth=0.4) can.cd() botPad.Draw() botPad.cd() ratio.Draw('axis') textScaleUp = 1.0 / botPad.GetHNDC() xAx, yAx = ratio.GetXaxis(), ratio.GetYaxis() yAx.SetRangeUser(0.0, 2.0) xAx.SetTitle(graphics_attributes['xtitle']) yAx.SetNdivisions(-202) yAx.SetTitle('Data/Sim') yAx.CenterTitle() for a in [xAx, yAx]: if a.GetLabelSize() > 0.04: continue a.SetLabelSize(a.GetLabelSize() * textScaleUp) a.SetTitleSize(a.GetTitleSize() * textScaleUp) a.SetTitleOffset(a.GetTitleOffset() / textScaleUp) ratio.SetMarkerStyle(graphics_attributes['markers']['data']) fitfunc.SetLineWidth(2) fitfunc.SetLineStyle(2) fitfunc.Draw('same') ratio.Draw('same') tex = r.TLatex() tex.SetNDC(True) p0, p0Err, chi2, ndf = fitResults(fitfunc) fitParLabel = "Const. fit : %s #pm %s" % (pdgRound(p0, p0Err)) fitGoodLabel = "#chi^{2}/DOF : %.2f / %d" % (chi2, ndf) tex.SetTextSize(yAx.GetTitleSize()) tex.SetTextFont(yAx.GetTitleFont()) tex.DrawLatex(0.15, 0.40, "#splitline{%s}{%s}" % (fitParLabel, fitGoodLabel)) can.Update() outfname = outfname + '.png' rmIfExists(outfname) # avoid root warnings can.SaveAs(outfname)
def subtractRealAndComputeScaleFactor(histosPerGroup={}, variable='', outRatiohistoname='',outDataeffhistoname='', outputDir='./', region='', subtractReal=True, verbose=False): "efficiency scale factor" groups = histosPerGroup.keys() mkdirIfNeeded(outputDir) histosPerType = dict([(lt, dict([(g, histosPerGroup[g][variable][lt]) for g in groups])) for lt in leptonTypes]) for lt in leptonTypes : histosPerType[lt]['totSimBkg'] = summedHisto([histo for group,histo in histosPerType[lt].iteritems() if group not in ['data', 'signal']]) simuTight = histosPerType['fake_tight']['totSimBkg'] simuLoose = histosPerType['fake_loose']['totSimBkg'] dataTight = histosPerType['tight' ]['data' ] dataLoose = histosPerType['loose' ]['data' ] # subtract real contribution from data # _Note to self_: currently estimating the real contr from MC; in # the past also used iterative corr, which might be more # appropriate in cases like here, where the normalization is # so-so. Todo: investigate the normalization. dataSubTight = dataTight.Clone(dataTight.GetName().replace('data_tight','data_minus_prompt_tight')) dataSubLoose = dataLoose.Clone(dataLoose.GetName().replace('data_loose','data_minus_prompt_loose')) dataSubTight.SetDirectory(0) dataSubLoose.SetDirectory(0) dataSubTight.Add(histosPerType['real_tight']['totSimBkg'], -1.0 if subtractReal else 0.0) dataSubLoose.Add(histosPerType['real_loose']['totSimBkg'], -1.0 if subtractReal else 0.0) effData = dataSubTight.Clone(outDataeffhistoname) effData.SetDirectory(0) effData.Divide(dataSubLoose) effSimu = simuTight.Clone(simuTight.GetName().replace('fake_tight','fake_eff')) effSimu.SetDirectory(0) effSimu.Divide(simuLoose) print "eff(T|L) vs. ",variable def formatFloat(floats): return ["%.4f"%f for f in floats] print "efficiency data : ",formatFloat(getBinContents(effData)) print "efficiency simu : ",formatFloat(getBinContents(effSimu)) ratio = effData.Clone(outRatiohistoname) ratio.SetDirectory(0) ratio.Divide(effSimu) print "sf data/simu : ",formatFloat(getBinContents(ratio)) print " +/- : ",formatFloat(getBinErrors(ratio)) can = r.TCanvas('c_'+outRatiohistoname, outRatiohistoname, 800, 600) botPad, topPad = rootUtils.buildBotTopPads(can) can.cd() topPad.Draw() topPad.cd() pm = effData pm.SetStats(0) pm.Draw('axis') xAx, yAx = pm.GetXaxis(), pm.GetYaxis() xAx.SetTitle('') xAx.SetLabelSize(0) yAx.SetRangeUser(0.0, 0.25) textScaleUp = 1.0/topPad.GetHNDC() yAx.SetLabelSize(textScaleUp*0.04) yAx.SetTitleSize(textScaleUp*0.04) yAx.SetTitle('#epsilon(T|L)') yAx.SetTitleOffset(yAx.GetTitleOffset()/textScaleUp) effSimu.SetLineColor(r.kRed) effSimu.SetMarkerStyle(r.kOpenCross) effSimu.SetMarkerColor(effSimu.GetLineColor()) effData.Draw('same') effSimu.Draw('same') leg = drawLegendWithDictKeys(topPad, {'data':effData, 'simulation':simuTight}, legWidth=0.4) leg.SetHeader('scale factor '+region+' '+('electron' if '_el_'in outRatiohistoname else 'muon' if '_mu_' in outRatiohistoname else '')) can.cd() botPad.Draw() botPad.cd() ratio.SetStats(0) ratio.Draw() textScaleUp = 1.0/botPad.GetHNDC() xAx, yAx = ratio.GetXaxis(), ratio.GetYaxis() yAx.SetRangeUser(0.0, 2.0) xAx.SetTitle({'pt1':'p_{T}', 'eta1':'|#eta|', 'pt1_eta1':'p_{T}'}[variable]) yAx.SetNdivisions(-202) yAx.SetTitle('Data/Sim') yAx.CenterTitle() xAx.SetLabelSize(textScaleUp*0.04) xAx.SetTitleSize(textScaleUp*0.04) yAx.SetLabelSize(textScaleUp*0.04) yAx.SetTitleSize(textScaleUp*0.04) refLine = rootUtils.referenceLine(xAx.GetXmin(), xAx.GetXmax()) refLine.Draw() can.Update() outFname = os.path.join(outputDir, region+'_'+outRatiohistoname) for ext in ['.eps','.png']: utils.rmIfExists(outFname+ext) can.SaveAs(outFname+ext) return {outRatiohistoname : ratio, outDataeffhistoname : effData, outDataeffhistoname.replace('_fake_rate_data_', '_tight_data_minus_prompt') : dataSubTight, outDataeffhistoname.replace('_fake_rate_data_', '_loose_data_minus_prompt') : dataSubLoose }
def plotStackedHistos(histosPerGroup={}, outputDir='', region='', verbose=False): groups = histosPerGroup.keys() variables = first(histosPerGroup).keys() leptonTypes = first(first(histosPerGroup)).keys() colors = getGroupColor() 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 g not in ['data', 'signal']]) totBkg = summedHisto(bkgHistos.values()) err_band = None # 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]) # fixme with err_band yMin, yMax = 0.0, data.GetMaximum() 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') drawLegendWithDictKeys(can, bkgHistos, 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 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 subtractRealAndComputeScaleFactor(histosPerGroup={}, variable='', outRatiohistoname='', outDataeffhistoname='', outputDir='./', region='', subtractReal=True, verbose=False): "efficiency scale factor" groups = histosPerGroup.keys() mkdirIfNeeded(outputDir) histosPerType = dict([(lt, dict([(g, histosPerGroup[g][variable][lt]) for g in groups])) for lt in leptonTypes]) for lt in leptonTypes: histosPerType[lt]['totSimBkg'] = summedHisto([ histo for group, histo in histosPerType[lt].iteritems() if group not in ['data', 'signal'] ]) simuTight = histosPerType['fake_tight']['totSimBkg'] simuLoose = histosPerType['fake_loose']['totSimBkg'] dataTight = histosPerType['tight']['data'] dataLoose = histosPerType['loose']['data'] # subtract real contribution from data # _Note to self_: currently estimating the real contr from MC; in # the past also used iterative corr, which might be more # appropriate in cases like here, where the normalization is # so-so. Todo: investigate the normalization. dataSubTight = dataTight.Clone(dataTight.GetName().replace( 'data_tight', 'data_minus_prompt_tight')) dataSubLoose = dataLoose.Clone(dataLoose.GetName().replace( 'data_loose', 'data_minus_prompt_loose')) dataSubTight.SetDirectory(0) dataSubLoose.SetDirectory(0) dataSubTight.Add(histosPerType['real_tight']['totSimBkg'], -1.0 if subtractReal else 0.0) dataSubLoose.Add(histosPerType['real_loose']['totSimBkg'], -1.0 if subtractReal else 0.0) effData = dataSubTight.Clone(outDataeffhistoname) effData.SetDirectory(0) effData.Divide(dataSubLoose) effSimu = simuTight.Clone(simuTight.GetName().replace( 'fake_tight', 'fake_eff')) effSimu.SetDirectory(0) effSimu.Divide(simuLoose) print "eff(T|L) vs. ", variable def formatFloat(floats): return ["%.4f" % f for f in floats] print "efficiency data : ", formatFloat(getBinContents(effData)) print "efficiency simu : ", formatFloat(getBinContents(effSimu)) ratio = effData.Clone(outRatiohistoname) ratio.SetDirectory(0) ratio.Divide(effSimu) print "sf data/simu : ", formatFloat(getBinContents(ratio)) print " +/- : ", formatFloat(getBinErrors(ratio)) can = r.TCanvas('c_' + outRatiohistoname, outRatiohistoname, 800, 600) botPad, topPad = rootUtils.buildBotTopPads(can) can.cd() topPad.Draw() topPad.cd() pm = effData pm.SetStats(0) pm.Draw('axis') xAx, yAx = pm.GetXaxis(), pm.GetYaxis() xAx.SetTitle('') xAx.SetLabelSize(0) yAx.SetRangeUser(0.0, 0.25) textScaleUp = 1.0 / topPad.GetHNDC() yAx.SetLabelSize(textScaleUp * 0.04) yAx.SetTitleSize(textScaleUp * 0.04) yAx.SetTitle('#epsilon(T|L)') yAx.SetTitleOffset(yAx.GetTitleOffset() / textScaleUp) effSimu.SetLineColor(r.kRed) effSimu.SetMarkerStyle(r.kOpenCross) effSimu.SetMarkerColor(effSimu.GetLineColor()) effData.Draw('same') effSimu.Draw('same') leg = drawLegendWithDictKeys(topPad, { 'data': effData, 'simulation': simuTight }, legWidth=0.4) leg.SetHeader('scale factor ' + region + ' ' + ('electron' if '_el_' in outRatiohistoname else 'muon' if '_mu_' in outRatiohistoname else '')) can.cd() botPad.Draw() botPad.cd() ratio.SetStats(0) ratio.Draw() textScaleUp = 1.0 / botPad.GetHNDC() xAx, yAx = ratio.GetXaxis(), ratio.GetYaxis() yAx.SetRangeUser(0.0, 2.0) xAx.SetTitle({ 'pt1': 'p_{T}', 'eta1': '|#eta|', 'pt1_eta1': 'p_{T}' }[variable]) yAx.SetNdivisions(-202) yAx.SetTitle('Data/Sim') yAx.CenterTitle() xAx.SetLabelSize(textScaleUp * 0.04) xAx.SetTitleSize(textScaleUp * 0.04) yAx.SetLabelSize(textScaleUp * 0.04) yAx.SetTitleSize(textScaleUp * 0.04) refLine = rootUtils.referenceLine(xAx.GetXmin(), xAx.GetXmax()) refLine.Draw() can.Update() outFname = os.path.join(outputDir, region + '_' + outRatiohistoname) for ext in ['.eps', '.png']: utils.rmIfExists(outFname + ext) can.SaveAs(outFname + ext) return { outRatiohistoname: ratio, outDataeffhistoname: effData, outDataeffhistoname.replace('_fake_rate_data_', '_tight_data_minus_prompt'): dataSubTight, outDataeffhistoname.replace('_fake_rate_data_', '_loose_data_minus_prompt'): dataSubLoose }