ATLAS Offline Software
Control/AthenaServices/python/Dso.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 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 
33 
35  S = 4 # SCOPED
36  SF = 5 # SCOPED|FINAL
37  SQ = 6 # SCOPED|QUALIFIED
38  SFQ = 7 # SCOPED|FINAL|QUALIFIED
39  DICTSCOPE =SF
40 
41 class DsoDb(_Dso.PyDsoDb):
42  """
43  The repository of 'rootmap' files (location, content,...) and a set of
44  operations one can apply on them (load dict, query dicts,...)
45  """
46  def __init__(self):
47  super(DsoDb, self).__init__('AthenaDsoDb')
48  import AthenaCommon.Logging
49  self.msg = AthenaCommon.Logging.logging.getLogger("AthenaDsoDb")
50  #self.msg.setLevel(AthenaCommon.Logging.logging.VERBOSE)
51 
52  # inject the known aliases NOW
53  for k,v in _aliases.iteritems():
54  try:
55  self.db[k] = self.db[v]
56  except KeyError:
57  self.msg.info("could not install alias [%s] -> [%s]", k,v)
58  # make sure we'll be able to load dicts
59  import cppyy
60  #self._load_dict = cppyy.loadDict
61  self._rflx_type = cppyy.gbl.RootType.ByName
62  return
63 
64  def has_type (self, typename):
65  global _cpp_builtins
66  if typename in _cpp_builtins:
67  return True
68  # need to massage a bit the typename to match ROOT naming convention
69  typename = self._to_rootmap_name (typename)
70  return self.db.has_key (typename) or \
71  self.pf.has_key (typename)
72 
73  def load_type (self, typename):
74  rflx_type = self.rflx_type(typename)
75  if not(rflx_type is None):
76  rflx_name = rflx_type.Name(RflxEnums.DICTSCOPE)
77  if rflx_name != '':
78  return rflx_name
79  return None
80 
81  def rflx_type(self, typename):
82  _rootmap_name = self._to_rootmap_name (typename)
83  _rflx_name = self._to_rflx_name (typename)
84  self.msg.verbose("------- loading type [%s]...", typename)
85 
86  global _cpp_builtins
87  if typename in _cpp_builtins:
88  self.msg.verbose(" ==> [ok] (builtin)")
89  return self._rflx_type (_rflx_name)
90 
91  if not self.has_type (_rootmap_name):
92  self.msg.verbose(" ==> [err] (no '%s')",_rootmap_name)
93  return None
94  libs = (self.db.get(_rootmap_name) or
95  self.pf.get(_rootmap_name))
96  if libs is None or len(libs) <= 0:
97  return None
98  from ctypes import cdll
99  _load = cdll.LoadLibrary
100  from cppyy import loadDict as _load
101  lib = libs[0]
102  self.msg.verbose("... %s",lib)
103  _load (os.path.basename(lib.strip()))
104  self.msg.verbose("... %s [done]",lib)
105  self.msg.verbose(" ==> [ok]")
106 
107  # give the non-massaged name to reflex as this is what it expects
108  # ...ROOT is sooo self-consistent...
109  rflx_type = self._rflx_type (_rflx_name)
110  if rflx_type.Name() != '':
111  return rflx_type
112  return None
113 
114 
115  def visit(self, typename, visitor=None, ctx=None):
116  self.msg.verbose("=== visiting %s", typename)
117  if ctx is None:
118  ctx = set()
119  if isinstance (typename, str):
120  rflx_type = self.load_type (typename)
121  typename = rflx_type.Name (RflxEnums.DICTSCOPE)
122  else:
123  rflx_type = typename
124 
125  if not rflx_type:
126  self.msg.verbose("**warning** no dict for [%s] !!", typename)
127  return ctx
128 
129  ctx.add (typename)
130  if visitor:
131  visitor (rflx_type)
132 
133  if rflx_type.IsClass() or rflx_type.IsStruct():
134  for i in range(rflx_type.BaseSize()):
135  itype = rflx_type.BaseAt(i).ToType()
136  itype_name = itype.Name(RflxEnums.DICTSCOPE)
137  if itype_name != '' and not (itype_name in ctx):
138  self.load_type (itype_name)
139  ctx.add (itype_name)
140  ctx.update (self.visit (itype, visitor, ctx))
141 
142  for i in range(rflx_type.DataMemberSize()):
143  itype = rflx_type.DataMemberAt (i).TypeOf()
144  itype = itype.RawType() if itype.IsPointer() else itype
145  itype_name = itype.Name(RflxEnums.DICTSCOPE)
146  if itype_name != '' and not (itype_name in ctx):
147  self.load_type (itype_name)
148  ctx.add (itype_name)
149  # restore original type
150  itype = rflx_type.DataMemberAt (i).TypeOf()
151  itype_name = itype.Name(RflxEnums.DICTSCOPE)
152  ctx.update (self.visit (itype, visitor, ctx))
153  return ctx
154 
155  pass # class DsoDb
156 
157 
158 registry = _Dso.DsoDb()
python.Dso.DsoDb.rflx_type
def rflx_type(self, typename)
Definition: Control/AthenaServices/python/Dso.py:81
python.Dso.DsoDb.__init__
def __init__(self)
Definition: Control/AthenaServices/python/Dso.py:46
python.Dso.DsoDb.has_type
def has_type(self, typename)
Definition: Control/AthenaServices/python/Dso.py:64
python.Dso.DsoDb.load_type
def load_type(self, typename)
Definition: Control/AthenaServices/python/Dso.py:73
python.Dso.DsoDb
Definition: Control/AthenaServices/python/Dso.py:41
python.Dso.DsoDb.msg
msg
Definition: Control/AthenaServices/python/Dso.py:49
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
python.Dso.DsoDb._rflx_type
_rflx_type
Definition: Control/AthenaServices/python/Dso.py:61
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.Dso.DsoDb.visit
def visit(self, typename, visitor=None, ctx=None)
Definition: Control/AthenaServices/python/Dso.py:115
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:127
pickleTool.object
object
Definition: pickleTool.py:29
python.Dso.RflxEnums
classes ----------------------------------------------------------------—
Definition: Control/AthenaServices/python/Dso.py:34
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87