CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Classes | Functions | Variables
python.rootplot.rootmath Namespace Reference

Classes

class  Target
 Classes #############################################################. More...
 

Functions

def add
 
def allsame
 
def alltrue
 
def bayes_divide
 
def divide
 
def main
 
def newadd
 
def operator_func
 
def pathdiff
 
def pathdiff2
 
def pathdiff3
 
def scale_with_error
 
def subtract
 
def walk_rootfile
 Implementation ######################################################. More...
 

Variables

string __license__
 
tuple ROOT = loadROOT()
 

Detailed Description

rootmath description

Function Documentation

def python.rootplot.rootmath.add (   outfile,
  dest,
  hists,
  scales = None,
  dest_path = "",
  scale_errors = None 
)

Definition at line 266 of file rootmath.py.

References sistrip::SpyUtilities.range(), and python.rootplot.rootmath.scale_with_error().

Referenced by python.rootplot.rootmath.newadd().

267 def add(outfile, dest, hists, scales=None, dest_path="", scale_errors=None):
268  if not scales:
269  scales = [1. for i in range(len(hists))]
270  if not scale_errors:
271  scale_errors = [None for i in range(len(hists))]
272  sumhist = hists[0].Clone(os.path.basename(dest))
273  sumhist = scale_with_error(sumhist, scales[0], scale_errors[0])
274  #sumhist.Scale(scales[0])
275  for i in range(1,len(hists)):
276  sumhist.Add(scale_with_error(hists[i], scales[i], scale_errors[i]))
277  #sumhist.Add(hists[i], scales[i])
278  if dest_path:
279  outfile.cd()
280  if not ROOT.gDirectory.GetDirectory(dest_path):
281  ROOT.gDirectory.mkdir(dest_path)
282  ROOT.gDirectory.cd(dest_path)
283  sumhist.Write()
284  ROOT.gDirectory.cd("/")
285 
@operator_func
const uint16_t range(const Frame &aFrame)
def python.rootplot.rootmath.allsame (   iterable)

Definition at line 148 of file rootmath.py.

Referenced by python.rootplot.rootmath.newadd(), python.rootplot.rootmath.pathdiff(), python.rootplot.rootmath.pathdiff2(), and python.rootplot.rootmath.pathdiff3().

149 def allsame(iterable):
150  for element in iterable:
151  if element != iterable[0]:
152  return False
153  return True
def python.rootplot.rootmath.alltrue (   iterable)

Definition at line 154 of file rootmath.py.

Referenced by python.rootplot.rootmath.main(), and python.rootplot.rootmath.newadd().

155 def alltrue(iterable):
156  for element in iterable:
157  if element != True:
158  return False
159  return True
def python.rootplot.rootmath.bayes_divide (   outfile,
  dest,
  numer,
  denom 
)

Definition at line 299 of file rootmath.py.

300 def bayes_divide(outfile, dest, numer, denom):
301  quotient = ROOT.TGraphAsymmErrors()
302  quotient.SetName(os.path.basename(dest))
303  quotient.BayesDivide(numer, denom)
304  quotient.Write()
def python.rootplot.rootmath.divide (   outfile,
  dest,
  numer,
  denom 
)

Definition at line 293 of file rootmath.py.

294 def divide(outfile, dest, numer, denom):
295  quotient = numer.Clone(os.path.basename(dest))
296  quotient.Divide(numer, denom)
297  quotient.Write()
298 
@operator_func
def python.rootplot.rootmath.main ( )

Definition at line 305 of file rootmath.py.

References python.rootplot.rootmath.alltrue(), python.rootplot.rootmath.pathdiff(), python.rootplot.utilities.rootglob(), and python.rootplot.rootmath.walk_rootfile().

306 def main():
307  parser = argparse.ArgumentParser()
308  parser.add_argument('filenames', type=str, nargs='+',
309  help='root files to process')
310  parser.add_argument('--dirs', type=str, nargs='+', default=['/'],
311  help='target directories in the root files; paths to '
312  'histograms will be relative to these')
313  parser.add_argument('--add', default=[], action='append', nargs='*',
314  help='a list of directories or histograms to add')
315  parser.add_argument('--subtract', default=[], action='append', nargs='*',
316  help='a list of directories or histograms to subtract')
317  parser.add_argument('--divide', default=[], action='append', nargs='*',
318  help='2 directories or histograms to divide')
319  parser.add_argument('--bayes-divide', default=[], action='append', nargs='*',
320  help='2 directories or histograms from which to make '
321  'an efficiency plot')
322  args = parser.parse_args()
323  separators = {'add' : '_plus_',
324  'subtract' : '_minus_',
325  'divide' : '_div_',
326  'bayes_divide' : '_eff_'}
327 
328  files = [ROOT.TFile(x, 'read') for x in args.filenames]
329  outfile = ROOT.TFile('out.root', 'recreate')
330  dirs = []
331  for d in args.dirs:
332  dirs += rootglob(files[0], d)
333 
334  if len(files) == 1:
335  f = files[0]
336  for thisdir in dirs:
337  for operation_type, separator in separators.items():
338  for arg_set in getattr(args, operation_type):
339  paths = [joined(thisdir, x) for x in arg_set]
340  if f.GetDirectory(paths[0]):
341  destdir = pathdiff(paths, separator)
342  for target in [os.path.basename(x) for x in
343  rootglob(f, paths[0] + '/*')]:
344  hists = [f.GetDirectory(x).Get(target)
345  for x in paths]
346  if not alltrue([x and x.InheritsFrom('TH1')
347  for x in hists]):
348  continue
349  dest = joined(destdir, target)
350  math_func = globals()[operation_type]
351  math_func(outfile, dest, hists)
352  else:
353  hists = [f.GetDirectory(thisdir).Get(x) for x in paths]
354  if not alltrue([x and x.InheritsFrom('TH1')
355  for x in hists]):
356  continue
357  dest = pathdiff(paths, separator)
358  math_func = globals()[operation_type]
359  math_func(outfile, dest, hists)
360  else:
361  for operation_type, separator in separators.items():
362  arg_sets = getattr(args, operation_type)
363  if arg_sets and arg_sets != [[]]:
364  raise ValueError("No arguments to --%s allowed when multiple "
365  "files are specified" % operation_type)
366  elif arg_sets:
367  if 'divide' in operation_type and len(files) != 2:
368  raise ValueError("Exactly 2 files are expected with --%s; "
369  "%i given" % (operation_type, len(files)))
370  for path, folders, objects in walk_rootfile(files[0]):
371  for obj in objects:
372  hists = [x.GetDirectory(path).Get(obj) for x in files]
373  if not alltrue([x and x.InheritsFrom('TH1')
374  for x in hists]):
375  continue
376  math_func = globals()[operation_type]
377  math_func(outfile, joined(path, obj), hists)
378 
379  outfile.Close()
def walk_rootfile
Implementation ######################################################.
Definition: rootmath.py:130
def python.rootplot.rootmath.newadd (   outfile,
  targets,
  dest_path = "" 
)
Description.

Definition at line 67 of file rootmath.py.

References python.rootplot.rootmath.add(), python.rootplot.rootmath.allsame(), python.rootplot.rootmath.alltrue(), bitset_utilities.append(), python.rootplot.rootmath.pathdiff2(), print(), and python.rootplot.utilities.rootglob().

67 
68 def newadd(outfile, targets, dest_path=""):
69  """Description."""
70  if allsame([x.filename for x in targets]):
71  f = ROOT.TFile(targets[0].filename, 'read')
72  paths = [x.path for x in targets]
73  scales = [x.scale for x in targets]
74  scale_errors = [x.scale_error for x in targets]
75  if f.GetDirectory(paths[0]):
76  destdir = pathdiff2(paths) # What does this do?
77  for h in [os.path.basename(x) for x in
78  rootglob(f, paths[0] + '/*')]:
79  hists = [f.GetDirectory(x).Get(h) for x in paths]
80  if not alltrue([x and x.InheritsFrom('TH1') for x in hists]):
81  continue
82  dest = joined(destdir, h)
83  add(outfile, dest, hists, scales, dest_path, scale_errors=scale_errors)
84  else:
85  hists = [f.Get(x) for x in paths]
86  if alltrue([x and x.InheritsFrom('TH1') for x in hists]):
87  dest = pathdiff2(paths)
88  add(outfile, dest, hists, scales, scale_errors=scale_errors)
89  else:
90  dict_targets = {} # Stores paths and scales, key = filename
91  dict_tfiles = {} # Stores map from filenames to Root.TFile() objects
92  for target in targets:
93  dict_targets.setdefault(target.filename, []).append((target.path, target.scale))
94  if (target.filename not in dict_tfiles):
95  # Only open root files once
96  dict_tfiles[target.filename] = ROOT.TFile(target.filename, 'read')
97  # dict_targets now a dictionary, with keys the filenames, example:
98  # {'fileA.root': [('path0',scale0), ('path1', scale1)],
99  # 'fileB.root': [('path3', scale3)]}
100  f = ROOT.TFile(targets[0].filename, 'read')
101  if f.GetDirectory(targets[0].path):
102  # Create list of histograms to get
103  destdir = '/' # should probably use pathdiff2 somehow
104  histnames = [os.path.basename(x) for x in
105  rootglob(f, targets[0].path + '/*')]
106  f.Close()
107  # For each histogram name found, grab it from
108  # every file & path
109  for histname in histnames:
110  hists = []
111  scales = []
112  for filename in dict_targets:
113  tfile_cur = dict_tfiles[filename]
114  for path, scale in dict_targets[filename]:
115  hists.append(tfile_cur.GetDirectory(path).Get(histname))
116  scales.append(scale)
117  #print "%s:%s:%s:%f" % (filename, path, histname, scale)
118  if not alltrue([x and x.InheritsFrom('TH1') for x in hists]):
119  continue
120  dest = joined(destdir, histname)
121  add(outfile, dest, hists, scales, dest_path)
122  else:
123  print("Code not written yet to add histograms from multiple files")
124  return
125  return
126 
boost::dynamic_bitset append(const boost::dynamic_bitset<> &bs1, const boost::dynamic_bitset<> &bs2)
this method takes two bitsets bs1 and bs2 and returns result of bs2 appended to the end of bs1 ...
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def python.rootplot.rootmath.operator_func (   fn)

Definition at line 242 of file rootmath.py.

References personalPlayback.fn, and submitPVValidationJobs.split().

243 def operator_func(fn):
244  def newfunc(outfile, dest, hists, scales=None, dest_path="", scale_errors=None):
245  outfile.cd()
246  for d in os.path.dirname(dest).split('/'):
247  if not ROOT.gDirectory.GetDirectory(d):
248  ROOT.gDirectory.mkdir(d)
249  ROOT.gDirectory.cd(d)
250  fn(outfile, dest, hists, scales, dest_path, scale_errors)
251  return newfunc
def python.rootplot.rootmath.pathdiff (   paths,
  joiner 
)
Return the appropriate destination for an object.

In all cases, the result will be placed in the deepest directory shared by
all paths.  If the histogram names are the same, the result will be named
based on the first directories that they do not share.  Otherwise, the 
result will be named based on the names of the other histograms.

>>> pathdiff(['/dirA/dirB/dirX/hist', '/dirA/dirB/dirY/hist'], '_div_')
'/dirA/dirB/dirX_div_dirY'
>>> pathdiff(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
'/dirA/hist1_plus_hist2_plus_hist3'
>>> pathdiff(['/hist1', '/dirA/hist2'], '_minus_')
'/hist1_minus_hist2'

Definition at line 160 of file rootmath.py.

References python.rootplot.rootmath.allsame(), and sistrip::SpyUtilities.range().

Referenced by python.rootplot.rootmath.main().

161 def pathdiff(paths, joiner):
162  """
163  Return the appropriate destination for an object.
164 
165  In all cases, the result will be placed in the deepest directory shared by
166  all paths. If the histogram names are the same, the result will be named
167  based on the first directories that they do not share. Otherwise, the
168  result will be named based on the names of the other histograms.
169 
170  >>> pathdiff(['/dirA/dirB/dirX/hist', '/dirA/dirB/dirY/hist'], '_div_')
171  '/dirA/dirB/dirX_div_dirY'
172  >>> pathdiff(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
173  '/dirA/hist1_plus_hist2_plus_hist3'
174  >>> pathdiff(['/hist1', '/dirA/hist2'], '_minus_')
175  '/hist1_minus_hist2'
176  """
177  paths = [x.split('/') for x in paths]
178  dest = '/'
179  for i in range(len(paths[0])):
180  if allsame([p[i] for p in paths]):
181  dest = joined(dest, paths[0][i])
182  else:
183  break
184  name = joiner.join([p[-1] for p in paths])
185  if allsame([p[-1] for p in paths]):
186  for i in range(len(paths[0])):
187  if not allsame([p[i] for p in paths]):
188  name = joiner.join([p[i] for p in paths])
189  return joined(dest, name)
const uint16_t range(const Frame &aFrame)
def python.rootplot.rootmath.pathdiff2 (   paths,
  joiner = '__',
  truncate = False 
)
Placeholder.

Definition at line 190 of file rootmath.py.

References python.rootplot.rootmath.allsame(), and sistrip::SpyUtilities.range().

Referenced by python.rootplot.rootmath.newadd().

191 def pathdiff2(paths, joiner='__', truncate=False):
192  """
193  Placeholder.
194  """
195  paths = [x.split('/') for x in paths]
196  commonbeginning = ''
197  for i in range(len(paths[0])):
198  if allsame([p[i] for p in paths]):
199  commonbeginning = joined(commonbeginning, paths[0][i])
200  else:
201  break
202  commonending = ''
203  for i in range(-1, -1 * len(paths[0]), -1):
204  if allsame([p[i] for p in paths]):
205  commonending = joined(paths[0][i], commonending)
206  else:
207  break
208  #return commonbeginning, commonending
209  if truncate:
210  return commonending
211  else:
212  return joined(commonbeginning, commonending)
const uint16_t range(const Frame &aFrame)
def python.rootplot.rootmath.pathdiff3 (   paths,
  joiner = '__' 
)
Return the appropriate destination for an object.

If the final objects in each path match, then the return value will be the
matching part of the paths.  Otherwise, the output path will simply be those
names joined together with *joiner*.  See the examples below.

>>> pathdiff3(['/dirA/dirX/hist', '/dirA/dirY/hist'])
'/hist'
>>> pathdiff3(['/dirA/dirX/dirB/hist', '/dirA/dirY/dirB/hist'])
'/dirB/hist'
>>> pathdiff3(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
'/hist1_plus_hist2_plus_hist3'
>>> pathdiff3(['/hist1', '/dirA/hist2'], '_div_')
'/hist1_div_hist2'

Definition at line 213 of file rootmath.py.

References python.rootplot.rootmath.allsame(), SiStripPI.min, and sistrip::SpyUtilities.range().

214 def pathdiff3(paths, joiner='__'):
215  """
216  Return the appropriate destination for an object.
217 
218  If the final objects in each path match, then the return value will be the
219  matching part of the paths. Otherwise, the output path will simply be those
220  names joined together with *joiner*. See the examples below.
221 
222  >>> pathdiff3(['/dirA/dirX/hist', '/dirA/dirY/hist'])
223  '/hist'
224  >>> pathdiff3(['/dirA/dirX/dirB/hist', '/dirA/dirY/dirB/hist'])
225  '/dirB/hist'
226  >>> pathdiff3(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
227  '/hist1_plus_hist2_plus_hist3'
228  >>> pathdiff3(['/hist1', '/dirA/hist2'], '_div_')
229  '/hist1_div_hist2'
230  """
231  paths = [x.split('/') for x in paths]
232  if allsame([x[-1] for x in paths]):
233  dest = paths[0][-1]
234  for i in range(-2, min([len(x) for x in paths]) * -1, -1):
235  if allsame([p[i] for p in paths]):
236  dest = joined(paths[0][i], dest)
237  else:
238  break
239  return '/' + dest
240  else:
241  return '/' + joiner.join([x[-1] for x in paths])
const uint16_t range(const Frame &aFrame)
def python.rootplot.rootmath.scale_with_error (   hist,
  scale,
  scale_error = None 
)
Scale a histogram by a scale factor that has an error.
This takes into account the scale error to set new error bars.

Definition at line 252 of file rootmath.py.

References sistrip::SpyUtilities.range().

Referenced by python.rootplot.rootmath.add().

253 def scale_with_error(hist, scale, scale_error=None):
254  '''Scale a histogram by a scale factor that has an error.
255  This takes into account the scale error to set new error bars.'''
256  hist_new = hist.Clone()
257  if scale_error:
258  for i in range(hist_new.GetNbinsX()+2):
259  hist_new.SetBinContent(i, scale)
260  hist_new.SetBinError(i, scale_error)
261  hist_new.Multiply(hist)
262  else:
263  hist_new.Scale(scale)
264  return hist_new
265 
@operator_func
const uint16_t range(const Frame &aFrame)
def python.rootplot.rootmath.subtract (   outfile,
  dest,
  hists 
)

Definition at line 286 of file rootmath.py.

287 def subtract(outfile, dest, hists):
288  diffhist = hists[0].Clone(os.path.basename(dest))
289  for hist in hists[1:]:
290  diffhist.Add(hist, -1)
291  diffhist.Write()
292 
@operator_func
def python.rootplot.rootmath.walk_rootfile (   rootfile,
  path = '' 
)

Implementation ######################################################.

Definition at line 130 of file rootmath.py.

Referenced by python.rootplot.rootmath.main().

131 def walk_rootfile(rootfile, path=''):
132  #### Yield (path, folders, objects) for each directory under path.
133  keys = rootfile.GetDirectory(path).GetListOfKeys()
134  folders, objects = [], []
135  for key in keys:
136  name = key.GetName()
137  classname = key.GetClassName()
138  newpath = joined(path, name)
139  dimension = 0
140  if 'TDirectory' in classname:
141  folders.append(name)
142  else:
143  objects.append(name)
144  yield path, folders, objects
145  for folder in folders:
146  for x in walk_rootfile(rootfile, joined(path, folder)):
147  yield x
def walk_rootfile
Implementation ######################################################.
Definition: rootmath.py:130

Variable Documentation

string python.rootplot.rootmath.__license__
Initial value:
1 = '''\
2 Copyright (c) 2009-2010 Jeff Klukas <klukas@wisc.edu>
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 '''

Definition at line 8 of file rootmath.py.

tuple python.rootplot.rootmath.ROOT = loadROOT()

Definition at line 46 of file rootmath.py.