ATLAS Offline Software
Loading...
Searching...
No Matches
python.ConfigurationShelve Namespace Reference

Classes

class  ConfigurationJar
class  ConfigurationShelve
 representation of job databases ========================================== More...

Functions

 storeJobOptionsCatalogue (cfg_fname)
 loadJobOptionsCatalogue (cfg_fname)
 saveToAscii (out, cfgName=None)
 further saving utilities =================================================
 loadFromAscii (fileName, cfgName=None)
 saveToPickle (fileName, cfgName=None)
 loadFromPickle (fileName, cfgName=None)
 cmpConfigs (ref, chk, refName=None, chkName=None)

Variables

str __version__ = '1.1.0'
 data ------------------------------------------------------------------—
str __author__
list __all__

Function Documentation

◆ cmpConfigs()

python.ConfigurationShelve.cmpConfigs ( ref,
chk,
refName = None,
chkName = None )
Helper function to compare 2 configurations.
 @param ref the path to a pickle file where a configuration was stored
 @param chk the path to a pickle file where a configuration was stored
 @param refName the name of the configuration jar to load
 @param chkName the name of the configuration jar to load
if `ref` and/or `chk` are joboptions (ie: their extension is '.py') a shelve
is automatically created on the fly

Definition at line 358 of file ConfigurationShelve.py.

358def cmpConfigs (ref, chk, refName=None, chkName=None):
359 """
360 Helper function to compare 2 configurations.
361 @param ref the path to a pickle file where a configuration was stored
362 @param chk the path to a pickle file where a configuration was stored
363 @param refName the name of the configuration jar to load
364 @param chkName the name of the configuration jar to load
365 if `ref` and/or `chk` are joboptions (ie: their extension is '.py') a shelve
366 is automatically created on the fly
367 """
368 import os
369 _path = os.path
370 ref = _path.expanduser(_path.expandvars(ref))
371 chk = _path.expanduser(_path.expandvars(chk))
372
373 from PyUtils.Decorators import forking
374 # if we are given joboptions, create ConfigurationShelves on the fly
375 @forking
376 def _create_shelve (joboname):
377 from tempfile import NamedTemporaryFile
378 fname = os.path.basename (joboname)
379 fname = os.path.splitext(fname)[0] + '.pkl'
380 fname = NamedTemporaryFile(prefix=fname, suffix='.pkl').name
381 job = [ "from AthenaCommon.Include import include",
382 "include ('%s')" % joboname,
383 "from AthenaCommon.ConfigurationShelve import saveToPickle",
384 "saveToPickle ('%s')" % fname,
385 # exit before actually running the job
386 "raise SystemExit(0)",
387 ]
388 jobofile = NamedTemporaryFile(suffix='.py')
389 map (jobofile.writelines, [l+os.linesep for l in job])
390 jobofile.flush()
391
392 from subprocess import getstatusoutput
393 sc,out = getstatusoutput ('athena.py %s' % jobofile.name)
394
395 jobofile.close()
396 if sc==0:
397 return fname
398 return (sc, out)
399
400 if os.path.splitext(ref)[1]=='.py':
401 print ("::: creating a shelve on the fly for [%s]..."%ref)
402 ref = _create_shelve (ref)
403 if not isinstance(ref, str):
404 raise RuntimeError (
405 'could not create a shelve on the fly:\n%s'%ref[1])
406 import atexit
407 atexit.register (os.unlink, ref)
408
409 if os.path.splitext(chk)[1]=='.py':
410 print ("::: creating a shelve on the fly for [%s]..."%chk)
411 chk = _create_shelve (chk)
412 if not isinstance(chk, str):
413 raise RuntimeError (
414 'could not create a shelve on the fly:\n%s'%chk[1])
415 import atexit
416 atexit.register (os.unlink, chk)
417
418 for fname in (ref, chk):
419 if not _path.exists (fname):
420 raise RuntimeError ('file [%s] does not exist'%fname)
421
422 @forking
423 def _dict_cfg (fname, cfgName):
424 #from PyUtils.odict import OrderedDict as odict
425 jar = loadFromPickle (fname, cfgName)
426 d = list()
427 all_cfgs = dict()
428 all_cfgs.setdefault (dict)
429 def _visit_cfg (cfg):
430 name = cfg.getJobOptName()
431 values = [name]
432 all_cfgs[name] = dict()
433 props = cfg.getProperties()
434 def _get_value (cfg, k, v):
435 _no_value = cfg.propertyNoValue
436 if v == _no_value:
437 v = cfg.getDefaultProperty(k)
438 return v
439
440 from AthenaCommon.Configurable import Configurable
441 for k,v in props.items():
442 if not isinstance(v, Configurable):
443 all_cfgs[name][k] = _get_value(cfg,k,v)
444 else:
445 all_cfgs[name][k] = v.getJobOptName()
446 if v not in cfg.getAllChildren():
447 values.extend (_visit_cfg(v))
448
449 if hasattr(cfg, 'getAllChildren'):
450 for c in cfg.getAllChildren():
451 values.extend (_visit_cfg(c))
452 return values
453
454 for c in jar.athAlgSeq.getChildren():
455 d.extend (_visit_cfg(c))
456
457 for c in jar.ServiceMgr.getChildren():
458 d.extend (_visit_cfg(c))
459 return d, all_cfgs
460
461 ref_list, ref_cfgs = _dict_cfg (ref, refName)
462 chk_list, chk_cfgs = _dict_cfg (chk, chkName)
463
464 report = []
465 addNames,subNames = [],[]
466 if ref_list != chk_list:
467 report.append ("::: configurable list in 'ref' and in 'chk' differ !")
468 addNames = sorted([ n for n in chk_cfgs if not (n in ref_cfgs) ])
469 if len (addNames) > 0:
470 report.append ("::: configurables in 'chk' and not in 'ref':")
471 report.extend ([" + %s" % n for n in addNames])
472 subNames = sorted([ n for n in ref_cfgs if not (n in chk_cfgs) ])
473 if len (subNames) > 0:
474 report.append ("::: configurables in 'ref' and not in 'chk':")
475 report.extend ([" - %s" % n for n in subNames])
476
477 common_cfgs = set (
478 [n for n in ref_list if not (n in addNames or n in subNames)] +
479 [n for n in chk_list if not (n in addNames or n in subNames)]
480 )
481 for n in common_cfgs:
482 ref_cfg = ref_cfgs[n]
483 chk_cfg = chk_cfgs[n]
484 diff_props_report = []
485 for k in ref_cfg.iterkeys():
486 ref_val = str(ref_cfg.get(k, '**N/A**'))
487 chk_val = str(chk_cfg.get(k, '**N/A**'))
488
489 if ref_val != chk_val:
490 diff_props_report.append (" ref: %s = %r" % (k, ref_val))
491 diff_props_report.append (" chk: %s = %r" % (k, chk_val))
492 if len(diff_props_report)>0:
493 report.append ("::: properties differing for [%s]:"%n)
494 report.extend (diff_props_report)
495 return (ref_list, ref_cfgs), (chk_list, chk_cfgs), report

◆ loadFromAscii()

python.ConfigurationShelve.loadFromAscii ( fileName,
cfgName = None )
Helper function to retrieve a configuration from an ASCII file.

Definition at line 329 of file ConfigurationShelve.py.

329def loadFromAscii(fileName, cfgName=None):
330 """
331 Helper function to retrieve a configuration from an ASCII file.
332 """
333 raise NotImplementedError("Sorry no restoration from ASCII file (yet?)")
334

◆ loadFromPickle()

python.ConfigurationShelve.loadFromPickle ( fileName,
cfgName = None )
Helper function to retrieve a configuration from a pickle file

Definition at line 346 of file ConfigurationShelve.py.

346def loadFromPickle(fileName, cfgName=None):
347 """
348 Helper function to retrieve a configuration from a pickle file
349 """
350 if cfgName is None: cfgName = "Snapshot"
351 import os
352 fileName = os.path.expanduser(os.path.expandvars(fileName))
353 shelve = ConfigurationShelve( fileName )
354 # configuration is loaded by side-effects...
355 jar = shelve.retrieve( cfgName )
356 return jar
357

◆ loadJobOptionsCatalogue()

python.ConfigurationShelve.loadJobOptionsCatalogue ( cfg_fname)
Load properties from a pickle file, previously dumped by
storeConfiguration, back into the JobOptionsSvc.

Definition at line 245 of file ConfigurationShelve.py.

245def loadJobOptionsCatalogue( cfg_fname ):
246 """Load properties from a pickle file, previously dumped by
247 storeConfiguration, back into the JobOptionsSvc.
248 """
249 # read jobopt catalogue dump and pycomps back in
250 cfg = open( cfg_fname, 'rb' )
251
252 jocat = pickle.load( cfg )
253 jocfg = pickle.load( cfg )
254 pycomps = pickle.load( cfg )
255
256 cfg.close()
257
258 kw = jocfg[ 'ApplicationMgr' ]
259 from AthenaCommon.AppMgr import theApp
260 theApp.JobOptionsSvcType = kw[ 'JobOptionsSvcType' ]
261 theApp.MessageSvcType = kw[ 'MessageSvcType' ]
262 theApp.getHandle( kw )
263 del jocfg[ 'ApplicationMgr' ]
264
265 # no longer want to call setup(), since there are no Configurables to
266 # setup; it would be a no-op, already, but __build_master_sequence is
267 # broken, so make sure this can't be run ...
268 def noop( self ):
269 pass
270 theApp.__class__.setup = noop
271
272 import AthenaPython.PyAthena as PyAthena
273 josvc = PyAthena.py_svc( 'JobOptionsSvc', createIf = False, iface = 'Gaudi::Interfaces::IOptionsSvc')
274
275 # restore job catalogue entries
276 import GaudiPython.Bindings as gaudi
277 for client in jocat:
278 if client == "ApplicationMgr":
279 # ApplicationMgr properties are already set
280 continue
281 for n,v in jocat[ client ].items():
282 josvc.set( client+'.'+n, v )
283
284 # restore special services properties
285 for client in jocfg:
286 svc = PyAthena.py_svc( client, createIf = False, iface='IProperty' )
287 for n,v in jocfg[ client ].items():
288 # See comment above.
289 p = gaudi.StringProperty()
290 p.setName(n)
291 p.fromString(v).ignore()
292 svc.setProperty( p )
293
294 # pycomps hack-around
295 if pycomps:
296 import AthenaPython.Configurables as _C
297 _C.PyComponents.instances = dict( (p.name, p) for p in pycomps )
298 for p in pycomps:
299 if hasattr( p, 'setup' ):
300 if callable( p.setup ):
301 p.setup()
302
303

◆ saveToAscii()

python.ConfigurationShelve.saveToAscii ( out,
cfgName = None )

further saving utilities =================================================

Helper function to store the current configuration to (ASCII) file

Definition at line 305 of file ConfigurationShelve.py.

305def saveToAscii(out, cfgName=None):
306 """
307 Helper function to store the current configuration to (ASCII) file
308 """
309 import os
310
311 # temporarily set the Configurable log level to make sure that the printout
312 # does not get suppressed
313 from AthenaCommon import Configurable
314 from AthenaCommon import Constants
315 llevel = Configurable.log.level
316 Configurable.log.setLevel( Constants.INFO )
317
318 if cfgName is None: cfgName = "Snapshot"
319 content = ConfigurationJar( cfgName ).content()
320
321 if type(out) is str:
322 out = open( out, "w" )
323 for v in content.values(): out.write( str(v) + os.linesep )
324
325 Configurable.log.setLevel( llevel )
326
327 return
328

◆ saveToPickle()

python.ConfigurationShelve.saveToPickle ( fileName,
cfgName = None )
Helper function to store the current configuration to a pickle file

Definition at line 335 of file ConfigurationShelve.py.

335def saveToPickle(fileName, cfgName=None):
336 """
337 Helper function to store the current configuration to a pickle file
338 """
339 if cfgName is None: cfgName = "Snapshot"
340 shelve = ConfigurationShelve( fileName )
341 jar = ConfigurationJar( cfgName )
342 shelve.store( jar )
343
344 return
345

◆ storeJobOptionsCatalogue()

python.ConfigurationShelve.storeJobOptionsCatalogue ( cfg_fname)
Inspect the 'configured' JobOptionsSvc and existing services,
then dump the properties of each component into a pickle file.

Definition at line 134 of file ConfigurationShelve.py.

134def storeJobOptionsCatalogue( cfg_fname ):
135 """Inspect the 'configured' JobOptionsSvc and existing services,
136 then dump the properties of each component into a pickle file.
137 """
138
139 from collections import defaultdict
140 jocat = defaultdict( dict )
141 jocfg = defaultdict( dict )
142
143 def _fillCfg( client, props ):
144 for p in props:
145 n, v = p
146 if hasattr( v, 'toStringProperty' ):
147 v = str( v.toStringProperty() )
148 elif hasattr( v, 'toString' ):
149 v = str( v.toString() )
150 elif type (v) is float:
151 # str(1.8e12) will give '1.8e+12' in py2
152 # and `1800000000000.0' in py3.
153 # Convert floats like this for consistency.
154 v = '%g'%v
155 else:
156 v = str( v )
157 jocfg[ client ][ n ] = v
158
159 from AthenaCommon.AppMgr import theApp
160 from AthenaCommon.AppMgr import ServiceMgr as svcMgr
161 from AthenaCommon.Configurable import Configurable as C
162
163 # tickle the Gaudi C++ side and configure the ApplicationMgr
164 theApp.setup( recursive = True )
165
166 app_props = [ (k,v.value())
167 for k,v in theApp.getHandle().properties().items() ]
168 _fillCfg( 'ApplicationMgr', app_props )
169
170 # get all services that now already exist, as they require special treatment;
171 # the appmgr handle talks directly to the ServiceManager and services() returns
172 # a copy of the services names
173 svcs = theApp.getHandle().services()
174
175 # now assume that if these services carry configuration, then they should exist
176 # on the service manager configurable
177 for svcname in svcs:
178 svc = getattr( svcMgr, svcname, None )
179 if svc:
180 _fillCfg( svcname, svc.getValuedProperties().items() )
181
182 # make sure to propagate the EventLoop properties through the josvc
183 try:
184 evLoopName = theApp.EventLoop.split('/')[-1]
185 evLoop = getattr( svcMgr, evLoopName )
186
187 props = []
188 for k,v in evLoop.properties().items():
189 if v != C.propertyNoValue:
190 props.append( (k,v) )
191 _fillCfg( evLoopName, props )
192
193 except AttributeError:
194 pass # no properties defined for EventLoop type
195
196 # get the values for all other components (these may contain duplicates of
197 # the ones above in svcs, and there may even be conflicts)
198 import AthenaPython.PyAthena as PyAthena
199 josvc = PyAthena.py_svc( 'JobOptionsSvc',iface="Gaudi::Interfaces::IOptionsSvc")
200 allProps=josvc.items() #a std::tuple<string,string>
201 for prop in allProps:
202 cn=str(prop._0).split(".")
203 v=str(prop._1)
204 client=".".join(cn[:-1])
205 n=cn[-1]
206 jocat[ client ][ n ] = v
207
208 # take care of some ancient history
209 for k in ( 'Go', 'Exit' ):
210 if k in jocfg[ 'ApplicationMgr' ]:
211 del jocfg[ 'ApplicationMgr' ][k]
212
213 # workaround for pycomps
214 pycomps = []
215 for c in C.allConfigurables.values():
216 if not isinstance( c, (PyAthena.Alg,
217 PyAthena.AlgTool,
219 PyAthena.Aud) ):
220 continue
221 # FIXME: should check if the component is still 'active'
222 # ie: is it in one of the TopAlg,SvcMgr,ToolSvc and children ?
223 try:
224 delattr( c, 'msg' )
225 except AttributeError:
226 pass
227
228 pycomps.append( c )
229
230 # write out all parts; start with the jocat, so that it can be loaded by
231 # itself only, if need be
232
233 cfg = open( cfg_fname, 'wb' ) # output pickle file
234
235 pickle.dump( jocat, cfg ) # jobopt catalogue contents
236 pickle.dump( jocfg, cfg ) # special services' properties
237 pickle.dump( pycomps, cfg ) # python components workaround
238
239 cfg.close()
240
241 return cfg_fname
242
243
244#----- loading from DB
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177

Variable Documentation

◆ __all__

list python.ConfigurationShelve.__all__
private
Initial value:
1= [ 'ConfigurationShelve', 'ConfigurationJar',
2 'saveToAscii', 'loadFromAscii',
3 'saveToPickle', 'loadFromPickle',
4 'cmpConfigs',
5 ]

Definition at line 30 of file ConfigurationShelve.py.

◆ __author__

str python.ConfigurationShelve.__author__
private
Initial value:
1= """\
2Wim Lavrijsen (WLavrijsen@lbl.gov),
3Sebastien Binet <binet@cern.ch>"""

Definition at line 26 of file ConfigurationShelve.py.

◆ __version__

str python.ConfigurationShelve.__version__ = '1.1.0'
private

data ------------------------------------------------------------------—

Definition at line 25 of file ConfigurationShelve.py.