示例#1
0
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
示例#2
0
文件: utils.py 项目: yihui-lai/TauFW
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
示例#3
0
文件: utils.py 项目: yihui-lai/TauFW
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
示例#4
0
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
示例#5
0
    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
示例#6
0
文件: Ratio.py 项目: yihui-lai/TauFW
    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)
示例#7
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)