ATLAS Offline Software
xAODRootTest.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
2 #
3 # File: share/xAODRootTest.py
4 # Author: snyder@bnl.gov
5 # Date: Jun 2014
6 # Purpose: Test reading xAOD objects directly from root.
7 #
8 
9 # Work around library loading order issue seen with the LTO build.
10 # Otherwise we can get inconsistent resolution of a static std::string,
11 # leading to a free() failure during exit().
12 import ROOT
13 if ROOT.gSystem.FindDynamicLibrary (cppyy.gbl.TString ("libGaudiKernel"), True):
14  ROOT.gSystem.Load("libGaudiKernel")
15 
16 import cppyy
17 
18 import sys
19 cppyy.load_library("libDataModelTestDataCommonDict")
20 if 'LOAD_WRITE_DIR' in globals():
21  cppyy.load_library("libDataModelTestDataWriteDict")
22 else:
23  cppyy.load_library("libDataModelTestDataReadDict")
24 
25 def CHECK(sc):
26  if not sc.isSuccess():
27  raise Exception ('bad StatusCode')
28  return
29 
30 
31 
32 reg=ROOT.SG.AuxTypeRegistry.instance()
33 
34 def _typename(t):
35  return getattr (t, '__cpp_name__', t.__name__)
36 
37 def xAODInit():
38  ROOT.xAOD.TEvent
39  CHECK(ROOT.xAOD.Init())
40  import sys
41  if len(sys.argv) >= 2 and sys.argv[1] == '--rntuple':
42  return True
43  return False
44 
45 
46 
47 cvec_cls=ROOT.DataVector(ROOT.DMTest.C_v1)
48 cel_cls=ROOT.ElementLink(cvec_cls)
49 
50 
51 
52 def format_int(x): return '%d'%x
53 def format_float(x): return '%.1f'%x
54 def format_str(x): return f"'{x}'"
55 def format_el(x): return '%s[%s]' % (x.dataID(), ('inv' if x.isDefaultIndex() else x.index()))
56 def format_el_vec(v): return '[' + ', '.join([format_el(el) for el in v.asVector()]) + ']'
58  l = [format_float(x) for x in v]
59  return '[' + ','.join(l) + ']'
61  l = [format_int(x) for x in v]
62  return '[' + ','.join(l) + ']'
64  l = [format_str(x) for x in v]
65  return '[' + ','.join(l) + ']'
66 CVec_type = ROOT.DataVector(ROOT.DMTest.C_v1)
67 accessors = {
68  'int' : (ROOT.SG.ConstAccessor(int), format_int),
69  'unsigned int' : (getattr (ROOT, 'SG::ConstAccessor<unsigned int>'), format_int),
70  'float' : (ROOT.SG.ConstAccessor(float), format_float),
71  'std::vector<float>' : (getattr (ROOT, 'SG::ConstAccessor<std::vector<float> >'), format_float_vec),
72  'std::vector<int>' : (getattr (ROOT, 'SG::ConstAccessor<std::vector<int> >'), format_int_vec),
73  'ElementLink<DataVector<DMTest::C_v1> >' :
74  (ROOT.SG.ConstAccessor(cel_cls), format_el),
75  'SG::JaggedVecElt<int>' :
76  (ROOT.SG.ConstAccessor(ROOT.SG.JaggedVecElt(ROOT.int)),
77  format_int_vec),
78  'SG::JaggedVecElt<float>' :
79  (ROOT.SG.ConstAccessor(ROOT.SG.JaggedVecElt(ROOT.float)),
80  format_float_vec),
81  'SG::JaggedVecElt<double>' :
82  (ROOT.SG.ConstAccessor(ROOT.SG.JaggedVecElt(ROOT.double)),
83  format_float_vec),
84  'SG::JaggedVecElt<std::string>' :
85  (ROOT.SG.ConstAccessor(ROOT.SG.JaggedVecElt(ROOT.std.string)),
86  format_str_vec),
87  'SG::JaggedVecElt<ElementLink<DataVector<DMTest::C_v1> > >' :
88  (ROOT.SG.ConstAccessor(ROOT.SG.JaggedVecElt(ROOT.ElementLink(CVec_type))),
89  format_el_vec),
90  'SG::PackedLink<DataVector<DMTest::C_v1> >' :
91  (ROOT.SG.ConstAccessor(ROOT.SG.PackedLink(ROOT.DataVector(ROOT.DMTest.C_v1))),
92  format_el),
93  'std::vector<SG::PackedLink<DataVector<DMTest::C_v1> > >' :
94  (ROOT.SG.ConstAccessor(ROOT.std.vector(ROOT.SG.PackedLink(ROOT.DataVector(ROOT.DMTest.C_v1)))),
95  format_el_vec),
96  }
97 
98 def dump_auxitem (x, auxid, f = sys.stdout):
99  tname = reg.getTypeName (auxid)
100  ac_p = accessors.get (tname)
101  if not ac_p:
102  print ('<unknown %s>'%tname, end='', file=f)
103  else:
104  (ac_cl, formatter) = ac_p
105  val = ac_cl(reg.getName(auxid))(x)
106  print (formatter(val) + '; ', end='', file=f)
107  return
108 
109 
110 def dump_auxdata (x, exclude=[], f = sys.stdout):
111  auxids = list(x.getAuxIDs())
112  auxids = [(reg.getName(id), id) for id in auxids]
113  auxids.sort()
114  for name, auxid in auxids:
115  if name in exclude: continue
116  if reg.isLinked (auxid): continue
117  print (name + ': ', file=f, end='')
118  dump_auxitem (x, auxid, f)
119  return
120 
121 
122 def dump_c (c, f=sys.stdout):
123  if hasattr(c, '__deref__'):
124  c = c.__deref__()
125  print (' anInt1: %d; aFloat: %.1f; ' % (c.anInt(), c.aFloat()), end='')
126  dump_auxdata (c, exclude = ['anInt1', 'aFloat'])
127  print ('')
128  return
129 
130 
131 def dump_xaodobj (h, f=sys.stdout):
132  if hasattr(h, '__deref__'):
133  h = h.__deref__()
134  dump_auxdata (h)
135  print ('')
136  return
137 
138 
139 def dump_plinks (p, f=sys.stdout):
140  if hasattr(p, '__deref__'):
141  p = p.__deref__()
142  dump_auxdata (p)
143  print ('')
144  return
145 
146 
147 def copy_obj (event, obj, key):
148  copy = obj.__class__()
149  copy_aux = obj.getConstStore().__class__()
150  copy.setNonConstStore (copy_aux)
151  copy.__assign__ (obj)
152  CHECK (event.record (copy, key))
153  CHECK (event.record (copy_aux, key + 'Aux.'))
154  ROOT.SetOwnership (copy, False)
155  ROOT.SetOwnership (copy_aux, False)
156  return
157 
158 
159 def copy_vec (event, obj, key):
160  copy = obj.__class__()
161  copy_aux = obj.getConstStore().__class__()
162  copy.setNonConstStore (copy_aux)
163  for i in range(obj.size()):
164  elt_orig = obj[i]
165  if _typename (elt_orig.__class__).startswith ('DataModel_detail::ElementProxy<'):
166  elt_orig = elt_orig.__follow__()
167  elt = elt_orig.__class__()
168  copy.push_back(elt)
169  ROOT.SetOwnership (elt, False)
170  elt.__assign__ (elt_orig)
171  CHECK (event.record (copy, key))
172  CHECK (event.record (copy_aux, key + 'Aux.'))
173  ROOT.SetOwnership (copy, False)
174  ROOT.SetOwnership (copy_aux, False)
175  return
176 
177 
178 def copy_view (event, obj, key):
179  copy = obj.__class__(obj)
180  copy.toPersistent()
181  CHECK (event.record (copy, key))
182  ROOT.SetOwnership (copy, False)
183  return
184 
185 
187  def __init__ (self, is_rntuple, readPrefix = ''):
188  self.readPrefix = readPrefix
189  self.is_rntuple = is_rntuple
190  return
191 
192 
193  def execute (self, event):
194  print (self.readPrefix + 'cvec')
195  vec = event[self.readPrefix + 'cvec']
196  for c in vec:
197  dump_c (c)
198 
199  print (self.readPrefix + 'cinfo')
200  cinfo = event[self.readPrefix + 'cinfo']
201  dump_c (cinfo)
202 
203  print (self.readPrefix + 'ctrig')
204  ctrig = event[self.readPrefix + 'ctrig']
205  for c in ctrig:
206  dump_c (c)
207 
208  vec = event[self.readPrefix + 'cvecWD']
209  print (self.readPrefix + 'cvecWD' + ' ', vec.meta1)
210  for c in vec:
211  dump_c (c)
212 
213  if not self.is_rntuple:
214  vec = event[self.readPrefix + 'cview']
215  print (self.readPrefix + 'cview')
216  for c in vec:
217  dump_c (c)
218 
219  print (self.readPrefix + 'pvec')
220  vec = event[self.readPrefix + 'pvec']
221  for p in vec:
222  dump_xaodobj (p)
223 
224  print (self.readPrefix + 'hvec')
225  vec = event[self.readPrefix + 'hvec']
226  for h in vec:
227  dump_xaodobj (h)
228 
229  print (self.readPrefix + 'jvecContainer')
230  vec = event[self.readPrefix + 'jvecContainer']
231  for h in vec:
232  dump_xaodobj (h)
233 
234  print (self.readPrefix + 'jvecInfo')
235  jvecInfo = event[self.readPrefix + 'jvecInfo']
236  dump_xaodobj (jvecInfo)
237 
238  print (self.readPrefix + 'plinksContainer')
239  vec = event[self.readPrefix + 'plinksContainer']
240  for h in vec:
241  dump_plinks (h)
242 
243  print (self.readPrefix + 'plinksInfo')
244  plinksInfo = event[self.readPrefix + 'plinksInfo']
245  dump_plinks (plinksInfo)
246 
247  #vec = event[self.readPrefix + 'hview']
248  #print (self.readPrefix + 'hview')
249  #for h in vec:
250  # dump_h (h)
251 
252  return
253 
254 
256  def __init__ (self, readPrefix = '', writePrefix = None):
257  self.readPrefix = readPrefix
258  self.writePrefix = writePrefix
259  return
260 
261  def execute (self, event):
262  CHECK (event.copy (self.readPrefix + 'cvec'))
263  CHECK (event.copy (self.readPrefix + 'cinfo'))
264  CHECK (event.copy (self.readPrefix + 'ctrig'))
265  CHECK (event.copy (self.readPrefix + 'cvecWD'))
266  CHECK (event.copy (self.readPrefix + 'cview'))
267  CHECK (event.copy (self.readPrefix + 'pvec'))
268  CHECK (event.copy (self.readPrefix + 'hvec'))
269  CHECK (event.copy (self.readPrefix + 'jvecContainer'))
270  CHECK (event.copy (self.readPrefix + 'jvecInfo'))
271  CHECK (event.copy (self.readPrefix + 'plinksContainer'))
272  CHECK (event.copy (self.readPrefix + 'plinksInfo'))
273  #CHECK (event.copy (self.readPrefix + 'hview'))
274 
275  if self.writePrefix != None:
276  cinfo = event[self.readPrefix + 'cinfo']
277  copy_obj (event, cinfo, self.writePrefix + 'cinfo')
278 
279  cvec = event[self.readPrefix + 'cvec']
280  copy_vec (event, cvec, self.writePrefix + 'cvec')
281 
282  ctrig = event[self.readPrefix + 'ctrig']
283  copy_vec (event, ctrig, self.writePrefix + 'ctrig')
284 
285  cvecwd = event[self.readPrefix + 'cvecWD']
286  copy_vec (event, cvecwd, self.writePrefix + 'cvecWD')
287 
288  cview = event[self.readPrefix + 'cview']
289  copy_view (event, cview, self.writePrefix + 'cview')
290 
291  pvec = event[self.readPrefix + 'pvec']
292  copy_vec (event, pvec, self.writePrefix + 'pvec')
293 
294  hvec = event[self.readPrefix + 'hvec']
295  copy_vec (event, hvec, self.writePrefix + 'hvec')
296 
297  jvec = event[self.readPrefix + 'jvecContainer']
298  copy_vec (event, jvec, self.writePrefix + 'jvecContainer')
299 
300  jvecinfo = event[self.readPrefix + 'jvecInfo']
301  copy_obj (event, jvecinfo, self.writePrefix + 'jvecInfo')
302 
303  plinks = event[self.readPrefix + 'plinksContainer']
304  copy_vec (event, plinks, self.writePrefix + 'plinksContainer')
305 
306  plinksinfo = event[self.readPrefix + 'plinksInfo']
307  copy_obj (event, plinksinfo, self.writePrefix + 'plinksInfo')
308 
309  #hview = event[self.readPrefix + 'hview']
310  #copy_view (event, hview, self.writePrefix + 'hview')
311 
312  return
313 
314 
316  def __init__ (self, decorName, offset=0, readPrefix = ''):
317  self.readPrefix = readPrefix
318  self.offset = offset
319  self.decor = ROOT.SG.Decorator(int)(decorName)
320  return
321 
322 
323  def execute (self, event):
324  cvec = event[self.readPrefix + 'cvec']
325  for c in cvec:
326  self.decor.set(c, self.offset + c.anInt())
327 
328  ctrig = event[self.readPrefix + 'ctrig']
329  for c in cvec:
330  self.decor.set(c, self.offset + c.anInt())
331 
332  cinfo = event[self.readPrefix + 'cinfo']
333  self.decor.set(cinfo, self.offset + cinfo.anInt())
334  return
335 
336 
338  def __init__ (self, decorName, offset=0, readPrefix = ''):
339  self.readPrefix = readPrefix
340  self.offset = offset
341  self.decor = ROOT.SG.Decorator(int)(decorName)
342  return
343 
344 
345  def execute (self, event):
346  cvec = event[self.readPrefix + 'cvec']
347  assert cvec.setOption (self.decor.auxid(), ROOT.SG.AuxDataOption ('nbins', 23))
348  for c in cvec:
349  self.decor.set(c, self.offset + c.anInt())
350  return
351 
352 
354  def __init__ (self, readPrefix = ''):
355  self.readPrefix = readPrefix
356  return
357 
358 
359  def execute (self, event):
360  cvec = event[self.readPrefix + 'cvec']
361  cvec.clearDecorations()
362 
363  ctrig = event[self.readPrefix + 'ctrig']
364  ctrig.clearDecorations()
365 
366  cinfo = event[self.readPrefix + 'cinfo']
367  cinfo.clearDecorations()
368  return
369 
370 
371 
373  def execute (self, event):
374  cont = event['AllocTest']
375  print ('AllocTest: ', end='')
376  for a in cont:
377  print (a.atInt1(), a.atInt2(), end=' ')
378  print()
379  return
380 
381 
382 
383 class Analysis:
384  def __init__ (self, ifname, ofname = None, is_rntuple = False):
385  self.algs = []
386  if is_rntuple:
387  from xAODRootAccess.RPyEvent import RPyEvent
388  self.event = RPyEvent()
389  CHECK (self.event.readFrom (ifname))
390  else:
391  from xAODRootAccess.TPyEvent import TPyEvent
392  self.f = ROOT.TFile (ifname)
393  self.event = TPyEvent (TPyEvent.kAthenaAccess)
394  CHECK (self.event.readFrom (self.f, True, 'CollectionTree'))
395  self.fout = None
396  if ofname:
397  self.fout = ROOT.TFile.Open (ofname, 'recreate')
398  CHECK (self.event.writeTo (self.fout))
399  return
400 
401  def add (self, alg):
402  self.algs.append (alg)
403  return
404 
405  def run (self, n=None):
406  nent = self.event.getEntries()
407  if n != None:
408  nent = min (n, nent)
409  for i in range(nent):
410  self.event.getEntry(i)
411  print ('---> Event', i)
412  for a in self.algs:
413  a.execute (self.event)
414  if self.fout != None:
415  self.event.fill()
416  return
417 
418  def finalize (self):
419  if self.fout:
420  CHECK (self.event.finishWritingTo (self.fout))
421  return
422 
423 
xAODRootTest.format_str
def format_str(x)
Definition: xAODRootTest.py:54
xAODRootTest.xAODTestPDecor.execute
def execute(self, event)
Definition: xAODRootTest.py:345
xAODRootTest.xAODTestClearDecor
Definition: xAODRootTest.py:353
xAODRootTest.AllocTestRead
Definition: xAODRootTest.py:372
xAODRootTest.format_el_vec
def format_el_vec(v)
Definition: xAODRootTest.py:56
xAODRootTest.xAODTestPDecor
Definition: xAODRootTest.py:337
xAODRootTest.xAODTestClearDecor.__init__
def __init__(self, readPrefix='')
Definition: xAODRootTest.py:354
xAODRootTest.xAODTestCopy.writePrefix
writePrefix
Definition: xAODRootTest.py:258
xAODRootTest.dump_plinks
def dump_plinks(p, f=sys.stdout)
Definition: xAODRootTest.py:139
xAODRootTest.xAODTestDecor.execute
def execute(self, event)
Definition: xAODRootTest.py:323
xAODRootTest.xAODTestPDecor.readPrefix
readPrefix
Definition: xAODRootTest.py:339
xAODRootTest.xAODTestPDecor.decor
decor
Definition: xAODRootTest.py:341
xAODRootTest._typename
def _typename(t)
Definition: xAODRootTest.py:34
xAODRootTest.format_int_vec
def format_int_vec(v)
Definition: xAODRootTest.py:60
xAODRootTest.dump_c
def dump_c(c, f=sys.stdout)
Definition: xAODRootTest.py:122
xAODRootTest.xAODTestRead.execute
def execute(self, event)
Definition: xAODRootTest.py:193
xAODRootTest.Analysis.event
event
Definition: xAODRootTest.py:388
xAODRootTest.xAODTestDecor.__init__
def __init__(self, decorName, offset=0, readPrefix='')
Definition: xAODRootTest.py:316
xAODRootTest.xAODTestDecor.decor
decor
Definition: xAODRootTest.py:319
xAODRootTest.xAODTestRead
Definition: xAODRootTest.py:186
xAODRootTest.xAODTestDecor.offset
offset
Definition: xAODRootTest.py:318
xAODRootTest.Analysis
Definition: xAODRootTest.py:383
xAODRootTest.xAODTestCopy
Definition: xAODRootTest.py:255
xAODRootTest.Analysis.finalize
def finalize(self)
Definition: xAODRootTest.py:418
xAODRootTest.AllocTestRead.execute
def execute(self, event)
Definition: xAODRootTest.py:373
xAODRootTest.format_int
def format_int(x)
Definition: xAODRootTest.py:52
xAODRootTest.Analysis.algs
algs
Definition: xAODRootTest.py:385
xAODRootTest.format_el
def format_el(x)
Definition: xAODRootTest.py:55
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
xAODRootTest.Analysis.f
f
Definition: xAODRootTest.py:392
xAODRootTest.xAODTestClearDecor.execute
def execute(self, event)
Definition: xAODRootTest.py:359
xAODRootTest.copy_view
def copy_view(event, obj, key)
Definition: xAODRootTest.py:178
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
xAODRootTest.format_str_vec
def format_str_vec(v)
Definition: xAODRootTest.py:63
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
xAODRootTest.xAODTestCopy.readPrefix
readPrefix
Definition: xAODRootTest.py:257
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
xAODRootTest.xAODTestClearDecor.readPrefix
readPrefix
Definition: xAODRootTest.py:355
vtune_athena.formatter
formatter
Definition: vtune_athena.py:19
xAODRootTest.format_float
def format_float(x)
Definition: xAODRootTest.py:53
xAODRootTest.xAODInit
def xAODInit()
Definition: xAODRootTest.py:37
xAODRootTest.xAODTestPDecor.__init__
def __init__(self, decorName, offset=0, readPrefix='')
Definition: xAODRootTest.py:338
xAODRootTest.Analysis.__init__
def __init__(self, ifname, ofname=None, is_rntuple=False)
Definition: xAODRootTest.py:384
xAODRootTest.xAODTestDecor.readPrefix
readPrefix
Definition: xAODRootTest.py:317
xAODRootTest.dump_auxitem
def dump_auxitem(x, auxid, f=sys.stdout)
Definition: xAODRootTest.py:98
xAODRootTest.xAODTestRead.__init__
def __init__(self, is_rntuple, readPrefix='')
Definition: xAODRootTest.py:187
lumiFormat.fill
fill
Definition: lumiFormat.py:104
xAODRootTest.CHECK
def CHECK(sc)
Definition: xAODRootTest.py:25
xAODRootTest.xAODTestCopy.execute
def execute(self, event)
Definition: xAODRootTest.py:261
xAODRootTest.dump_xaodobj
def dump_xaodobj(h, f=sys.stdout)
Definition: xAODRootTest.py:131
xAODRootTest.copy_obj
def copy_obj(event, obj, key)
Definition: xAODRootTest.py:147
xAODRootTest.Analysis.add
def add(self, alg)
Definition: xAODRootTest.py:401
xAODRootTest.xAODTestDecor
Definition: xAODRootTest.py:315
xAODRootTest.xAODTestCopy.__init__
def __init__(self, readPrefix='', writePrefix=None)
Definition: xAODRootTest.py:256
xAODRootTest.xAODTestPDecor.offset
offset
Definition: xAODRootTest.py:340
xAODRootTest.format_float_vec
def format_float_vec(v)
Definition: xAODRootTest.py:57
xAODRootTest.Analysis.fout
fout
Definition: xAODRootTest.py:395
xAODRootTest.xAODTestRead.readPrefix
readPrefix
Definition: xAODRootTest.py:188
xAODRootTest.copy_vec
def copy_vec(event, obj, key)
Definition: xAODRootTest.py:159
xAODRootTest.Analysis.run
def run(self, n=None)
Definition: xAODRootTest.py:405
xAODRootTest.dump_auxdata
def dump_auxdata(x, exclude=[], f=sys.stdout)
Definition: xAODRootTest.py:110
xAODRootTest.xAODTestRead.is_rntuple
is_rntuple
Definition: xAODRootTest.py:189