def havesamebins(hist1, hist2, **kwargs): """Compare bins of x axes between two TH1 or TGraph objects.""" verbosity = LOG.getverbosity(kwargs) errorX = kwargs.get('errorX', gStyle.GetErrorX()) if isinstance(hist1, TH1) and isinstance(hist2, TH1): if hist1.GetXaxis().IsVariableBinSize() or hist2.GetXaxis( ).IsVariableBinSize(): xbins1 = hist1.GetXaxis().GetXbins() xbins2 = hist2.GetXaxis().GetXbins() if xbins1.GetSize() != xbins2.GetSize(): return False for i in xrange(xbins1.GetSize()): #print xbins1[i] if xbins1[i] != xbins2[i]: return False return True else: return hist1.GetXaxis().GetXmin()==hist2.GetXaxis().GetXmin() and\ hist1.GetXaxis().GetXmax()==hist2.GetXaxis().GetXmax() and\ hist1.GetXaxis().GetNbins()==hist2.GetXaxis().GetNbins() else: # one is TGraph ? bins1 = getbinedges(hist1) bins2 = getbinedges(hist2) if bins1 != bins2 and errorX <= 0: # only look at bin center bins1 = [(a + b) / 2 for a, b in bins1] bins2 = [(a + b) / 2 for a, b in bins2] if bins1 != bins2: print "bins1 =", bins1 print "bins2 =", bins2 return bins1 == bins2
def getgraphratio(graphnum,histden,**kwargs): """Make the ratio of a TGraph with a TH1 object on a bin-by-bin basis.""" verbosity = LOG.getverbosity(kwargs) hname = "ratio_%s-%s"%(graphnum.GetName() or 'graph',histden.GetName()) hname = kwargs.get('name', hname ) tag = kwargs.get('tag', "" ) eval = kwargs.get('eval', False ) # use interpolation yinf = kwargs.get('yinf', 1e12 ) # if denominator is 0 zero = kwargs.get('zero', True ) # ratio=1 if both num and den bins are zero errorX = kwargs.get('errorX', gStyle.GetErrorX() ) # horizontal error bars #color = kwargs.get('color', None ) nbins = histden.GetXaxis().GetNbins() if tag: hname += tag rgraph = graphnum.__class__() rgraph.SetName(hname) copystyle(rgraph,graphnum) xpoints = list(graphnum.GetX()) ypoints = list(graphnum.GetY()) ir = 0 # index ratio graph LOG.verb("getgraphratio: Making ratio of %s w.r.t. %s"%(graphnum,histden),verbosity,2) TAB = LOG.table("%4s %9s %9s %4s %9s %9s %4s %8s %-14s", "%4d %9.5g %9.2f %4d %9.5g %9.2f %4d %8.2f +%5.2f -%5.2f",verb=verbosity,level=3) TAB.printheader("ig","xval","yval","ibin","xval","yden","ig","ratio","error") if isinstance(histden,TH1): for ibin in range(0,nbins+2): xval = histden.GetXaxis().GetBinCenter(ibin) xerr = histden.GetXaxis().GetBinWidth(ibin)/2 if errorX else 0 yden = histden.GetBinContent(ibin) ig = -1 if eval: ynum = graphnum.Eval(xval) elif xval in xpoints: # assume points coincide with histogram bin centers ig = xpoints.index(xval) ynum = ypoints[ig] else: continue yerrupp = graphnum.GetErrorYhigh(ig) # -1 if graphnum is not TGraph(Asymm)Errors yerrlow = graphnum.GetErrorYlow(ig) # -1 if graphnum is not TGraph(Asymm)Errors ratio = 0.0 rerrupp = 0.0 rerrlow = 0.0 if yden!=0: ratio = ynum/yden rerrupp = yerrupp/yden rerrlow = yerrlow/yden elif zero: ratio = 1.0 if ynum==0 else yinf if ynum>0 else -yinf rgraph.SetPoint(ir,xval,ratio) if isinstance(rgraph,TGraphErrors): rgraph.SetPointError(ir,xerr,max(rerrupp,rerrlow)) elif isinstance(rgraph,TGraphAsymmErrors): rgraph.SetPointError(ir,xerr,xerr,rerrlow,rerrupp) TAB.printrow(ig,xval,ynum,ibin,xval,yden,ir,ratio,rerrupp,rerrlow) ir += 1 else: LOG.throw(IOError,"getgraphratio: Ratio between %s and %s not implemented..."%(graphnum,histden)) return rgraph
def gethistratio(histnum,histden,**kwargs): """Make the ratio of two TH1 histograms.""" verbosity = LOG.getverbosity(kwargs) hname = "ratio_%s-%s"%(histnum.GetName(),histden.GetName()) hname = kwargs.get('name', hname ) tag = kwargs.get('tag', "" ) yinf = kwargs.get('yinf', 1e12 ) # if denominator is 0 zero = kwargs.get('zero', True ) # ratio=1 if both num and den bins are zero errorX = kwargs.get('errorX', gStyle.GetErrorX() ) # horizontal error bars if tag: hname += tag if isinstance(histden,THStack): histden = histden.GetStack().Last() # should already have correct bin content and error if isinstance(histnum,THStack): histnum = histnum.GetStack().Last() rhist = histnum.Clone(hname) nbins = rhist.GetNcells() # GetNcells = GetNbinsX for TH1 LOG.verb("gethistratio: Making ratio of %s w.r.t. %s"%(histnum,histden),verbosity,2) if havesamebins(histden,histnum,errorX=errorX): # sanity check binning is the same; works for TH1 and TH2 #rhist.Divide(histden) TAB = LOG.table("%5d %9.3f %9.3f %9.3f %9.3f +- %7.3f",verb=verbosity,level=3) TAB.printheader("ibin","xval","yden","ynum","ratio","error") for ibin in xrange(0,nbins+2): yden = histden.GetBinContent(ibin) ynum = histnum.GetBinContent(ibin) enum = histnum.GetBinError(ibin) #max(histnum.GetBinErrorLow(ibin),histnum.GetBinErrorUp(ibin)) ratio = 0.0 erat = 0.0 if yden!=0: ratio = ynum/yden erat = enum/yden elif zero: ratio = 1. if ynum==0 else yinf if ynum>0 else -yinf TAB.printrow(ibin,rhist.GetXaxis().GetBinCenter(ibin),yden,ynum,ratio,erat) rhist.SetBinContent(ibin,ratio) rhist.SetBinError(ibin,erat) else: # works only for TH1 LOG.warning("gethistratio: %r and %r do not have the same bins..."%(histnum,histden)) TAB = LOG.table("%5d %9.3f %9.3f %5d %9.3f %9.3f %5d %8.3f +- %7.3f",verb=verbosity,level=3) TAB.printheader("iden","xval","yden","inum","xval","ynum","ratio","error") for iden in range(0,nbins+2): xval = histden.GetXaxis().GetBinCenter(iden) yden = histden.GetBinContent(iden) inum = histnum.GetXaxis().FindBin(xval) ynum = histnum.GetBinContent(inum) enum = histnum.GetBinError(inum) #max(histnum.GetBinErrorLow(inum),histnum.GetBinErrorUp(inum)) ratio = 0.0 erat = 0.0 if yden!=0: ratio = ynum/yden erat = enum/yden elif zero: ratio = 1.0 if ynum==0 else yinf if ynum>0 else -yinf TAB.printheader(iden,xval,yden,inum,histnum.GetXaxis().GetBinCenter(inum),ynum,ratio,erat) rhist.SetBinContent(iden,ratio) rhist.SetBinError(iden,erat) return rhist
def dividebybinsize(hist, **kwargs): """Divide each bin by its bin width. If a histogram has assymmetric errors (e.g. data with Poisson), return a TGraphAsymmErrors instead.""" verbosity = LOG.getverbosity(kwargs) LOG.verbose('dividebybinsize: "%s"' % (hist.GetName()), verbosity, 2) zero = kwargs.get('zero', True) # include bins that are zero in TGraph zeroerrs = kwargs.get('zeroerrs', True) # include errors for zero bins errorX = kwargs.get('errorX', gStyle.GetErrorX()) # horizontal error bars nbins = hist.GetXaxis().GetNbins() TAB = LOG.table("%5s %8.6g %8.6g %10.3f %9.4f %8.4f %8.4f %10.4f", verb=verbosity, level=3) TAB.printheader("ibin", "xval", "width", "yval", "yerr", "yupp", "ylow", "yerr/width") if hist.GetBinErrorOption( ) == TH1.kPoisson: # make asymmetric Poisson errors (like for data) graph = TGraphAsymmErrors() graph.SetName(hist.GetName() + "_graph") graph.SetTitle(hist.GetTitle()) copystyle(graph, hist) ip = 0 # skip zero bins if not zero for ibin in xrange(1, nbins + 1): xval = hist.GetXaxis().GetBinCenter(ibin) width = hist.GetXaxis().GetBinWidth(ibin) xerr = width / 2 if errorX else 0 yval = hist.GetBinContent(ibin) yerr = hist.GetBinError(ibin) yupp = hist.GetBinErrorUp(ibin) ylow = hist.GetBinErrorLow(ibin) TAB.printrow(ibin, xval, width, yval, yerr, yupp, ylow, yval / width) hist.SetBinContent(ibin, yval / width) hist.SetBinError(ibin, yerr / width) if yval != 0 or zero: graph.SetPoint(ip, xval, yval / width) if yval != 0 or zeroerrs: graph.SetPointError(ip, xerr, xerr, ylow / width, yupp / width) else: graph.SetPointError(ip, xerr, xerr, 0, 0) ip += 1 return graph else: for ibin in xrange(0, nbins + 2): xval = hist.GetXaxis().GetBinCenter(ibin) width = hist.GetXaxis().GetBinWidth(ibin) yval = hist.GetBinContent(ibin) yerr = hist.GetBinError(ibin) hist.SetBinContent(ibin, yval / width) hist.SetBinError(ibin, yerr / width) TAB.printrow(ibin, xval, width, yval, yerr, hist.GetBinErrorUp(ibin), hist.GetBinErrorLow(ibin), yval / width) return hist
def drawlegend(self, position=None, **kwargs): """Create and draw legend. Legend position can be controlled in several ways drawlegend(position) drawlegend(position=position) where position is a string which can contain the horizontal position, e.g. 'left', 'center', 'right', 'L', 'C', 'R', 'x=0.3', ... where 'x' is the position (between 0 an 1) of the left side in the frame. The position string can also contain the vertical position as e.g. 'top', 'middle', 'bottom', 'T', 'M', 'B', 'y=0.3', ... where 'y' is the position (between 0 an 1) of the top side in the frame. Instead of the strings, the exact legend coordinates can be controlled with the keywords x1, x2, y1 and y2, or, x1, y1, width and height: drawlegend(x1=0.2,width=0.4) drawlegend(x1=0.2,width=0.4,y1=0.9,height=0.4) drawlegend(x1=0.2,x2=0.6,y1=0.9,y2=0.4) These floats are normalized to the axis frame, ignoring the canvas margins: x=0 is the left, x=1 is the right, y=0 is the bottom and y=1 is the top side. Values less than 0, or larger than 1, will put the legend outside the frame. """ #if not ratio: # tsize *= 0.80 # signaltsize *= 0.80 verbosity = LOG.getverbosity(self, kwargs) hists = self.hists errstyle = 'lep' if gStyle.GetErrorX() else 'ep' entries = kwargs.get('entries', []) bands = kwargs.get('band', [self.errband]) # error bands bands = ensurelist(bands, nonzero=True) bandentries = kwargs.get('bandentries', []) title = kwargs.get('header', None) title = kwargs.get('title', title) # legend header/title latex = kwargs.get('latex', True) # automatically format strings as LaTeX style = kwargs.get('style', None) style0 = kwargs.get('style0', None) # style of first histogram errstyle = kwargs.get('errstyle', errstyle) # style for an error point styles = kwargs.get('styles', []) position = kwargs.get('pos', position) # legend position position = kwargs.get('position', position) or self.position option = kwargs.get('option', '') border = kwargs.get('border', False) transparent = kwargs.get('transparent', True) x1_user = kwargs.get('x1', None) # legend left side x2_user = kwargs.get('x2', None) # legend right side y1_user = kwargs.get('y1', None) # legend top side y2_user = kwargs.get('y2', None) # legend bottom side width = kwargs.get('width', -1) # legend width height = kwargs.get('height', -1) # legend height tsize = kwargs.get('tsize', _lsize) # text size twidth = kwargs.get('twidth', None) or 1 # scalefactor for legend width theight = kwargs.get('theight', None) or 1 # scalefactor for legend height texts = kwargs.get('text', []) # extra text below legend ncols = kwargs.get('ncols', self.ncols) or 1 # number of legend columns colsep = kwargs.get('colsep', 0.06) # seperation between legend columns bold = kwargs.get('bold', True) # bold legend header panel = kwargs.get('panel', 1) # panel (top=1, bottom=2) texts = ensurelist(texts, nonzero=True) entries = ensurelist(entries, nonzero=False) bandentries = ensurelist(bandentries, nonzero=True) headerfont = 62 if bold else 42 # CHECK LOG.insist(self.canvas, "Canvas does not exist!") self.canvas.cd(panel) scale = 485. / min(gPad.GetWh() * gPad.GetHNDC(), gPad.GetWw() * gPad.GetWNDC()) tsize *= scale # text size # ENTRIES #if len(bandentries)==len(bands) and len(entries)>len(hists): # for band, bandtitle in zip(band,bandentries): # entries.insert(hists.index(band),bandtitle) while len(entries) < len(hists): entries.append(hists[len(entries)].GetTitle()) while len(bandentries) < len(bands): bandentries.append(bands[len(bandentries)].GetTitle()) hists = hists + bands entries = entries + bandentries if latex: title = maketitle(title) entries = [maketitle(e) for e in entries] texts = [maketitle(t) for t in texts] maxlen = estimatelen([title] + entries + texts) # STYLES if style0: styles[0] = style0 while len(styles) < len(hists): hist = hists[len(styles)] if hist in bands: styles.append('f') elif style != None: styles.append(style) elif hasattr(hist, 'GetFillStyle') and hist.GetFillStyle() > 0: styles.append('f') elif 'E0' in hist.GetOption() or 'E1' in hist.GetOption(): styles.append(errstyle) else: styles.append('lp') # NUMBER of LINES nlines = sum([1 + e.count('\n') for e in entries]) #else: nlines += 0.80 if texts: nlines += sum([1 + t.count('\n') for t in texts]) if ncols > 1: nlines /= float(ncols) if title: nlines += 1 + title.count('\n') # DIMENSIONS if width < 0: width = twidth * max(0.22, min(0.60, 0.036 + 0.016 * maxlen)) if height < 0: height = theight * 1.34 * tsize * nlines if ncols > 1: width *= ncols / (1 - colsep) x2 = 0.90 x1 = x2 - width y1 = 0.92 y2 = y1 - height # POSITION if position == None: position = "" position = position.replace('left', 'L').replace( 'center', 'C').replace('right', 'R').replace( #.lower() 'top', 'T').replace('middle', 'M').replace('bottom', 'B') if not any(c in position for c in 'TMBy'): # set default vertical position += 'T' if not any(c in position for c in 'LCRx'): # set default horizontal position += 'RR' if ncols > 1 else 'R' # if title else 'L' if 'C' in position: if 'R' in position: center = 0.57 elif 'L' in position: center = 0.43 else: center = 0.50 x1 = center - width / 2 x2 = center + width / 2 elif 'LL' in position: x1 = 0.03 x2 = x1 + width elif 'L' in position: x1 = 0.08 x2 = x1 + width elif 'RR' in position: x2 = 0.97 x1 = x2 - width elif 'R' in position: x2 = 0.92 x1 = x2 - width elif 'x=' in position: x1 = float(re.findall(r"x=(\d\.\d+)", position)[0]) x2 = x1 + width if 'M' in position: if 'T' in position: middle = 0.57 elif 'B' in position: middle = 0.43 else: middle = 0.50 y1 = middle - height / 2 y2 = middle + height / 2 elif 'TT' in position: y2 = 0.97 y1 = y2 - height elif 'T' in position: y2 = 0.92 y1 = y2 - height elif 'BB' in position: y1 = 0.03 y2 = y1 + height elif 'B' in position: y1 = 0.08 y2 = y1 + height elif 'y=' in position: y2 = float(re.findall(r"y=(\d\.\d+)", position)[0]) y1 = y2 - height if x1_user != None: x1 = x1_user x2 = x1 + width if x2_user == None else x2_user if y1_user != None: y1 = y1_user y2 = y1 - height if y2_user == None else y2_user L, R = gPad.GetLeftMargin(), gPad.GetRightMargin() T, B = gPad.GetTopMargin(), gPad.GetBottomMargin() X1, X2 = L + (1 - L - R) * x1, L + ( 1 - L - R) * x2 # convert frame to canvas coordinates Y1, Y2 = B + (1 - T - B) * y1, B + ( 1 - T - B) * y2 # convert frame to canvas coordinates legend = TLegend(X1, Y1, X2, Y2) LOG.verb( "Plot.drawlegend: position=%r, height=%.3f, width=%.3f, (x1,y1,x2,y2)=(%.2f,%.2f,%.2f,%.2f), (X1,Y1,X2,Y2)=(%.2f,%.2f,%.2f,%.2f)" % (position, height, width, x1, y1, x2, y2, X1, Y1, X2, Y2), verbosity, 1) # MARGIN if ncols >= 2: margin = 0.090 / width else: margin = 0.044 / width legend.SetMargin(margin) # STYLE if transparent: legend.SetFillStyle(0) # 0 = transparent else: legend.SetFillColor(0) legend.SetBorderSize(border) legend.SetTextSize(tsize) legend.SetTextFont(headerfont) # bold for title if ncols > 1: legend.SetNColumns(ncols) legend.SetColumnSeparation(colsep) # HEADER if title: legend.SetHeader(title) legend.SetTextFont(42) # no bold for entries # ENTRIES if hists: for hist1, entry1, style1 in columnize(zip(hists, entries, styles), ncols): for entry in entry1.split('\n'): legend.AddEntry(hist1, entry, style1) hist1, style1 = 0, '' for line in texts: legend.AddEntry(0, line, '') if verbosity >= 2: print ">>> Plot.drawlegend: title=%r, texts=%s, latex=%s" % ( title, texts, latex) print ">>> Plot.drawlegend: hists=%s" % (hists) print ">>> Plot.drawlegend: entries=%s" % (entries) print ">>> Plot.drawlegend: styles=%s" % (styles) print ">>> Plot.drawlegend: nlines=%s, len(hists)=%s, len(texts)=%s, ncols=%s, margin=%s" % ( nlines, len(hists), len(texts), ncols, margin) legend.Draw(option) self.legends.append(legend) return legend
def __init__(self, histden, *histnums, **kwargs): """Make a ratio of two histograms bin by bin. Second hist may be a stack, to do data / MC stack.""" verbosity = LOG.getverbosity(kwargs) self.ratios = [] self.errband = None self.title = kwargs.get('title', "ratio") self.line = kwargs.get('line', True) self.drawzero = kwargs.get('drawzero', True) # draw ratio of two zero bins as 1 self.garbage = [] errband = kwargs.get('errband', None) # error band (e.g. stat. and/or sys. unc.) option = kwargs.get('option', "") denom = kwargs.get('denom', None) # histogram as denominator (count from 1) errorX = kwargs.get('errorX', gStyle.GetErrorX()) # horizontal error bars histnums = unwraplistargs(histnums) # SETUP NUMERATOR/DENOMINATOR if len(histnums) == 0: LOG.warning("Ratio.init: No histogram to compare with!") elif denom not in [0, 1, None]: # change denominator histogram histnums.insert(0, histden) if denom > 1: denom = min(max(0, denom - 1), len(histnums) - 1) elif abs(denom) > len(histnums): denom = 0 histden = histnums[denom] histnums.remove(histden) if isinstance(histden, THStack): histden = histden.GetStack().Last( ) # should have correct bin content and error #elif isinstance(histden,TGraph): # LOG.error("Ratio.init: TGraph not implemented") #elif isinstance(histden,TProfile): # histtemp = histden.ProjectionX(histden.GetName()+"_px",'E') # copystyle(histtemp,histden) # histden = histtemp # self.garbage.append(histtemp) LOG.verb( "Ratio.init: denom=%s, histden=%s, histnums=%s, errband=%s" % (denom, histden, histnums, errband), verbosity, 2) # MAKE RATIOS for i, histnum in enumerate(histnums): tag = str(i) if isinstance(histnum, TH1) or isinstance(histnum, THStack): ratio = gethistratio(histnum, histden, tag=tag, drawzero=self.drawzero, errorX=errorX) elif isinstance(histnum, TGraph): LOG.warning( "Ratio.init: TGraph ratio not validated! Please check verbose output..." ) ratio = getgraphratio(histnum, histden, tag=tag, drawzero=self.drawzero, errorX=errorX) #elif isinstance(hist,TProfile): # histtemp = hist.ProjectionX(hist.GetName()+"_projx",'E') # copystyle(histtemp,hist) # hist = histtemp # self.garbage.append(histtemp) #if isinstance(hist,TH1) and 'h' in option.lower(): # ratio = hist.Clone("ratio_%s-%s_%d"%(histden.GetName(),hist.GetName(),i)) # ratio.Reset() #else: # ratio = TGraphAsymmErrors() # copystyle(ratio,hist) # ratio.SetName("ratio_%s-%s_%d"%(histden.GetName(),hist.GetName(),i)) # ratio.SetTitle(self.title) copystyle(ratio, histnum) ratio.SetFillStyle(0) self.ratios.append(ratio) # MAKE ERROR BAND RATIO if isinstance(errband, TGraphAsymmErrors): self.errband = getgraphratio(errband, histden, errorX=True) copystyle(self.errband, errband) #seterrorbandstyle(self.errband,style='hatched',color=errband.GetFillColor()) self.histden = histden self.frame = self.histden.Clone("frame_ratio_%s" % (self.histden.GetName())) self.frame.Reset() # make empty self.frame.SetLineColor(0) self.frame.SetLineWidth(0) self.frame.SetMarkerSize(0)
def draw2DdeltaRHist(hist, c): c.Clear() c.cd() gStyle.SetOptTitle(0) txtSize = 0.028 margin = 0.08 histpad_sizeX = 0.6 histpad_sizeY = 0.7 hist_pad = ROOT.TPad(c.GetName() + "_hist", "subpad", margin, margin, histpad_sizeX + margin, histpad_sizeY + margin, c.GetFillColor()) hist_pad.SetMargin(0., 0., 0., 0.) hist_pad.Draw() xprojection_pad = ROOT.TPad(c.GetName() + "_xprojection", "subpad", margin, histpad_sizeY + margin, histpad_sizeX + margin, 1 - margin, c.GetFillColor()) xprojection_pad.SetMargin(0., 0., 0., 0.) xprojection_pad.Draw() yprojection_pad = ROOT.TPad(c.GetName() + "_yprojection", "subpad", histpad_sizeX + margin, margin, 1 - 2.5 * margin, histpad_sizeY + margin, c.GetFillColor()) yprojection_pad.SetMargin(0., 0., 0., 0.) yprojection_pad.Draw() hist.Sumw2() hist.Scale(1. / hist.Integral()) xprojection_hist = hist.ProjectionX(hist.GetName(), 1, hist.GetNbinsY(), "e") xprojection = ROOT.TGraphErrors(xprojection_hist) xprojection.SetLineColor(ROOT.kBlack) xprojection.SetMarkerColor(ROOT.kBlack) yprojection_hist = hist.ProjectionY(hist.GetName(), 1, hist.GetNbinsX(), "e") yprojection = ROOT.TGraphErrors(yprojection_hist.GetXaxis().GetNbins()) yprojection.SetName(yprojection_hist.GetName() + "_graph") yproj_xaxis = yprojection_hist.GetXaxis() for i in range(0, yprojection_hist.GetXaxis().GetNbins()): bin = yproj_xaxis.GetBinCenter(i + 1) width = yprojection_hist.GetBinWidth(i + 1) * gStyle.GetErrorX() count = yprojection_hist.GetBinContent(i + 1) err = yprojection_hist.GetBinError(i + 1) yprojection.SetPoint(i, count, bin) yprojection.SetPointError(i, err, width) # Draw 2D hist hist_pad.cd() hist.Draw("col") gPad.SetLogz() hist.GetXaxis().SetTitle("d#eta(reco-gen)") hist.GetYaxis().SetTitle("d#phi(reco-gen)") hist.GetYaxis().SetTitleOffset(1.4) # Fit hist shape = ROOT.TF2( "2dshape", "[0]*TMath::Exp(-[2]*(x[0]-[1])**2-[4]*(x[1]-[3])**2-2*[5]*(x[0]-[1])*(x[1]-[3]))", -0.05, 0.05, -0.05, 0.05) shape.SetParameters(0.003, 0., 3.769e4, 0., 4.215e4, -1.763e4) hist.Fit(shape, "n") max_ = shape.GetParameter(0) contours = array('d', []) contours.append(max_ * ROOT.TMath.Exp(-4.5)) contours.append(max_ * ROOT.TMath.Exp(-2)) contours.append(max_ * ROOT.TMath.Exp(-0.5)) shape.SetContour(3, contours) shape.SetNpx(100) shape.SetNpy(100) shape.SetLineWidth(2) shape.SetLineColor(ROOT.kBlack) shape.Draw("cont3 same") # One crystal box crystalBox = ROOT.TBox(-0.0173 / 2, -0.0173 / 2, 0.0173 / 2, 0.0173 / 2) crystalBox.SetLineStyle(3) crystalBox.SetLineColor(13) crystalBox.SetLineWidth(2) crystalBox.SetFillStyle(0) crystalBox.Draw() # Draw x projection xprojection_pad.cd() xprojection.Draw("apez") xprojection.GetYaxis().SetNdivisions(0) xprojection.GetXaxis().SetRangeUser( hist.GetXaxis().GetBinLowEdge(1), hist.GetXaxis().GetBinUpEdge(hist.GetXaxis().GetNbins())) xprojection.GetXaxis().SetLabelSize(0.) xprojection.GetYaxis().SetRangeUser(0., 0.22) shapeprojX = ROOT.TF1( "shapeprojX", "[0]*TMath::Sqrt(([2]*[4]-[5]**2)/(TMath::Pi()*[2]))*exp(([5]**2-[2]*[4])*(x-[3])**2/[2])", -0.05, 0.05) shapeprojX.SetParameters(shape.GetParameters()) shapeprojX.SetParameter(0, shape.GetParameter(0) / 20) shapeprojX.SetLineWidth(2) shapeprojX.SetNpx(100) shapeprojX.SetLineColor(ROOT.kRed) shapeprojX.Draw("same") # Draw y projection yprojection_pad.cd() yprojection.Draw("apez") yprojection.GetXaxis().SetNdivisions(0) yprojection.GetXaxis().SetRangeUser(0., 0.2) yprojection.GetYaxis().SetRangeUser( hist.GetYaxis().GetBinLowEdge(1), hist.GetYaxis().GetBinUpEdge(hist.GetYaxis().GetNbins())) yprojection.GetYaxis().SetLabelSize(0.) shapeprojY = ROOT.TF1( "shapeprojY", "[0]*TMath::Sqrt(([2]*[4]-[5]**2)/(TMath::Pi()*[4]))*exp(([5]**2-[2]*[4])*(x-[1])**2/[4])", -0.05, 0.05) shapeprojY.SetParameters(shape.GetParameters()) shapeprojY.SetParameter(0, shape.GetParameter(0) / 20) shapeprojYpos = array('d', []) shapeprojYval = array('d', []) for i in range(0, 101): shapeprojYpos.append(1e-3 * i - 0.05) shapeprojYval.append(shapeprojY.Eval(shapeprojYpos[i])) shapeprojYLine = ROOT.TGraph(101, shapeprojYval, shapeprojYpos) shapeprojYLine.SetLineColor(ROOT.kRed) shapeprojYLine.SetLineWidth(2) shapeprojYLine.Draw("l") # Draw Title c.cd() if c.GetTitle() != '': title = ROOT.TLatex(margin, 1 - margin + 0.01, "Crystal-level EG Trigger #DeltaR Distribution") title.SetTextSize(0.04) title.SetTextFont(42) title.SetNDC() title.Draw() # CMS info string cmsString = ROOT.TLatex(histpad_sizeX + margin - 0.005, 1 - margin - 0.005, "CMS Simulation, <PU>=200 bx=25, Single Electron") #"CMS Simulation, <PU>=200 bx=25, Single Photon") cmsString.SetTextFont(42) cmsString.SetTextSize(0.02) cmsString.SetNDC(1) cmsString.SetTextAlign(33) cmsString.Draw() # Stats stats = [] stats.append( ROOT.TLatex(histpad_sizeX + margin + 0.01, histpad_sizeY + margin + 0.13, "#mu_#eta = " + format(shape.GetParameter(1), '.2g'))) stats.append( ROOT.TLatex(histpad_sizeX + margin + 0.01, histpad_sizeY + margin + 0.1, "#mu_#phi = " + format(shape.GetParameter(3), '.2g'))) stats.append( ROOT.TLatex( histpad_sizeX + margin + 0.01, histpad_sizeY + margin + 0.07, "#sigma_#eta#eta = " + format(ROOT.TMath.Sqrt(0.5 / shape.GetParameter(2)), '.2g'))) stats.append( ROOT.TLatex( histpad_sizeX + margin + 0.01, histpad_sizeY + margin + 0.04, "#sigma_#phi#phi = " + format(ROOT.TMath.Sqrt(0.5 / shape.GetParameter(4)), '.2g'))) stats.append( ROOT.TLatex( histpad_sizeX + margin + 0.01, histpad_sizeY + margin + 0.01, "#sigma_#eta#phi = " + format(ROOT.TMath.Sqrt(-0.5 / shape.GetParameter(5)), '.2g'))) for i in range(0, 5): stats[i].SetTextSize(txtSize - 0.002) stats[i].SetTextFont(42) stats[i].SetNDC() stats[i].Draw() # Draw palette # (not working) gPad.Update() palette = ROOT.TPaletteAxis(1 - 2.5 * margin + 0.01, margin, 1 - 1.5 * margin, histpad_sizeY + margin, hist) hist.GetXaxis().SetTitleOffset(.8) hist.GetXaxis().SetLabelSize(txtSize * 1.35) hist.GetXaxis().SetTitleSize(txtSize * 2) hist.GetYaxis().SetTitleOffset(1.1) hist.GetYaxis().SetLabelSize(txtSize * 1.35) hist.GetYaxis().SetTitleSize(txtSize * 2) hist.GetZaxis().SetTitleOffset(1.4) hist.GetZaxis().SetLabelSize(txtSize) hist.GetZaxis().SetTitleSize(txtSize) palette.Draw() #gPad.SetLogz() gPad.Modified() gPad.Update() c.Print(universalSaveDir + c.GetName() + ".png") #c.Print(universalSaveDir+c.GetName()+".pdf") gStyle.SetOptTitle(1)