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
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
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)
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
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()
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()
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
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
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
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()
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
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()
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