Beispiel #1
0
def invertcharge(oldcuts, target='SS', **kwargs):
    """Help function to find, invert and replace charge selections."""
    verbosity = LOG.getverbosity(kwargs)
    oldcuts = getselstr(oldcuts)
    newcuts = oldcuts
    if oldcuts == "":
        newcuts = "q_1*q_2<0" if target == 'OS' else "q_1*q_2>0" if target == 'OS' else ""
    else:
        matchOS = re.findall(r"q_[12]\s*\*\s*q_[12]\s*<\s*0", oldcuts)
        matchSS = re.findall(r"q_[12]\s*\*\s*q_[12]\s*>\s*0", oldcuts)
        LOG.verbose("invertcharge: oldcuts=%r" % (oldcuts), verbosity, 2)
        LOG.verbose(
            "invertcharge: matchOS=%r, matchSS=%r" % (matchOS, matchSS),
            verbosity, 2)
        if (len(matchOS) + len(matchSS)) > 1:
            LOG.warning(
                'invertcharge: more than one charge match (%d OS, %d SS) in %r'
                % (len(matchOS), len(matchSS), oldcuts))
        if target == 'OS':
            for match in matchSS:
                newcuts = oldcuts.replace(match,
                                          "q_1*q_2<0")  # invert SS to OS
        elif target == 'SS':
            for match in matchOS:
                newcuts = oldcuts.replace(match,
                                          "q_1*q_2>0")  # invert OS to SS
        else:
            for match in matchOS:
                newcuts = oldcuts.replace(match, "")  # REMOVE
            for match in matchSS:
                newcuts = oldcuts.replace(match, "")  # REMOVE
        newcuts = cleanbool(newcuts)
    LOG.verbose('  %r\n>>>   -> %r %s\n>>>' % (oldcuts, newcuts, target),
                verbosity, 2)
    return newcuts
Beispiel #2
0
def joincuts(*cuts, **kwargs):
    """Joins selection strings and apply weight if needed."""
    verbosity = LOG.getverbosity(kwargs)
    cuts = [c for c in cuts if c and isinstance(c, str)]
    weight = kwargs.get('weight', False)
    if any('||' in c and not ('(' in c and ')' in c) for c in cuts):
        LOG.warning(
            'joincuts: Be careful with those "or" statements in %s! Not sure how to join...'
            % (cuts, ))
        for i, cut in enumerate(cuts):
            if '||' in cut and not ('(' in cut and ')' in cut):
                cuts[i] = "(%s)" % (cut)
    if weight:
        string = re.sub("\(.+\)", "", weight)
        if any(c in string for c in '=<>+-&|'):
            weight = "(%s)" % (weight)
    if cuts:
        cuts = " && ".join(cuts)
        if weight:
            string = re.sub("\(.+\)", "", cuts)
            cuts = "(%s)*%s" % (cuts, weight)
    elif weight:
        cuts = weight
    else:
        cuts = ""
    #print cuts
    return cuts
Beispiel #3
0
 def __init__(self, context_dict, *args, **kwargs):
     if not isinstance(context_dict, dict):
         LOG.warning("Context.init: No dictionary given!")
     self.context = context_dict
     self.default = args[0] if len(args) > 0 else context_dict.get(
         'default', None)
     self.regex = kwargs.get('regex', False)
Beispiel #4
0
def wrapvariable(*args,**kwargs):
  """Help function to wrap variable arguments into a Variable object."""
  if len(args)==4 or len(args)==5:
    return Variable(args) # (xvar,nxbins,xmin,xmax)
  elif len(args)==1 and isinstance(args[0],Variable):
    return args[0]
  LOG.warning('wrapvariable: Could not unwrap arguments "%s" to a Variable object. Returning None.'%args)
  return None
Beispiel #5
0
def stackinputs(file, variable, processes, **kwargs):
    """Stack histograms from ROOT file.
       file:       TFile or TDirectory object
       variable:  Variables object
       processes: list of strings (name of processes)
     e.g.
       stackinputs(file,variable,['ZTT','TTT','W','QCD','data_obs'])
  """
    text = kwargs.get('text', None)
    tag = kwargs.get('tag', "")
    groups = kwargs.get('group', [])  # e.g. [(['^TT','ST'],'Top')]
    dname = kwargs.get('dname', None)  # directory ('bin') name
    pname = kwargs.get('save', "stack$TAG.png")  # save as image file
    wname = kwargs.get('write', "stack$TAG")  # write to file
    style = kwargs.get('style', False)  # write style to file

    exphists = []
    datahist = None
    tdir = ensureTDirectory(file, dname, cd=True) if dname else file
    if style:
        gStyle.Write(
            'style',
            TH1.kOverwrite)  # write current TStyle object to reproduce plots
    for process in processes:
        hname = process
        hist = gethist(tdir, process, fatal=False, warn=False)
        if not hist:
            LOG.warning(
                "stackinputs: Could not find %r in %s. Skipping stacked plot..."
                % (process, tdir.GetPath()))
            return
        hist.SetDirectory(0)
        hist.SetLineColor(kBlack)
        hist.SetFillStyle(1001)  # assume fill color is already correct
        if process == 'data_obs':
            datahist = hist
        else:
            exphists.append(hist)
    for group in groups:
        grouphists(exphists, *group, replace=True, regex=True, verb=0)
    stack = Stack(variable, datahist, exphists)
    stack.draw()
    stack.drawlegend(ncols=2, twidth=0.9)
    if text:
        stack.drawtext(text)
    if pname:
        pname = repkey(pname, TAG=tag)
        stack.saveas(pname, ext=['png'])
    if wname:
        wname = repkey(wname, TAG=tag)
        stack.canvas.Write(wname, TH1.kOverwrite)
    stack.close()
Beispiel #6
0
def comparevars(file, variable, processes, systag, **kwargs):
    """Compare up/down variations of input histograms from ROOT file.
       file:      TFile or TDirectory object
       variable:  Variables object
       processes: list of strings (name of processes)
       systag:    string of systematic (file must contain up/down variation)
     e.g.
       comparevars(file,variable,['ZTT','TTT'],'TES')
  """
    text = kwargs.get('text', None)
    pname = kwargs.get('pname', "stack.png")
    tag = kwargs.get('tag', "")
    groups = kwargs.get('group', [])  # e.g. [(['^TT','ST'],'Top')]
    dname = kwargs.get('dname', None)  # directory ('bin') name
    pname = kwargs.get('save', "plot_$PROC$SYST$TAG.png")  # save as image file
    wname = kwargs.get('write', "plot_$PROC$SYST$TAG")  # write to file
    processes = ensurelist(processes)
    uptag = systag + "Up"
    downtag = systag + "Down"
    tdir = ensureTDirectory(file, dname, cd=True) if dname else file
    for process in processes:
        hists = []
        skip = False
        for var in [uptag, "", downtag]:
            hname = process + var
            hist = gethist(tdir, hname, fatal=False, warn=False)
            if not hist:
                skip = True
                break
            hists.append(hist)
        if skip:
            LOG.warning(
                "comparevars: Could not find %r in %s. Skipping shape comparison..."
                % (hname, tdir.GetPath()))
            continue
        plot = Plot(variable, hists)
        plot.draw(ratio=2, lstyle=1)
        plot.drawlegend()
        if text:
            plot.drawtext(text)
        if pname:
            pname_ = repkey(pname, PROC=process, TAG=tag)
            plot.saveas(pname_, ext=['png'])
        if wname:
            wname_ = repkey(wname, PROC=process, TAG=tag)
            plot.canvas.Write(wname_, TH1.kOverwrite)
        plot.close()
Beispiel #7
0
def shiftjetvars(var, jshift, **kwargs):
    """Shift all jet variable in a given string (e.g. to propagate JEC/JER)."""
    vars        = [r'mt_1',r'met(?!filter)'] if "unclusten" in jshift.lower() else\
                  [r'jpt_[12]',r'jeta_[12]',r'jets\w*',r'nc?btag\w*',r'mt_1',r'met(?!filter)',r'dphi_ll_bj']
    verbosity = LOG.getverbosity(kwargs)
    vars = kwargs.get('vars', vars)
    varshift = var[:]
    if re.search(r"(Up|Down)", var):
        LOG.warning("shiftjetvars: Already shifts in %r" % (var))
    if len(jshift) > 0 and jshift[0] != '_': jshift = '_' + jshift
    for jvar in vars:
        oldvarpattern = r'(' + jvar + r')'
        newvarpattern = r"\1%s" % (jshift)
        varshift = re.sub(oldvarpattern, newvarpattern, varshift)
    if verbosity > 0:
        print "shiftjetvars with %r shift" % varshift
        print ">>>   %r" % var
        print ">>>    -> %r" % jshift
    return varshift
Beispiel #8
0
    def getcontext(self, *args, **kwargs):
        """Get the contextual object for a set of ordered arguments. If it is not available, return Default."""

        regex = kwargs.get('regex', self.regex)

        # CHECK
        if len(args) == 0:
            LOG.warning("Context.getcontext: No arguments given!")
            return self.default
        if not self.context:
            LOG.warning("Context.getcontext: No context dictionary!")
            return None

        # MATCH
        ckey = args[0]
        if ckey.__class__.__name__ == 'Selection':
            ckey = ckey.selection
        result = None
        if regex:
            for key in sorted(self.context,
                              key=lambda x: len(x)
                              if isinstance(x, str) else 1,
                              reverse=True):
                #LOG.verbose('Context.getcontext: Matching "%s" to "%s"'%(key,ckey),True)
                if key == ckey or (isinstance(key, str) and isinstance(
                        ckey, str) and re.search(key, ckey)):
                    #LOG.verbose('Context.getcontext: Regex match of key "%s" to "%s"'%(key,ckey),True)
                    ckey = key
                    result = self.context[ckey]
                    break
            else:
                result = self.default  # TODO: check for multiple args !
        elif ckey not in self.context:
            result = self.default
        else:
            result = self.context[ckey]

        # RESULT
        if isinstance(result, Context):
            return result.getcontext(*args[1:], **kwargs)  # recursive
        elif len(args) > 1 and result == self.default:
            return self.getcontext(*args[1:], **kwargs)  # recursive
        return result
Beispiel #9
0
def makelatex(string, **kwargs):
    """Convert patterns in a string to LaTeX format."""
    global var_dict_sorted
    verbosity = LOG.getverbosity(kwargs)
    if not isinstance(string, str) or not string:
        return string
    if string and string[0] == '{' and string[-1] == '}':
        return string[1:-1]
    units = kwargs.get('units', True)
    split = kwargs.get('split', False)
    GeV = False
    cm = False
    oldstr = string

    # PREDEFINED
    if len(var_dict_sorted) != len(var_dict):
        var_dict_sorted = sorted(var_dict, key=lambda x: len(x), reverse=True)
    for var in var_dict_sorted:
        if var in string:
            string = string.replace(var, var_dict[var])
            #string = re.sub(r"\b%s\b"%var,var_dict[var],string,re.IGNORECASE)
            break

    # SPLIT LINE
    if split:
        while '\n' in string:
            string = "#splitline{%s}" % (string.replace('\n', '}{', 1))
        if 'splitline' not in string and len(string) > 30:
            part1 = string[:len(string) / 2]
            part2 = string[len(string) / 2:]
            if ' ' in part2:
                string = "#splitline{" + part1 + part2.replace(' ', '}{',
                                                               1) + "}"
            elif ' ' in part1:
                i = part1.rfind(' ')
                string = "#splitline{" + string[:i] + '}{' + string[i +
                                                                    1:] + "}"

    # REPLACE PATTERNS (RECURSIVELY)
    match = funcexpr.match(string)  # for min(), max(), ...
    if ' / ' in string:
        kwargs['units'] = False
        string = ' / '.join(
            makelatex(s, **kwargs) for s in string.split(' / '))
    elif match:
        kwargs['units'] = False
        func = makelatex(match.group(1), **kwargs)
        arg1 = makelatex(match.group(2), **kwargs)
        arg2 = makelatex(match.group(3), **kwargs)
        old = "%s(%s,%s)" % (match.group(1), match.group(2), match.group(3))
        new = "%s(%s,%s)" % (func, arg1, arg2)
        string = string.replace(old, new)
        #print ">>> %r -> %r, %r -> %r, %r -> %r, %r"%(match.group(2),arg1,match.group(3),arg2,old,new,string)
    elif '+' in string:
        kwargs['units'] = False
        string = '+'.join(makelatex(s, **kwargs) for s in string.split('+'))
    else:
        strlow = string.lower().strip()
        if "p_" in strlow:
            string = re.sub(r"(?<!i)(p)_([^{}()|<>=\ ]+)",
                            r"\1_{\2}",
                            string,
                            flags=re.IGNORECASE).replace('{t}', '{T}')
            GeV = True
        if re.search(r"(?<!le)(?<!byphoton)(?<!dee)pt(?!weight)",
                     strlow):  # pt
            string = re.sub(
                r"(?<!k)(?<!Dee)(?<!OverTau)(p)[tT]_([^{}()|<>=_\ ]+)",
                r"\1_{T}^{\2}",
                string,
                flags=re.IGNORECASE)
            string = re.sub(r"\b(?<!Dee)(p)[tT]\b",
                            r"\1_{T}",
                            string,
                            flags=re.IGNORECASE)
            GeV = True
        if strlow == "mt":
            string = re.sub(r"(m)(t)", r"\1_{T}", string, flags=re.IGNORECASE)
            GeV = True
        elif "m_" in strlow:
            string = re.sub(r"(?<!u)(m)_([^{}()|<>=\ \^]+)",
                            r"\1_{\2}",
                            string,
                            flags=re.IGNORECASE).replace('{t}', '{T}')
            GeV = True
        elif "mt_" in strlow:
            string = re.sub(r"(m)t_([^{}()|<>=\ ]+)",
                            r"\1_{T}^{\2}",
                            string,
                            flags=re.IGNORECASE)
            GeV = True
        if re.search(r"(?<!weig)(?<!daug)ht(?!au)", strlow):  # HT
            string = re.sub(r"\b(h)t\b",
                            r"\1_{T}",
                            string,
                            flags=re.IGNORECASE)
            GeV = True
        if strlow[0] == 's' and 't' in strlow[1:3]:  # scalar sum pT
            string = re.sub(r"s_?t(?!at)",
                            r"S_{T}",
                            string,
                            flags=re.IGNORECASE)
            string = re.sub(r"met", r"^{MET}", string, flags=re.IGNORECASE)
            GeV = True
        if " d_" in strlow:
            string = re.sub(r"(\ d)_([^{}()\|<>=\ ]+)",
                            r"\1_{\2}",
                            string,
                            flags=re.IGNORECASE)
            cm = True
        if "deltar_" in strlow:
            string = re.sub(r"(?<!\#)deltar_([^{}()|<>=\ ]+)",
                            r"#DeltaR_{\1}",
                            string,
                            flags=re.IGNORECASE)
        elif "deltar" in strlow:
            string = re.sub(r"(?<!\#)deltar",
                            r"#DeltaR",
                            string,
                            flags=re.IGNORECASE)
        elif "dr_" in strlow:
            string = re.sub(r"(?<!\w)dr_([^{}()|<>=\ ]+)",
                            r"#DeltaR_{\1}",
                            string,
                            flags=re.IGNORECASE)
        elif "dr" in strlow:
            string = re.sub(r"(?<![a-z])dr(?![a-z])",
                            r"#DeltaR",
                            string,
                            flags=re.IGNORECASE)
        if "chi" in strlow:
            string = re.sub(r"(?<!#)chi(?!ng)",
                            r"#chi",
                            string,
                            flags=re.IGNORECASE)
            string = re.sub(r"chi_([^{}()^|<>=\ ]+)",
                            r"chi_{\1}",
                            string,
                            flags=re.IGNORECASE)
        if "phi" in strlow:
            if "dphi" in strlow:
                string = string.replace("dphi", "#Delta#phi")
            else:
                string = string.replace("phi", "#phi")
            string = re.sub(r"phi_([^{}()|<>=\ ]+)",
                            r"phi_{\1}",
                            string,
                            flags=re.IGNORECASE)
        if "zeta" in strlow and "#zeta" not in strlow:
            if "Dzeta" in string:
                string = string.replace("Dzeta", "D_{zeta}")
                GeV = True
            if "zeta_" in strlow:
                string = re.sub(r"(?<!#)(zeta)_([^{}()|<>=\ ]+)",
                                r"#\1_{\2}",
                                string,
                                flags=re.IGNORECASE)
            else:
                string = re.sub(r"(?<!#)(zeta)",
                                r"#\1",
                                string,
                                flags=re.IGNORECASE)
            GeV = True
        if "eta" in strlow:  #and "#eta" not in strlow and "#zeta" not in strlow and "deta" not in strlow:
            string = string.replace("deta", "#Deltaeta")
            string = re.sub(r"(?<!\#[Bbz])eta", r"#eta", string)
            string = re.sub(r"eta_([^{}()|<>=\ ]+)", r"eta_{\1}", string)
        if "tau" in strlow:
            #string = re.sub(r"(?<!^)tau(?!\ )",r"#tau",string,re.IGNORECASE)
            string = re.sub(r"(?<!Deep)(?<!Over)tau",
                            r"#tau",
                            string,
                            flags=re.IGNORECASE)
            #string = re.sub(r" #tau ",r" tau ",string,flags=re.IGNORECASE)
            #string = re.sub(r"^#tau ",r"tau ",string,flags=re.IGNORECASE)
            string = re.sub(r"tau_([^{}()^|<>=\ ]+)",
                            r"tau_{\1}",
                            string,
                            flags=re.IGNORECASE)
            string = re.sub(r"#tauh", r"#tau_{h}", string, flags=re.IGNORECASE)
        if "abs(" in string and ")" in string:
            string = re.sub(r"abs\(([^)]+)\)", r"|\1|", string)
            #string = string.replace("abs(","|").replace(")","") + "|" # TODO: split at next space
        if "mu" in strlow:
            string = re.sub(r"(?<!VS)mu(?![lo])", r"#mu", string)
            #string = string.replace("mu","#mu").replace("Mu","#mu")
            #string = string.replace("si#mulation","simulation")
        if "nu" in strlow:
            string = re.sub(r"nu(?![pm])", r"#nu", string)
        if "ttbar" in strlow:
            string = re.sub(r"ttbar", "t#bar{t}", string, flags=re.IGNORECASE)
        if "npv" in strlow:
            string = re.sub(r"npvs?", "Number of primary vertices", string)
        if '->' in string:
            string = string.replace('->', '#rightarrow')
        if '=' in string:
            string = string.replace(">=", "#geq").replace("<=", "#leq")
        string = string.replace('##', '#')

    # UNITS
    if isinstance(units, str):
        if re.search(r"[(\[].*[)\]]", units):
            string += " " + units.strip()
        else:
            string += " [%s]" % units.strip()
    elif units and not '/' in string:
        if GeV or "mass" in string or "p_{T}" in string or "S_{T}" in string or (
                any(m in string.lower()
                    for m in ["met", "p_{t}^{miss}"]) and "phi" not in string):
            if "GeV" not in string:
                string += " [GeV]"
            if cm:
                LOG.warning("makelatex: Flagged units are both GeV and cm!")
        elif cm:  #or 'd_' in string
            string += " [cm]"
    if (verbosity >= 2 and string != oldstr) or verbosity >= 3:
        print ">>> makelatex: %r -> %r" % (oldstr, string)
    return string
Beispiel #10
0
def drawpostfit(fname, bin, procs, **kwargs):
    """Plot pre- and post-fit plots PostFitShapesFromWorkspace."""
    print '>>>\n>>> drawpostfit("%s","%s")' % (fname, bin)
    outdir = kwargs.get('outdir', "")
    pname = kwargs.get('pname',
                       "$FIT.png")  # replace $FIT = 'prefit', 'postfit'
    ratio = kwargs.get('ratio', True)
    tag = kwargs.get('tag', "")
    xtitle = kwargs.get('xtitle', None)
    title = kwargs.get('title', None)
    text = kwargs.get('text', "")
    tsize = kwargs.get('tsize', 0.050)
    xmin = kwargs.get('xmin', None)
    xmax = kwargs.get('xmax', None)
    ymargin = kwargs.get('ymargin', 1.22)
    groups = kwargs.get('group', [])
    position = kwargs.get('pos', None)  # legend position
    ncol = kwargs.get('ncol', None)  # legend columns
    square = kwargs.get('square', False)
    era = kwargs.get('era', "")
    exts = kwargs.get('exts', ['pdf', 'png'])  # figure extension
    ymax = None
    fits = ['prefit', 'postfit']
    file = ensureTFile(fname, 'READ')
    if outdir:
        ensuredir(outdir)
    if era:
        setera(era)

    # DRAW PRE-/POST-FIT
    for fit in fits:
        fitdirname = "%s_%s" % (bin, fit)
        dir = file.Get(fitdirname)
        if not dir:
            LOG.warning('drawpostfit: Did not find dir "%s"' % (fitdirname),
                        pre="   ")
            return
        obshist = None
        exphists = []

        # GET HIST
        for proc in procs:  #reversed(samples):
            hname = "%s/%s" % (fitdirname, proc)
            hist = file.Get(hname)
            if not hist:
                LOG.warning(
                    'drawpostfit: Could not find "%s" template in directory "%s_%s"'
                    % (proc, bin, fit),
                    pre="   ")
                continue
            if 'data_obs' in proc:
                obshist = hist
                hist.SetLineColor(1)
                ymax = hist.GetMaximum() * ymargin
            else:
                exphists.append(hist)
            if proc in STYLE.sample_titles:
                hist.SetTitle(STYLE.sample_titles[proc])
            if proc in STYLE.sample_colors:
                hist.SetFillStyle(1001)
                hist.SetFillColor(STYLE.sample_colors[proc])
        if len(exphists) == 0:
            LOG.warning(
                'drawpostfit: Could not find any templates in directory "%s"' %
                (bin),
                pre="   ")
            continue
        if not obshist:
            LOG.warning(
                'drawpostfit: Could not find a data template in directory "%s"'
                % (bin),
                pre="   ")
            continue
        for groupargs in groups:
            grouphists(exphists, *groupargs, replace=True)

        # PLOT
        xtitle = (xtitle or exphists[0].GetXaxis().GetTitle()
                  )  #.replace('[GeV]','(GeV)')
        xmax = xmax or exphists[0].GetXaxis().GetXmax()
        xmin = xmin or exphists[0].GetXaxis().GetXmin()
        errtitle = "Pre-fit stat. + syst. unc." if fit == 'prefit' else "Post-fit unc."
        pname_ = repkey(pname, FIT=fit, ERA=era)
        rmin, rmax = (0.28, 1.52)
        plot = Stack(xtitle, obshist, exphists)
        plot.draw(xmin=xmin,
                  xmax=xmax,
                  ymax=ymax,
                  square=square,
                  ratio=ratio,
                  rmin=rmin,
                  rmax=rmax,
                  staterror=True,
                  errtitle=errtitle)
        plot.drawlegend(position, tsize=tsize, text=text, ncol=ncol)
        if title:
            plot.drawtext(title, bold=False)
        plot.saveas(pname_, outdir=outdir, ext=exts)
        plot.close()

    file.Close()
Beispiel #11
0
def compare(fnames, variables, **kwargs):

    # SETTING
    tnames = kwargs.get('tree', [])
    entries = kwargs.get('entries', [])  # entries of files
    outdir = kwargs.get('outdir', "compare")
    tag = kwargs.get('tag', "")
    cut = kwargs.get('cut', "")
    norm = kwargs.get('norm', False)
    ensuredir(outdir)
    if isinstance(tnames, str):
        tnames = [tnames] * len(fnames)
    else:
        while len(tnames) < len(fnames):
            tnames.append(tnames[-1])
    if norm:
        tag += "_norm"  # normalize each histogram

    # GET FILES & TREES
    files = []
    trees = []
    for fname, tname in zip(fnames, tnames):
        file = TFile.Open(fname, 'READ')
        tree = file.Get(tname)
        files.append(file)
        trees.append(tree)
        for variable in variables[:]:
            if not hasattr(tree, variable.name):
                LOG.warning(
                    "compare: tree %s:%s does not contain branch %r! Skipping..."
                    % (fname, tname, variable.name))
                variables.remove(variable)
    while len(entries) < len(trees):
        i = len(entries)
        entry = "%s %d" % (tnames[i], i + 1)
        entries.append(entry)

    # PLOT
    for variable in variables:
        fname = "%s/%s%s.png" % (outdir, variable, tag)
        rrange = 0.5
        header = "Compare"  # legend header
        text = ""  # corner text
        ratio = True  #and False
        logy = True and False
        grid = True  #and False
        staterr = True  #and False # add uncertainty band to first histogram
        lstyle = 1  # solid lines
        LOG.header(fname)

        # GET HISOGRAMS
        hists = []
        for i, (tree, htitle) in enumerate(zip(trees, entries)):
            hname = "%s_%d" % (variable.filename, i)
            #hist   = variable.gethist(hname,htitle)
            #dcmd   = variable.drawcmd(hname)
            hist = variable.draw(
                tree, cut, name=hname,
                title=htitle)  # create and fill hist from tree
            evts = hist.GetEntries()
            hist.SetTitle("%s (%d)" % (htitle, evts))
            hists.append(hist)
            print ">>>   %r: entries=%d, integral=%s, mean=%#.6g, s.d.=%#.6g" % (
                htitle, evts, hist.Integral(), hist.GetMean(),
                hist.GetStdDev())

        # DRAW PLOT
        plot = Plot(variable, hists, norm=norm)
        plot.draw(ratio=True,
                  logy=logy,
                  ratiorange=rrange,
                  lstyle=lstyle,
                  grid=grid,
                  staterr=staterr)
        plot.drawlegend(header=header)
        plot.drawtext(text)
        plot.saveas(fname)
        plot.close()
        print
Beispiel #12
0
def plotinputs(fname, varprocs, observables, bins, **kwargs):
    """Plot histogram inputs from ROOT file for datacards, and write to ROOT file.
       fname:       filename pattern of ROOT file
       varprocs:    dictionary for systematic variation to list of processes,
                    e.g. { 'Nom':   ['ZTT','TTT','W','QCD','data_obs'],
                           'TESUp': ['ZTT','TTT'], 'TESDown': ['ZTT','TTT'] }
       observables: list of Variables objects
       bins:        list of Selection objects
  """
    #LOG.header("plotinputs")
    tag = kwargs.get('tag', "")
    pname = kwargs.get('pname', "$OBS_$BIN$TAG.png")
    outdir = kwargs.get('outdir', 'plots')
    text = kwargs.get('text', "$BIN")
    groups = kwargs.get('group',
                        [])  # add processes together into one histogram
    verbosity = kwargs.get('verb', 0)
    ensuredir(outdir)
    print ">>>\n>>> " + color(" plotting... ", 'magenta', bold=True, ul=True)
    if 'Nom' not in varprocs:
        LOG.warning(
            "plotinputs: Cannot make plots because did not find nominal process templates 'Nom'."
        )
        return
    if isinstance(
            varprocs['Nom'],
            Systematic):  # convert Systematic objects back to simple string
        systs = varprocs  # OrderedDict of Systematic objects
        varprocs = OrderedDict()
        for syskey, syst in systs.iteritems():
            if syskey.lower() == 'nom':
                varprocs['Nom'] = syst.procs
            else:
                varprocs[syst.up.lstrip('_')] = syst.procs
                varprocs[syst.dn.lstrip('_')] = syst.procs
    for obs in observables:
        obsname = obs.filename
        ftag = tag + obs.tag
        fname_ = repkey(fname, OBS=obsname, TAG=ftag)
        file = ensureTFile(fname_, 'UPDATE')
        for set, procs in varprocs.iteritems(
        ):  # loop over processes with variation
            if set == 'Nom':
                systag = ""  # no systematics tag for nominal
                procs_ = procs[:]
            else:
                systag = '_' + set  # systematics tag for variation, e.g. '_TESUp'
                procs_ = [
                    (p + systag if p in procs else p) for p in varprocs['Nom']
                ]  # add tag to varied processes
            for selection in bins:
                if not obs.plotfor(selection): continue
                obs.changecontext(selection)
                bin = selection.filename
                text_ = repkey(
                    text, BIN=selection.title)  # extra text in plot corner
                tdir = ensureTDirectory(file, bin,
                                        cd=True)  # directory with histograms
                if set == 'Nom':
                    gStyle.Write(
                        'style', TH1.kOverwrite
                    )  # write current TStyle object to reproduce plots

                # STACKS
                pname_ = repkey(pname, OBS=obsname, BIN=bin,
                                TAG=ftag + systag)  # image file name
                wname = "stack" + systag  # name in ROOT file
                stackinputs(tdir,
                            obs,
                            procs_,
                            group=groups,
                            save=pname_,
                            write=wname,
                            text=text_)

                # VARIATIONS
                if 'Down' in set:
                    systag_ = systag.replace(
                        'Down', '')  # e.g.'_TES' without 'Up' or 'Down' suffix
                    pname_ = repkey(pname,
                                    OBS=obsname,
                                    BIN=bin,
                                    TAG=ftag + "_$PROC" +
                                    systag_)  # image file name
                    wname = "plot_$PROC" + systag_  # name in ROOT file
                    comparevars(tdir,
                                obs,
                                procs,
                                systag_,
                                save=pname_,
                                write=wname,
                                text=text_)

        file.Close()
Beispiel #13
0
 def __init__(self, name, *args, **kwargs):
     strings = [a for a in args if isinstance(a, str)]
     self.name = name
     self.name_ = name  # backup for addoverflow
     self.title = strings[0] if strings else self.name
     self.filename = makefilename(self.name.replace('/', '_'))
     self.title = kwargs.get('title', self.title)  # for plot axes
     self.filename = kwargs.get('fname', self.filename)
     self.filename = kwargs.get('filename',
                                self.filename)  # name for files, histograms
     self.filename = self.filename.replace('$NAME', self.name).replace(
         '$VAR', self.name)  #.replace('$FILE',self.filename)
     self.tag = kwargs.get('tag', "")
     self.units = kwargs.get('units', True)  # for plot axes
     self.latex = kwargs.get('latex', True)  # for plot axes
     self.nbins = None
     self.min = None
     self.max = None
     self.bins = None
     self.cut = kwargs.get('cut', "")  # extra cut when filling histograms
     self.weight = kwargs.get(
         'weight', "")  # extra weight when filling histograms (MC only)
     self.dataweight = kwargs.get(
         'dataweight', "")  # extra weight when filling histograms for data
     self.setbins(*args)
     self.dividebins = kwargs.get('dividebins', self.hasvariablebins(
     ))  # divide each histogram bins by it bin size (done in Plot.draw)
     self.data = kwargs.get('data', True)  # also draw data
     self.flag = kwargs.get('flag', "")  # flag, e.g. 'up', 'down', ...
     self.binlabels = kwargs.get('labels', [])  # bin labels for x axis
     self.ymin = kwargs.get('ymin', None)
     self.ymax = kwargs.get('ymax', None)
     self.rmin = kwargs.get('rmin', None)
     self.rmax = kwargs.get('rmax', None)
     self.ratiorange = kwargs.get('rrange', None)
     self.logx = kwargs.get('logx', False)
     self.logy = kwargs.get('logy', False)
     self.ymargin = kwargs.get(
         'ymargin', None)  # margin between hist maximum and plot's top
     self.logyrange = kwargs.get(
         'logyrange', None)  # log(y) range from hist maximum to ymin
     self.position = kwargs.get('pos', "")  # legend position
     self.position = kwargs.get('position',
                                self.position)  # legend position
     self.ncols = kwargs.get('ncol', None)  # number of legend columns
     self.ncols = kwargs.get('ncols',
                             self.ncols)  # number of legend columns
     #self.plot         = kwargs.get('plots',       True          )
     self.only = kwargs.get('only', [])  # only plot for these patterns
     self.veto = kwargs.get('veto', [])  # do not plot for these patterns
     self.blindcuts = kwargs.get('blind',
                                 "")  # string for blind cuts to blind data
     self.addoverflow_ = kwargs.get('addoverflow',
                                    False)  # add overflow to last bin
     if self.latex:
         self.title = makelatex(self.title, units=self.units)
         if 'ctitle' in kwargs:
             for ckey, title in kwargs['ctitle'].iteritems():
                 kwargs['ctitle'][ckey] = makelatex(title)
     if self.only:
         self.only = ensurelist(self.only)
     if self.veto:
         self.veto = ensurelist(self.veto)
     if self.binlabels and len(self.binlabels) < self.nbins:
         LOG.warning("Variable.init: len(binlabels)=%d < %d=nbins" %
                     (len(self.binlabels), self.nbins))
     if self.addoverflow_:
         self.addoverflow()
     if islist(self.blindcuts):
         LOG.insist(
             len(self.blindcuts) == 2,
             "Variable.init: blind cuts must be a string, or a pair of floats! Got: %s"
             % (self.blindcuts, ))
         self.blindcuts = self.blind(*self.blindcuts)
     self.ctxtitle = getcontext(kwargs,
                                self.title,
                                key='ctitle',
                                regex=True)  # context-dependent title
     self.ctxbins = getcontext(kwargs, args, key='cbins',
                               regex=True)  # context-dependent binning
     self.ctxposition = getcontext(kwargs,
                                   self.position,
                                   key='cposition',
                                   regex=True)  # context-dependent position
     self.ctxblind = getcontext(
         kwargs, self.blindcuts, key='cblind',
         regex=True)  # context-dependent blind limits
     self.ctxymargin = getcontext(kwargs,
                                  self.ymargin,
                                  key='cymargin',
                                  regex=True)  # context-dependent ymargin
     self.ctxcut = getcontext(kwargs, self.cut, key='ccut',
                              regex=True)  # context-dependent cuts
     self.ctxweight = getcontext(kwargs,
                                 self.weight,
                                 key='cweight',
                                 regex=True)  # context-dependent cuts