ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaPython
python
Configurables.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3
# @file: Configurables.py
4
# @purpose: a set of Configurables for the PyAthena components
5
# @author: Sebastien Binet <binet@cern.ch>, Frank Winklmeier
6
# @author: Frank Winklmeier (rewrite for GaudiConfig2)
7
8
import
GaudiConfig2
9
from
AthenaConfiguration.ComponentAccumulator
import
isComponentAccumulatorCfg
10
from
AthenaCommon.Configurable
import
(Configurable
as
LegacyConfigurable,
11
ConfigurableAlgorithm,
12
ConfigurableService,
13
ConfigurableAlgTool,
14
ConfigurableAuditor)
15
16
17
18
class
PyComponents
(object):
19
"""@c PyComponents is a placeholder where all factories for the python
20
components will be collected and stored for easy look-up and call from
21
the C++ side.
22
The @a PyComponents.instances dictionary will store the instance
23
e.g.:
24
PyComponents.instances[ 'alg1' ] = <PyAthena::Alg/alg1 instance>
25
All this boilerplate code will of course be done automatically for the user
26
as soon as she uses the (python) @PyConfigurable classes.
27
"""
28
instances = {}
29
pass
30
31
32
def
_get_prop_value
(pycomp, propname):
33
v = pycomp.properties()[propname]
34
if
v == pycomp.propertyNoValue:
35
from
AthenaCommon.AppMgr
import
ServiceMgr
as
svcMgr
36
if
propname ==
'OutputLevel'
and
hasattr (svcMgr,
'MessageSvc'
):
37
# special case of OutputLevel...
38
v = getattr(svcMgr.MessageSvc, propname)
39
else
:
40
v = pycomp.getDefaultProperty(propname)
41
pass
42
return
v
43
44
45
46
class
CfgPyComponent
:
47
def
__init__
(self, name, **kw):
48
self.
__dict__
[
'__cpp_type__'
] = self.getType()
49
for
n,v
in
kw.items():
50
setattr(self, n, v)
51
52
def
getDlls
(self):
53
return
'AthenaPython'
54
55
@property
56
def
msg
(self):
57
import
AthenaCommon.Logging
as
_L
58
return
_L.logging.getLogger( self.getName() )
59
60
def
getHandle
(self):
61
return
None
62
63
def
__getstate__
(self):
64
state = super().
__getstate__
()
65
state.update(self.
__dict__
)
66
return
state
67
68
def
__setstate__
(self, state):
69
self.
__dict__
.update(state)
70
super().
__setstate__
(state)
71
72
def
setup
(self):
73
if
isinstance(self, LegacyConfigurable):
74
from
AthenaCommon.AppMgr
import
ServiceMgr
as
svcMgr
75
if
not
hasattr( svcMgr,
'PyComponentMgr'
):
76
from
AthenaPython.AthenaPythonCompsConf
import
PyAthena__PyComponentMgr
77
svcMgr += PyAthena__PyComponentMgr(
'PyComponentMgr'
)
78
79
81
self.
OutputLevel
= _get_prop_value (self,
'OutputLevel'
)
82
83
84
o = PyComponents.instances.get(self.getName(),
None
)
85
if
o
is
not
None
and
o
is
not
self:
86
err =
"A python component [%r] has already been "
\
87
"registered with the PyComponents registry !"
% o
88
raise
RuntimeError(err)
89
PyComponents.instances[self.getName()] = self
90
91
def
merge
(self, other):
92
"""Basic merge for Python components.
93
Checks that all attributes/properties are identical.
94
"""
95
if
self
is
other:
96
return
self
97
98
if
type
(self)
is
not
type
(other):
99
raise
TypeError(f
"cannot merge instance of {type(other).__name__} into "
100
f
"an instance of { type(self).__name__}"
)
101
102
if
self.name != other.name:
103
raise
ValueError(f
"cannot merge configurables with different names ({self.name} and {other.name})"
)
104
105
for
prop
in
other.__dict__:
106
if
(hasattr(self, prop)
and
getattr(self, prop) == getattr(other, prop)):
107
continue
108
else
:
109
raise
ValueError(f
"conflicting settings for property {prop} of {self.name}: "
110
f
"{getattr(self,prop)} vs {getattr(other,prop)}"
)
111
return
self
112
113
114
120
if
isComponentAccumulatorCfg():
121
_alg_base = _svc_base = _tool_base = _aud_base = GaudiConfig2.Configurable
122
else
:
123
_alg_base = ConfigurableAlgorithm
124
_svc_base = ConfigurableService
125
_tool_base = ConfigurableAlgTool
126
_aud_base = ConfigurableAuditor
127
128
129
130
class
CfgPyAlgorithm
(
CfgPyComponent
, _alg_base ):
131
def
__init__
( self, name, **kw ):
132
if
isinstance(self, LegacyConfigurable):
133
_alg_base.__init__(self, name)
134
else
:
135
_alg_base.__init__(self, name, **kw)
136
CfgPyComponent.__init__(self, name, **kw)
137
138
def
getGaudiType
( self ):
return
'Algorithm'
139
def
getType(self):
return
'PyAthena::Alg'
140
141
def
setup
(self):
142
143
from
AthenaPython
import
PyAthena
144
setattr(PyAthena.algs, self.getName(), self)
145
146
147
CfgPyComponent.setup(self)
148
if
isinstance(self, LegacyConfigurable):
149
ConfigurableAlgorithm.setup(self)
150
151
152
153
class
CfgPyService
(
CfgPyComponent
, _svc_base ):
154
def
__init__
( self, name, **kw ):
155
if
isinstance(self, LegacyConfigurable):
156
_svc_base.__init__(self, name)
157
else
:
158
_svc_base.__init__(self, name, **kw)
159
CfgPyComponent.__init__(self, name, **kw)
160
161
def
getGaudiType
( self ):
return
'Service'
162
def
getType(self):
return
'PyAthena::Svc'
163
164
def
setup
(self):
165
166
from
AthenaPython
import
PyAthena
167
setattr(PyAthena.services, self.getName(), self)
168
169
170
CfgPyComponent.setup(self)
171
if
isinstance(self, LegacyConfigurable):
172
_svc_base.setup(self)
173
174
175
176
class
CfgPyAlgTool
(
CfgPyComponent
, _tool_base ):
177
def
__init__
( self, name, **kw ):
178
if
isinstance(self, LegacyConfigurable):
179
_tool_base.__init__(self, name)
180
else
:
181
_tool_base.__init__(self, name, **kw)
182
CfgPyComponent.__init__(self, name, **kw)
183
184
def
getGaudiType
( self ):
return
'AlgTool'
185
def
getType(self):
return
'PyAthena::Tool'
186
187
def
setup
(self):
188
CfgPyComponent.setup(self)
189
if
isinstance(self, LegacyConfigurable):
190
_tool_base.setup(self)
191
192
193
194
class
CfgPyAud
(
CfgPyComponent
, _aud_base ):
195
def
__init__
( self, name, **kw ):
196
_aud_base.__init__(self, name)
197
CfgPyComponent.__init__(self, name, **kw)
198
199
def
getGaudiType
( self ):
return
'Auditor'
200
def
getType(self):
return
'PyAthena::Aud'
201
202
def
setup
(self):
203
CfgPyComponent.setup(self)
204
if
isinstance(self, LegacyConfigurable):
205
_aud_base.setup(self)
206
207
208
209
class
_PyCompHandle
(object):
210
"""a class to mimic the gaudi C++ {Tool,Svc}Handle classes: automatic call
211
to `initialize` when __getattr__ is called on the instance.
212
"""
213
def
__init__
(self, parent, attr_name):
214
msg = parent.msg.verbose
215
try
:
216
parentName=parent.name()
217
except
TypeError:
218
parentName=parent.name
219
msg
(
'installing py-comp-handle for [%s.%s]...'
,
220
parentName, attr_name)
221
self.__dict__.update({
222
'_parent'
: parent,
223
'_name'
: attr_name,
224
'_attr'
: getattr(parent, attr_name),
225
'_init_called'
:
False
,
226
})
227
msg
(
'installing py-comp-handle for [%s.%s]... [done]'
,
228
parentName, attr_name)
229
return
230
231
def
_init_once
(self, obj):
232
if
self.__dict__[
'_init_called'
]:
233
return
234
parent = self.__dict__[
'_parent'
]
235
# FIXME: should we raise something in case initialize failed ?
236
obj.initialize()
237
self.__dict__[
'_init_called'
] =
True
238
# replace the handle with the proxied object
239
setattr(parent, self.__dict__[
'_name'
], obj)
240
241
def
__getattribute__
(self, n):
242
if
n.startswith(
'_'
):
243
return
super().
__getattribute__
(n)
244
obj = self.__dict__[
'_attr'
]
245
self.
_init_once
(obj)
246
return
getattr(obj, n)
247
248
def
__setattr__
(self, n, v):
249
if
n.startswith(
'_'
):
250
return
super().
__setattr__
(n,v)
251
obj = self.__dict__[
'_attr'
]
252
self.
_init_once
(obj)
253
return
setattr(obj, n, v)
254
255
256
def
_is_pycomp
(obj):
257
return
isinstance(
258
obj,
259
(CfgPyAlgorithm, CfgPyService, CfgPyAlgTool, CfgPyAud)
260
)
261
262
def
_install_fancy_attrs
():
263
"""loop over all pycomponents, inspect their attributes and install
264
a handle in place of (sub) pycomponents to trigger the auto-initialize
265
behaviour of (C++) XyzHandles.
266
"""
267
import
PyUtils.Logging
as
L
268
msg = L.logging.getLogger(
'PyComponentMgr'
).verbose
269
comps = PyComponents.instances.items()
270
ncomps = len(comps)
271
msg
(
'installing fancy getattrs... (%i)'
, ncomps)
272
for
k,comp
in
comps:
273
msg
(
'handling [%s]...'
, k)
274
for
attr_name, attr
in
comp.__dict__.items():
275
if
_is_pycomp
(attr):
276
msg
(
' ==> [%s]...'
, attr_name)
277
setattr(comp, attr_name,
278
_PyCompHandle
(parent=comp, attr_name=attr_name))
279
msg
(
' ==> [%s]... [done]'
, attr_name)
280
msg
(
'installing fancy getattrs... (%i) [done]'
,ncomps)
python.Configurables.CfgPyAlgTool
Definition
Configurables.py:176
python.Configurables.CfgPyAlgTool.getGaudiType
getGaudiType(self)
Definition
Configurables.py:184
python.Configurables.CfgPyAlgTool.__init__
__init__(self, name, **kw)
Definition
Configurables.py:177
python.Configurables.CfgPyAlgTool.setup
setup(self)
Definition
Configurables.py:187
python.Configurables.CfgPyAlgorithm
Configurable base class for PyAlgorithms -------------------------------—.
Definition
Configurables.py:130
python.Configurables.CfgPyAlgorithm.getGaudiType
getGaudiType(self)
Definition
Configurables.py:138
python.Configurables.CfgPyAlgorithm.__init__
__init__(self, name, **kw)
Definition
Configurables.py:131
python.Configurables.CfgPyAlgorithm.setup
setup(self)
Definition
Configurables.py:141
python.Configurables.CfgPyAud
Definition
Configurables.py:194
python.Configurables.CfgPyAud.getGaudiType
getGaudiType(self)
Definition
Configurables.py:199
python.Configurables.CfgPyAud.__init__
__init__(self, name, **kw)
Definition
Configurables.py:195
python.Configurables.CfgPyAud.setup
setup(self)
Definition
Configurables.py:202
python.Configurables.CfgPyComponent
Configurable base class for all Py compmonents -------------------------—.
Definition
Configurables.py:46
python.Configurables.CfgPyComponent.__init__
__init__(self, name, **kw)
Definition
Configurables.py:47
python.Configurables.CfgPyComponent.__dict__
__dict__
Definition
Configurables.py:65
python.Configurables.CfgPyComponent.OutputLevel
OutputLevel
special case of the OutputLevel: take the value from the svcMgr.MessageSvc if none already set by use...
Definition
Configurables.py:81
python.Configurables.CfgPyComponent.getHandle
getHandle(self)
Definition
Configurables.py:60
python.Configurables.CfgPyComponent.setup
setup(self)
Definition
Configurables.py:72
python.Configurables.CfgPyComponent.__getstate__
__getstate__(self)
Definition
Configurables.py:63
python.Configurables.CfgPyComponent.__setstate__
__setstate__(self, state)
Definition
Configurables.py:68
python.Configurables.CfgPyComponent.getDlls
getDlls(self)
Definition
Configurables.py:52
python.Configurables.CfgPyService
Definition
Configurables.py:153
python.Configurables.CfgPyService.getGaudiType
getGaudiType(self)
Definition
Configurables.py:161
python.Configurables.CfgPyService.__init__
__init__(self, name, **kw)
Definition
Configurables.py:154
python.Configurables.CfgPyService.setup
setup(self)
Definition
Configurables.py:164
python.Configurables.PyComponents
Definition
Configurables.py:18
python.Configurables._PyCompHandle
Definition
Configurables.py:209
python.Configurables._PyCompHandle.__getattribute__
__getattribute__(self, n)
Definition
Configurables.py:241
python.Configurables._PyCompHandle.__setattr__
__setattr__(self, n, v)
Definition
Configurables.py:248
python.Configurables._PyCompHandle.__init__
__init__(self, parent, attr_name)
Definition
Configurables.py:213
python.Configurables._PyCompHandle._init_once
_init_once(self, obj)
Definition
Configurables.py:231
Configurable
merge
Definition
merge.py:1
python.Configurables._install_fancy_attrs
_install_fancy_attrs()
Definition
Configurables.py:262
python.Configurables._is_pycomp
_is_pycomp(obj)
Definition
Configurables.py:256
python.Configurables._get_prop_value
_get_prop_value(pycomp, propname)
Definition
Configurables.py:32
type
msg
MsgStream & msg
Definition
testRead.cxx:32
Generated on
for ATLAS Offline Software by
1.17.0