ATLAS Offline Software
Control/AthenaServices/python/Dso.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 # @file: AthenaServices/python/Dso.py
4 # @purpose: simple interface to the rootmap files to easily locate reflex
5 # dictionaries (and load them)
6 # @author: Sebastien Binet <binet@cern.ch>
7 # @date: September 2008
8 
9 
10 __version__ = "$Revision: 1.12 $"
11 __author__ = "Sebastien Binet <binet@cern.ch>"
12 __doc__ = """\
13 simple interface to the rootmap files to easily locate reflex dictionaries \
14 (and load them)
15 """
16 
17 __all__ = [
18  'registry',
19  ]
20 
21 
22 import os
23 from PyUtils import Dso as _Dso
24 from PyUtils.Dso import _aliases
25 
26 try:
27  # attempt at fixing up the pyroot iterators...
28  import RootUtils.PyROOTFixes # noqa: F401
29 except ImportError:
30  pass
31 
32 _cpp_builtins = (
33  'char', 'unsigned char', 'signed char',
34  'signed',
35  'short int', 'short signed', 'short signed int',
36  'short', 'unsigned short', 'signed short',
37  'int', 'unsigned int',
38 
39  'long int',
40  'long signed int',
41  'signed long int',
42 
43  'long',
44  'long signed', 'signed long',
45  'unsigned long',
46  'unsigned long int',
47  'long unsigned int',
48 
49  'long long',
50  'long long int',
51  'unsigned long long',
52  'longlong',
53 
54  # no clue from where this one comes from, who's requesting it nor who
55  # got the alien naming scheme idea...
56  'ulonglong',
57 
58  'float',
59  'double',
60  'long double',
61  'bool',
62  )
63 
64 
65 
66 class RflxEnums(object):
67  S = 4 # SCOPED
68  SF = 5 # SCOPED|FINAL
69  SQ = 6 # SCOPED|QUALIFIED
70  SFQ = 7 # SCOPED|FINAL|QUALIFIED
71  DICTSCOPE =SF
72 
73 class DsoDb(_Dso.PyDsoDb):
74  """
75  The repository of 'rootmap' files (location, content,...) and a set of
76  operations one can apply on them (load dict, query dicts,...)
77  """
78  def __init__(self):
79  super(DsoDb, self).__init__('AthenaDsoDb')
80  import AthenaCommon.Logging
81  self.msg = AthenaCommon.Logging.logging.getLogger("AthenaDsoDb")
82  #self.msg.setLevel(AthenaCommon.Logging.logging.VERBOSE)
83 
84  # inject the known aliases NOW
85  for k,v in _aliases.iteritems():
86  try:
87  self.db[k] = self.db[v]
88  except KeyError:
89  self.msg.info("could not install alias [%s] -> [%s]", k,v)
90  # make sure we'll be able to load dicts
91  import cppyy
92  #self._load_dict = cppyy.loadDict
93  self._rflx_type = cppyy.gbl.RootType.ByName
94  return
95 
96  def has_type (self, typename):
97  if typename in _cpp_builtins:
98  return True
99  # need to massage a bit the typename to match ROOT naming convention
100  typename = self._to_rootmap_name (typename)
101  return self.db.has_key (typename) or \
102  self.pf.has_key (typename)
103 
104  def load_type (self, typename):
105  rflx_type = self.rflx_type(typename)
106  if not(rflx_type is None):
107  rflx_name = rflx_type.Name(RflxEnums.DICTSCOPE)
108  if rflx_name != '':
109  return rflx_name
110  return None
111 
112  def rflx_type(self, typename):
113  _rootmap_name = self._to_rootmap_name (typename)
114  _rflx_name = self._to_rflx_name (typename)
115  self.msg.verbose("------- loading type [%s]...", typename)
116 
117  if typename in _cpp_builtins:
118  self.msg.verbose(" ==> [ok] (builtin)")
119  return self._rflx_type (_rflx_name)
120 
121  if not self.has_type (_rootmap_name):
122  self.msg.verbose(" ==> [err] (no '%s')",_rootmap_name)
123  return None
124  libs = (self.db.get(_rootmap_name) or
125  self.pf.get(_rootmap_name))
126  if libs is None or len(libs) <= 0:
127  return None
128  from ctypes import cdll
129  _load = cdll.LoadLibrary
130  from cppyy import loadDict as _load
131  lib = libs[0]
132  self.msg.verbose("... %s",lib)
133  _load (os.path.basename(lib.strip()))
134  self.msg.verbose("... %s [done]",lib)
135  self.msg.verbose(" ==> [ok]")
136 
137  # give the non-massaged name to reflex as this is what it expects
138  # ...ROOT is sooo self-consistent...
139  rflx_type = self._rflx_type (_rflx_name)
140  if rflx_type.Name() != '':
141  return rflx_type
142  return None
143 
144 
145  def visit(self, typename, visitor=None, ctx=None):
146  self.msg.verbose("=== visiting %s", typename)
147  if ctx is None:
148  ctx = set()
149  if isinstance (typename, str):
150  rflx_type = self.load_type (typename)
151  typename = rflx_type.Name (RflxEnums.DICTSCOPE)
152  else:
153  rflx_type = typename
154 
155  if not rflx_type:
156  self.msg.verbose("**warning** no dict for [%s] !!", typename)
157  return ctx
158 
159  ctx.add (typename)
160  if visitor:
161  visitor (rflx_type)
162 
163  if rflx_type.IsClass() or rflx_type.IsStruct():
164  for i in range(rflx_type.BaseSize()):
165  itype = rflx_type.BaseAt(i).ToType()
166  itype_name = itype.Name(RflxEnums.DICTSCOPE)
167  if itype_name != '' and not (itype_name in ctx):
168  self.load_type (itype_name)
169  ctx.add (itype_name)
170  ctx.update (self.visit (itype, visitor, ctx))
171 
172  for i in range(rflx_type.DataMemberSize()):
173  itype = rflx_type.DataMemberAt (i).TypeOf()
174  itype = itype.RawType() if itype.IsPointer() else itype
175  itype_name = itype.Name(RflxEnums.DICTSCOPE)
176  if itype_name != '' and not (itype_name in ctx):
177  self.load_type (itype_name)
178  ctx.add (itype_name)
179  # restore original type
180  itype = rflx_type.DataMemberAt (i).TypeOf()
181  itype_name = itype.Name(RflxEnums.DICTSCOPE)
182  ctx.update (self.visit (itype, visitor, ctx))
183  return ctx
184 
185  pass # class DsoDb
186 
187 
188 registry = _Dso.DsoDb()
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
python.Dso.DsoDb
DsoDb
Definition: Tools/PyUtils/python/Dso.py:475
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
python.Utilities.__init__
__init__
Definition: Utilities.py:103
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:296
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:130
pickleTool.object
object
Definition: pickleTool.py:29
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87