8 __doc__ =
"a few utils to ease the day-to-day work with ROOT"
9 __author__ =
"Sebastien Binet"
19 from functools
import cache
23 """a helper method to wrap the 'import ROOT' statement to prevent ROOT
24 from screwing up the display or loading graphics libraries when in batch
25 mode (which is the default.)
28 >>> ROOT = import_root(batch=True)
29 >>> f = ROOT.TFile.Open(...)
32 ROOT.gROOT.SetBatch(batch)
34 ROOT.PyConfig.IgnoreCommandLineOptions =
True
36 if os.environ.get(
'GLIBCXX_USE_CXX11_ABI') ==
'0':
37 cmd = ROOT.gSystem.GetMakeSharedLib()
38 if cmd.find(
'GLIBCXX_USE_CXX11_ABI') < 0:
39 cmd = cmd.replace (
'$SourceFiles',
'$SourceFiles -D_GLIBCXX_USE_CXX11_ABI=0 ')
40 ROOT.gSystem.SetMakeSharedLib(cmd)
46 """a helper method to compile a set of C++ statements (via ``src``) or
47 a C++ file (via ``fname``) via ACLiC
49 if src
is not None and fname
is not None:
50 raise ValueError(
"'src' xor 'fname' should be not None, *not* both")
52 if src
is None and fname
is None:
53 raise ValueError(
"'src' xor 'fname' should be None, *not* both")
62 _first_compile =
False
63 root_compile (
'extern "C" { void __gmon_start__(){}; }',
None,
True)
64 return _root_compile (src, fname, batch)
68 from .Helpers
import ShutUp
as root_shutup
72 if 'dbg' in os.environ.get(
'CMTCONFIG',
'opt'):
73 compile_options +=
'g'
75 compile_options +=
'O'
81 src_file = tempfile.NamedTemporaryFile(prefix=
'root_aclic_',
83 src_file.write(textwrap.dedent(src).
encode())
97 _tempfiles.append (src_file)
101 import os.path
as osp
102 fname = osp.expanduser(osp.expandvars(fname))
105 assert os.access(fname, os.R_OK),
"could not read [%s]"%(fname,)
106 orig_root_lvl = ROOT.gErrorIgnoreLevel
107 ROOT.gErrorIgnoreLevel = ROOT.kWarning
110 sc = ROOT.gSystem.CompileMacro(fname, compile_options)
111 if sc == ROOT.kFALSE:
113 'problem compiling ROOT macro (rc=%s)'%(sc,)
116 ROOT.gErrorIgnoreLevel = orig_root_lvl
123 import PyUtils.Helpers
as H
124 with H.ShutUp(filters=[
126 'TClass::TClass:0: RuntimeWarning: no dictionary for.*'),
128 'Warning in <TEnvRec::ChangeValue>: duplicate entry.*'
131 cppyy.load_library(
"libRootUtilsPyROOTDict")
132 _ = root.RootUtils.PyBytes
134 read_root_file = root.RootUtils._pythonize_read_root_file
135 tell_root_file = root.RootUtils._pythonize_tell_root_file
137 def read(self, size=-1):
138 """read([size]) -> read at most size bytes, returned as a string.
140 If the size argument is negative or omitted, read until EOF is reached.
141 Notice that when in non-blocking mode, less data than what was requested
142 may be returned, even if no size parameter was given.
144 FIXME: probably doesn't follow python file-like conventions...
151 c_buf = read_root_file(self, size)
152 if c_buf
and c_buf.sz:
154 return bytes([ord(v[i])
for i
in range(v.size())])
161 c_buf = read_root_file(self, size)
162 if c_buf
and c_buf.sz:
164 chunk = bytes([ord(v[i])
for i
in range(v.size())])
170 root.TFile.read = read
173 root.TFile.seek = root.TFile.Seek
174 root.TFile.tell =
lambda self: tell_root_file(self)
185 tname = l.GetTypeName()
187 if tname
in [
'UInt_t',
'Int_t',
'ULong64_t',
'Long64_t']:
188 return [l.GetValueLong64(i)
for i
in range(ndat)]
189 if tname
in [
'Float_t',
'Double_t']:
190 return [l.GetValue(i)
for i
in range(ndat)]
191 if tname
in [
'Char_t']:
193 return l.GetValueString()
195 return [l.GetValue(i)
for i
in range(ndat)]
200 A helper class to dump in more or less human readable form the content of
204 def __init__(self, fname, tree_name="CollectionTree"):
205 object.__init__(self)
214 not isinstance(self.
root_file, ROOT.TFile)
or
216 raise IOError(
'could not open [%s]'% fname)
219 if self.
tree is None or not isinstance(self.
tree, ROOT.TTree):
220 raise AttributeError(
'no tree [%s] in file [%s]', tree_name, fname)
224 keys = [k.GetName()
for k
in self.
root_file.GetListOfKeys()]
227 if isinstance(o, ROOT.TTree):
233 def dump(self, tree_name, itr_entries, leaves=None, retvecs=False, sortleaves=True):
236 import AthenaPython.PyAthena
as PyAthena
237 _pythonize = PyAthena.RootUtils.PyROOTInspector.pyroot_inspect2
240 if self.
tree is None or not isinstance(self.
tree, ROOT.TTree):
241 raise AttributeError(
'no tree [%s] in file [%s]', tree_name, self.
root_file.GetName())
244 nentries = tree.GetEntries()
245 branches =
sorted([b.GetName().rstrip(
'\0')
for b
in tree.GetListOfBranches()])
246 if leaves
is None: leaves = branches
247 else: leaves = [
str(b).rstrip(
'\0')
for b
in leaves]
250 if isinstance(itr_entries, str):
251 if ':' in itr_entries:
259 from itertools
import islice
260 itr_entries = islice(
range(nentries),
261 *map(toint, itr_entries.split(
':')))
262 elif (
'range' in itr_entries
or
264 itr_entries = eval(itr_entries)
267 _n =
int(itr_entries)
268 itr_entries =
range(_n)
270 print (
"** err ** invalid 'itr_entries' argument. will iterate over all entries.")
271 itr_entries =
range(nentries)
272 elif isinstance(itr_entries, list):
273 itr_entries = itr_entries
275 itr_entries =
range(itr_entries)
280 isinstance_ = isinstance
282 for ientry
in itr_entries:
283 hdr =
":: entry [%05i]..." % (ientry,)
286 err = tree.LoadTree(ientry)
288 print (
"**err** loading tree for entry",ientry)
292 nbytes = tree.GetEntry(ientry)
294 print (
"**err** reading entry [%s] of tree [%s]" % (ientry, tree_name))
295 hdr =
":: entry [%05i]... [ERR]" % (ientry,)
300 for br_name
in leaves:
301 hdr =
":: branch [%s]..." % (br_name,)
306 br = tree.GetBranch (br_name)
307 if br.GetClassName() !=
'':
313 getattr (ROOT, br.GetClassName())
314 val = getattr(tree, br_name)
316 vals = [_getLeaf (l)
for l
in br.GetListOfLeaves()]
323 if not (val
is None):
326 vals = _pythonize(val, py_name,
True, retvecs)
327 except Exception
as err:
328 print (
"**err** for branch [%s] val=%s (type=%s)" % (
329 br_name, val,
type(val),
334 viter =
sorted(vals, key =
lambda x:
'.'.
join(s
for s
in x[0]
if isinstance_(s, str_)))
338 n = list_(map_(str_, o[0]))
340 yield tree_name, ientry, n, v
349 def no_raise(msg, fct, *args, **kwds):
354 except Exception
as xerr:
357 assert not caught,
"%s:\n%s\nERROR" % (msg, err,)
359 no_raise(
"problem pythonizing TFile", fct=_pythonize_tfile)
360 no_raise(
"problem compiling dummy one-liner",
361 root_compile,
"void foo1() { return ; }")
362 no_raise(
"problem compiling dummy one-liner w/ kwds",
363 fct=root_compile, src=
"void foo1a() { return ; }")
366 dummy = tempfile.NamedTemporaryFile(prefix=
"foo_",suffix=
".cxx")
367 with tempfile.NamedTemporaryFile(prefix=
"foo_",suffix=
".cxx")
as tmp:
368 tmp.write (b
"void foo2() { return ; }\n")
370 no_raise(
"problem compiling a file",
371 fct=root_compile, fname=tmp.name)
376 if __name__ ==
"__main__":