ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaCommon
python
ConfigurableDb.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3
# File: AthenaCommon/python/ConfigurableDb.py
4
# Author: Sebastien Binet (binet@cern.ch)
5
# Modified: Wim Lavrijsen (WLavrijsen@lbl.gov)
6
# Modified: Marco Clemencic
7
8
"""Provides cfgDb, a Singleton that holds the information on the whereabouts
9
of all the accessible, automatically generated, Configurables.
10
This repository of (informations on) Configurables is used by the PropertyProxy
11
class to locate Configurables and feed the JobOptionsSvc. It could also be used
12
to feed the AthenaEmacs module..."""
13
14
15
__version__ =
'3.0.0'
16
__author__ =
'Sebastien Binet (binet@cern.ch)'
17
18
__all__ = [
'CfgDb'
,
'cfgDb'
,
19
'loadConfigurableDb'
,
'unloadConfigurableDb'
,
20
'getConfigurable'
]
21
22
_transtable = str.maketrans(
'<>&*,: ().'
,
'__rp__s___'
)
23
24
25
def
_fillConfDict
():
26
nFiles =
loadConfigurableDb
()
27
cfgDb.msg.info(
"Read module info for %d configurables from %d genConfDb files"
,
28
len(cfgDb), nFiles )
29
30
if
0 < len( cfgDb.duplicates() ):
31
cfgDb.msg.warning(
"Found %d duplicates among the %d genConfDb files :"
,
32
len(cfgDb.duplicates()), nFiles )
33
cfgDb.msg.warning(
"--------------------------------------------------"
)
34
cfgDb.msg.warning(
" -%s: %s - %s"
,
35
"<component name>"
,
"<module>"
,
"[ <duplicates> ]"
)
36
cfgDb.msg.warning(
"--------------------------------------------------"
)
37
38
dups = cfgDb.duplicates()
39
for
cfgName
in
dups.keys():
40
cfgDb.msg.warning(
" -%s: %s - %s"
,
41
cfgName,
42
cfgDb[cfgName][
'module'
],
43
str([ d[
'module'
]
for
d
in
dups[cfgName]]) )
44
del dups
45
46
else
:
47
cfgDb.msg.info(
"No duplicates have been found: that's good !"
)
48
49
50
51
class
_CfgDb
( dict ):
52
"""
53
A singleton class holding informations about automatically generated
54
Configurables.
55
--> package holding that Configurable
56
--> library holding the components related to that Configurable
57
--> python module holding the Configurable
58
--> a dictionary of duplicates
59
"""
60
61
__slots__ = {
62
'_duplicates'
: { },
63
'_msg'
:
None
,
64
}
65
66
def
__init__
(self):
67
object.__init__( self )
68
self.
_duplicates
= {}
69
self.
_msg
=
None
70
71
@property
72
def
msg
(self):
73
if
self.
_msg
is
None
:
74
75
from
.
import
Logging
76
self.
_msg
= Logging.logging.getLogger(
'ConfigurableDb'
)
77
return
self.
_msg
78
79
def
add
( self, configurable, package, module, lib ):
80
"""Method to populate the Db.
81
It is called from the auto-generated Xyz_confDb.py files (genconf.cpp)
82
@param configurable: the name of the configurable being added
83
@param package: the name of the package which holds this Configurable
84
@param module: the name of the python module holding the Configurable
85
@param lib: the name of the library holding the component(s) (ie: the
86
C++ Gaudi component which is mapped by the Configurable)
87
"""
88
89
cfg = {
'package'
: package,
90
'module'
: module,
91
'lib'
: lib }
92
93
if
configurable
in
self:
94
# check if it comes from the same library...
95
if
cfg[
'lib'
] != self[configurable][
'lib'
]:
96
self.
msg
.
verbose
(
"dup!! [%s] p=%s m=%s lib=%s"
,
97
configurable, package, module, lib )
98
if
configurable
in
self.
_duplicates
:
99
self.
_duplicates
[configurable] += [ cfg ]
100
else
:
101
self.
_duplicates
[configurable] = [ cfg ]
102
103
else
:
104
self.
msg
.
verbose
(
"added [%s] p=%s m=%s lib=%s"
,
105
configurable, package, module, lib )
106
self[configurable] = cfg
107
108
def
duplicates
(self):
109
return
self.
_duplicates
110
111
112
def
_loadModule
(self, fname):
113
f = open(fname)
114
for
i,ll
in
enumerate(f):
115
l = ll.strip()
116
if
l.startswith(
'#'
)
or
len(l) <= 0:
117
continue
118
try
:
119
line = l.split()
120
cname = line[2]
121
pkg = line[0].
split
(
'.'
)[0]
122
module = line[0]
123
lib = line[1]
124
self.
add
(cname, pkg, module, lib)
125
except
Exception:
126
f.close()
127
raise
Exception(
128
"invalid line format: %s:%d: %r"
%
129
(fname, i+1, ll)
130
)
131
f.close()
132
133
134
def
loadConfigurableDb
():
135
"""Load all ConfigurableDb files (modules) holding informations about
136
Configurables available in the release
137
"""
138
139
import
os
140
from
os.path
import
join
as
path_join
141
142
cfgDb.msg.debug(
"loading confDb files..."
)
143
nFiles = 0
144
pathlist = os.getenv(
"LD_LIBRARY_PATH"
,
""
).
split
(os.pathsep)
145
for
path
in
pathlist:
146
if
not
os.path.isdir(path):
147
continue
148
cfgDb.msg.verbose(
"walking in [%s]..."
% path )
149
confDbFiles = [f
for
f
in
[path_join(path, f)
for
f
in
os.listdir(path)
150
if
f.endswith(
'.confdb'
)]
151
if
os.path.isfile(f)]
152
153
# check if we use "*_merged.confdb"
154
mergedConfDbFiles = [f
for
f
in
confDbFiles
155
if
f.endswith(
'_merged.confdb'
)]
156
if
mergedConfDbFiles:
157
# use only the merged ones
158
confDbFiles = mergedConfDbFiles
159
160
for
confDb
in
confDbFiles:
161
cfgDb.msg.debug(
"\t-loading [%s]..."
, confDb )
162
try
:
163
cfgDb._loadModule( confDb )
164
except
Exception
as
err:
165
import
traceback
166
traceback.print_exc()
167
cfgDb.msg.warning(
"Could not load file [%s] !"
, confDb )
168
cfgDb.msg.warning(
"Reason: %s"
, err )
169
nFiles += 1
170
cfgDb.msg.debug(
"loading confDb files... [DONE]"
)
171
nPkgs = len(
set
([k[
'package'
]
for
k
in
cfgDb.values()]) )
172
cfgDb.msg.debug(
"loaded %i confDb packages"
, nPkgs )
173
return
nFiles
174
175
176
177
def
unloadConfigurableDb
():
178
"""UNload all ConfigurableDb files (modules) holding informations about
179
Configurables available in the release:
180
- remove imported modules from sys.modules
181
- clear the configurable Db
182
"""
183
184
confModules =
set
( [ cfgDb.get(k).
get
(
'module'
)
for
k
in
cfgDb ] +
185
[ cfgDb.get(k).
get
(
'package'
)
for
k
in
cfgDb ] )
186
cfgDb.clear()
187
import
sys
188
for
m
in
sys.modules.keys():
189
if
m
in
confModules
or
\
190
m.count(
"_merged_confDb"
) > 0
or
\
191
m.count(
".GaudiHandles"
) > 0
or
\
192
m.count(
"ConfigurableDb"
) > 0
or
\
193
m.count(
"AthenaPython"
) > 0:
194
195
if
hasattr(sys.modules[m],
'__dict__'
):
196
for
i
in
sys.modules[m].__dict__.keys():
197
del sys.modules[m].__dict__[i]
198
del sys.modules[m]
199
del confModules
200
201
202
def
getConfigurable
( className, requester = '', assumeCxxClass = True ):
203
"""Localize and load a Configurable class based on the (C++) class name.
204
"""
205
206
# fill the configurable dict, first time only
207
try
:
208
global
_fillConfDict
209
_fillConfDict
()
210
del _fillConfDict
211
except
NameError:
212
pass
213
214
confClass = className
215
if
assumeCxxClass:
216
# assume className is C++: --> translate to python
217
confClass = str.translate( confClass, _transtable )
218
219
# attempt to retrieve existing information
220
confClassInfo = cfgDb.get( confClass )
221
222
# get the python module, if info available
223
confMod = confClassInfo
and
confClassInfo.get(
'module'
)
224
if
not
confMod:
225
cfgDb.msg.warning(
"%s: Class %s not in database"
, requester, className )
226
return
None
227
228
# load the module
229
try
:
230
mod = __import__( confMod, globals(), locals(), confClass, level=0 )
231
except
ImportError:
232
cfgDb.msg.warning(
"%s: Module %s not found (needed for configurable %s)"
,
233
requester, confMod, className )
234
return
None
235
236
# localize class
237
try
:
238
confClass = getattr( mod, confClass )
239
except
AttributeError:
240
cfgDb.msg.warning(
"%s: Configurable %s not found in module %s"
,
241
requester, confClass, confMod )
242
return
None
243
244
# got this far, assume confClass to be valid
245
cfgDb.msg.debug(
"%s: Found configurable %s in module %s"
,
246
requester, confClass, confMod )
247
248
return
confClass
249
250
251
252
class
_Singleton
( object ):
253
# the object this singleton is holding
254
# No other object will be created...
255
__obj =
_CfgDb
()
256
257
def
__call__
( self ):
258
return
self.
__obj
259
260
CfgDb =
_Singleton
()
261
cfgDb =
CfgDb
()
# default name for CfgDb instance
262
263
del _CfgDb, _Singleton
264
265
266
267
if
__name__ ==
'__main__'
:
268
# we'll get a recursive import, so point to ourselves
269
import
sys, __main__
270
sys.modules[
'AthenaCommon.ConfigurableDb'
] = __main__
# for clients
271
sys.modules[
'ConfigurableDb'
] = __main__
# for siblings
272
273
# retrieve a configurable
274
conf =
getConfigurable
(
'StoreGateSvc'
)
275
276
# now make sure it is what we think it is
277
from
StoreGate.StoreGateConf
import
StoreGateSvc
278
assert( conf
is
StoreGateSvc )
python.ConfigurableDb._CfgDb
singleton holding configurable and loadable information ---------------—
Definition
ConfigurableDb.py:51
python.ConfigurableDb._CfgDb._duplicates
dict _duplicates
Definition
ConfigurableDb.py:68
python.ConfigurableDb._CfgDb._loadModule
_loadModule(self, fname)
Definition
ConfigurableDb.py:112
python.ConfigurableDb._CfgDb.__init__
__init__(self)
Definition
ConfigurableDb.py:66
python.ConfigurableDb._CfgDb._msg
_msg
for messaging
Definition
ConfigurableDb.py:69
python.ConfigurableDb._CfgDb.add
add(self, configurable, package, module, lib)
Definition
ConfigurableDb.py:79
python.ConfigurableDb._CfgDb.msg
msg(self)
Definition
ConfigurableDb.py:72
python.ConfigurableDb._CfgDb.duplicates
duplicates(self)
Definition
ConfigurableDb.py:108
python.ConfigurableDb._Singleton
create configurable DB, and pre-fill it, then clean-up remnants -------—
Definition
ConfigurableDb.py:252
python.ConfigurableDb._Singleton.__call__
__call__(self)
Definition
ConfigurableDb.py:257
python.ConfigurableDb._Singleton.__obj
__obj
Definition
ConfigurableDb.py:255
set
STL class.
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition
hcg.cxx:132
verbose
bool verbose
Definition
hcg.cxx:75
split
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition
hcg.cxx:179
python.ConfigurableDb._fillConfDict
_fillConfDict()
helpers ---------------------------------------------------------------—
Definition
ConfigurableDb.py:25
python.ConfigurableDb.unloadConfigurableDb
unloadConfigurableDb()
function to UNload all ConfigurableDb informations --------------------—
Definition
ConfigurableDb.py:177
python.ConfigurableDb.loadConfigurableDb
loadConfigurableDb()
Definition
ConfigurableDb.py:134
python.ConfigurableDb.getConfigurable
getConfigurable(className, requester='', assumeCxxClass=True)
Definition
ConfigurableDb.py:202
python.ConfigurableDb.CfgDb
CfgDb
Definition
ConfigurableDb.py:260
msg
MsgStream & msg
Definition
testRead.cxx:32
Generated on
for ATLAS Offline Software by
1.17.0