5 from GaudiKernel.DataHandle
import DataHandle
6 import GaudiKernel.GaudiHandles
as GaudiHandles
8 from AthenaCommon.Logging
import logging
9 from AthenaCommon.Debugging
import DbgStage
10 from AthenaCommon.CFElements
import (isSequence, findSubSequence, findAlgorithm, iterSequences,
11 checkSequenceConsistency, findAllAlgorithmsByName)
13 from AthenaConfiguration.AccumulatorCache
import AccumulatorCachable
14 from AthenaConfiguration.ComponentFactory
import CompFactory, isComponentAccumulatorCfg
15 from AthenaConfiguration.Deduplication
import deduplicate, deduplicateOne, DeduplicationFailed
16 from AthenaConfiguration.DebuggingContext
import (Context, raiseWithCurrentContext, shortCallStack,
17 createContextForDeduplication)
20 from collections.abc
import Sequence
27 _basicServicesToCreateOrder=(
"CoreDumpSvc/CoreDumpSvc",
28 "GeoModelSvc/GeoModelSvc",
29 "DetDescrCnvSvc/DetDescrCnvSvc")
34 ComponentAccumulator._checkUnmerged =
False
35 atexit.register(__exit)
37 def printProperties(msg, c, nestLevel = 0, printDefaults=False, onlyComponentsOnly=False):
39 propnames=
sorted(c._descriptors.keys())
40 for propname
in propnames:
42 if not printDefaults
and not c.is_property_set(propname):
45 propval=getattr(c,propname)
48 if isinstance(propval,(GaudiConfig2.semantics._ListHelper,
49 GaudiConfig2.semantics._DictHelper,
50 GaudiConfig2.semantics._SetHelper))
and propval.data
is None:
53 if not c.is_property_set(propname)
and propname
in [
"DetStore",
"EvtStore",
"AuditFinalize",
"AuditInitialize",
"AuditReinitialize",
"AuditRestart",
"AuditStart",
"AuditStop",
"AuditTools",
"ExtraInputs",
"ExtraOutputs"]:
56 if isinstance(propval, GaudiConfig2.Configurable):
57 msg.info(
"%s * %s: %s/%s",
" "*nestLevel, propname, propval.__cpp_type__, propval.getName())
62 if isinstance(propval, GaudiHandles.PublicToolHandleArray):
63 ths = [th.getName()
for th
in propval]
64 propstr =
"PublicToolHandleArray([ {0} ])".
format(
', '.
join(ths))
65 elif isinstance(propval, GaudiHandles.PrivateToolHandleArray):
66 msg.info(
"%s * %s: PrivateToolHandleArray of size %s",
" "*nestLevel, propname, len(propval))
68 msg.info(
"%s * %s/%s",
" "*(nestLevel+3), el.__cpp_type__, el.getName())
70 elif isinstance(propval, GaudiHandles.GaudiHandle):
71 propstr =
"Handle( {0} )".
format(propval.typeAndName)
72 elif not onlyComponentsOnly:
73 propstr =
str(propval)
75 msg.info(
"%s * %s: %s",
" "*nestLevel, propname, propstr)
82 if not onlyComponents
or c.getName()
in onlyComponents:
84 elif c.getName()+
'-' in onlyComponents:
85 ret.append((c,
False))
102 ComponentAccumulator initialised with legacy (global) Configurable behavior!
103 CA Deduplication is impossible in this mode.
104 Create the CA using the AthenaCommon.Configurable.ConfigurableCABehavior context manager.
107 self.
_msg=logging.getLogger(
'ComponentAccumulator')
108 if isinstance(sequence, str):
109 kwargs={
'IgnoreFilterPassed' :
True,
110 'StopOverride' :
True }
111 if sequence ==
'AthAlgSeq' :
112 kwargs.setdefault(
'ProcessDynamicDataDependencies',
True)
113 kwargs.setdefault(
'ExtraDataForDynamicConsumers',[])
116 sequence = CompFactory.AthSequencer(sequence, **kwargs)
148 summary =
"This CA contains {0} service(s), {1} conditions algorithm(s), {2} event algorithm(s) and {3} public tool(s):\n"\
153 summary +=
" Private AlgTool: " + self.
_privateTools[-1].getFullJobOptName() +
"\n"
155 summary +=
" Private AlgTool: " + self.
_privateTools.getFullJobOptName() +
"\n"
158 summary +=
" Primary Component: " + self.
_primaryComp.getFullJobOptName() +
"\n"
160 summary +=
" Sequence(s): " +
", ".
join([s.name+(
" (main)" if s == self.
_sequence else "")
for s
in self.
_allSequences]) +
"\n"
176 from AthenaConfiguration.AccumulatorCache
import AccumulatorDecorator
177 AccumulatorDecorator.clearCache()
189 log = logging.getLogger(
"ComponentAccumulator")
190 log.error(
"ComponentAccumulator was never merged. %s\n", self.
_inspect())
192 traceback.print_stack()
193 if getattr(self,
'_privateTools',
None)
is not None:
194 log = logging.getLogger(
"ComponentAccumulator")
195 log.error(
"Deleting a ComponentAccumulator with dangling private tool(s): %s",
199 """Called by AccumulatorCache when deleting item from cache"""
204 state = self.__dict__.
copy()
210 self.__dict__.
update(state)
212 self.
_msg=logging.getLogger(
'ComponentAccumulator')
215 def printCondAlgs(self, summariseProps=False, onlyComponents=[], printDefaults=False, printComponentsOnly=False):
216 self.
_msg.
info(
"Condition Algorithms" )
217 for (c, flag)
in filterComponents (self.
_conditionsAlgs, onlyComponents):
219 if summariseProps
and flag:
229 onlyComponents = [], printDefaults=False, printComponentsOnly=False, printSequenceTreeOnly=False, prefix=None):
230 msg = logging.getLogger(prefix)
if prefix
else self.
_msg
232 msg.info(
"Event Algorithm Sequences" )
234 def printSeqAndAlgs(seq, nestLevel = 0,
235 onlyComponents = []):
237 if name
in seq._properties:
238 return seq._properties[name]
239 return seq._descriptors[name].default
241 msg.info(
"%s\\__ %s (seq: %s %s)",
" "*nestLevel, seq.name,
242 "SEQ" if __prop(
"Sequential")
else "PAR",
245 msg.info(
"%s\\__ %s",
" "*nestLevel, seq.name)
250 printSeqAndAlgs(c, nestLevel, onlyComponents = onlyComponents )
253 msg.info(
"%s\\__ %s (alg) %s",
" "*nestLevel, c.getFullJobOptName(), self.
_componentsContext.
get(c.name,
""))
255 msg.info(
"%s\\__ %s",
" "*nestLevel, c.name )
256 if summariseProps
and flag:
261 msg.info(
"Top sequence %d", n )
262 printSeqAndAlgs(s, onlyComponents = onlyComponents)
264 if printSequenceTreeOnly:
268 onlyComponents = onlyComponents)
269 msg.info(
"Services" )
270 msg.info( [ s[0].name + (
" (created) " if s[0].name
in self.
_servicesToCreate else "")
271 for s
in filterComponents (self.
_services, onlyComponents) ] )
272 msg.info(
"Public Tools" )
274 for (t, flag)
in filterComponents (self.
_publicTools, onlyComponents):
277 if summariseProps
and flag:
280 msg.info(
"Private Tools")
289 msg.info(
"Auditors" )
292 msg.info(
"theApp properties" )
294 msg.info(
" %s : %s", k, v)
298 Returns information about inputs needed and outputs produced by this CA
300 It is a list of dictionaries containing the: type, key, R / W, the component and name of the property via which it is set
302 def __getHandles(comp):
304 for i
in comp.ExtraInputs:
305 io.append({
"type": i.split(
"#")[0],
306 "key": i.split(
"#")[1],
307 "comp": comp.getFullJobOptName(),
309 "prop":
"ExtraInputs"})
310 for i
in comp.ExtraOutputs:
311 io.append({
"type": i.split(
"#")[0],
312 "key": i.split(
"#")[1],
313 "comp": comp.getFullJobOptName(),
315 "prop":
"ExtraOutputs"})
317 for prop, descr
in comp._descriptors.items():
318 if isinstance(descr.default, DataHandle):
319 io.append( {
"type": descr.default.type(),
320 "key": comp._properties[prop]
if prop
in comp._properties
else descr.default.path(),
321 "comp": comp.getFullJobOptName(),
322 "mode": descr.default.mode(),
325 if "PrivateToolHandle" == descr.cpp_type
and prop
in comp._properties:
326 io.extend( __getHandles(comp._properties[prop]) )
327 if "PrivateToolHandleArray" == descr.cpp_type
and prop
in comp._properties:
328 for tool
in getattr(comp, prop):
329 io.extend( __getHandles(tool))
334 ret.extend(__getHandles(comp))
339 """ Adds new sequence. If second argument is present then it is added under another sequence """
342 raise TypeError(
'{} is not a sequence'.
format(newseq.name))
344 if not isinstance(newseq, GaudiConfig2.Configurable):
345 raise ConfigurationError(
'{} is not the Conf2 Sequence, ComponentAccumulator handles only the former'.
format(newseq.name))
348 if len(algorithmsInside) != 0:
349 raise ConfigurationError(
'{} contains algorithms (or sub-sequences contain them). That is not supported. Construct ComponentAccumulator and merge it instead'.
format(newseq.name))
352 if parentName
is None:
359 parent.Members.append(newseq)
360 if "trackSequence" in ComponentAccumulator.debugMode:
365 self.
_msg.warning(
"addEventAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
367 newseq.__cpp_type__, newseq.name)
374 if sequenceName
is None:
380 """Use this method to carry private AlgTool(s) to the caller when returning this ComponentAccumulator.
381 The method accepts either a single private AlgTool or a list of private AlgTools (typically assigned to ToolHandleArray)
384 raise ConfigurationError(
"This ComponentAccumulator holds already a (list of) private tool(s). "
385 "Only one (list of) private tool(s) is allowed")
387 if isinstance(privTool, Sequence):
389 if t.__component_type__ !=
'AlgTool':
390 raise ConfigurationError(
"ComponentAccumulator.setPrivateTools accepts only ConfigurableAlgTools "
391 f
"or lists of ConfigurableAlgTools. Encountered {type(t)} in a list")
393 if privTool.__component_type__ !=
"AlgTool":
394 raise ConfigurationError(
"ComponentAccumulator.setPrivateTools accepts only ConfigurableAlgTools "
395 f
"or lists of ConfigurableAlgTools. Encountered {type(privTool)}")
398 if "trackPrivateTool" in ComponentAccumulator.debugMode:
405 """Get the (list of) private AlgTools from this ComponentAccumulator.
406 The CA will not keep any reference to the AlgTool. Throw an exception if
407 no tools are available unless quiet=True.
410 if not quiet
and tool
is None:
416 """ Merging in the other accumulator and getting the (list of) private AlgTools
417 from this ComponentAccumulator.
420 raise RuntimeError(
"popToolsAndMerge called on object of type None: "
421 "did you forget to return a CA from a config function?")
422 tool = other.popPrivateTools()
427 """ Get the current PerfMon domain. """
431 """ Mark the beginning of a new PerfMon domain. """
432 self.
_msg.
debug(f
"Toggling the current algorithm domain to {name}")
436 """ The actual registry keeps "alg":"domain".
437 This function inverts the registry to get "domain":["algs"].
441 result[v] = [i]
if v
not in result.keys()
else result[v] + [i]
445 """ Return the PerfMon domain of the given algorithm """
449 self.
_msg.
info(f
"Algorithm {name} is not in PerfMon domains registry")
453 """ Add the algorithm to the domains registry. """
457 self.
_msg.
debug(f
"Added algorithm {name} to the PerfMon domain {domain}")
459 if overwrite
and domain:
460 self.
_msg.
info(f
"Reassigned algorithm {name} "
461 f
"from {self._domainsRegistry[name]} "
462 f
"to {domain} PerfMon domain")
465 self.
_msg.
debug(f
"Algorithm {name} is already in the PerfMon "
466 "domain, if you want to reassign do overwrite=True")
469 """ Print the PerfMon domains. """
471 self.
_msg.
info(
":: This CA contains the following PerfMon domains ::")
472 self.
_msg.
info(f
":: There are a total of {len(self._domainsRegistry)} "
473 f
"registered algorithms in {len(invertedDomains)} domains ::")
474 for domain, algs
in invertedDomains.items():
475 self.
_msg.
info(f
"+ Domain : {domain}")
478 self.
_msg.
info(
":: End of PerfMon domains ::")
480 def addEventAlgo(self, algorithms,sequenceName=None,primary=False,domain=None):
481 if not isinstance(algorithms, Sequence):
483 algorithms=[algorithms,]
485 if sequenceName
is None:
497 for algo
in algorithms:
498 if not isinstance(algo, GaudiConfig2.Configurable):
499 raise TypeError(f
"Attempt to add wrong type: {type(algo).__name__} as event algorithm")
501 if algo.__component_type__ !=
"Algorithm":
502 raise TypeError(f
"Attempt to add an {algo.__component_type__} as event algorithm")
512 if not existingAlgInDest:
518 if len(algorithms)>1:
519 self.
_msg.warning(
"Called addEvenAlgo with a list of algorithms and primary==True. "
520 "Designating the first algorithm as primary component")
522 self.
_msg.warning(
"addEventAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
524 algorithms[0].__cpp_type__, algorithms[0].name)
529 if "trackEventAlgo" in ComponentAccumulator.debugMode:
530 for algo
in algorithms:
536 """Get algorithm with `name`"""
542 """Get all algorithms within sequence"""
547 """Add Conditions algorithm"""
548 if not isinstance(algo, GaudiConfig2.Configurable):
549 raise TypeError(f
"Attempt to add wrong type: {type(algo).__name__} as conditions algorithm")
551 if algo.__component_type__ !=
"Algorithm":
552 raise TypeError(f
"Attempt to add wrong type: {algo.__component_type__} as conditions algorithm")
559 self.
_msg.warning(
"addCondAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
561 algo.__cpp_type__, algo.name)
566 if "trackCondAlgo" in ComponentAccumulator.debugMode:
575 """Get all conditions algorithms"""
579 """Get conditions algorithm by name"""
583 """Add service and return the deduplicated instance"""
584 if not isinstance(newSvc, GaudiConfig2.Configurable):
585 raise TypeError(f
"Attempt to add wrong type: {type(newSvc).__name__} as service")
587 if newSvc.__component_type__ !=
"Service":
588 raise TypeError(f
"Attempt to add wrong type: {newSvc.__component_type__} as service")
595 self.
_msg.warning(
"addService: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
597 newSvc.__cpp_type__, newSvc.name)
603 sname = newSvc.getFullJobOptName()
606 if "trackService" in ComponentAccumulator.debugMode:
612 """Add Auditor to ComponentAccumulator and return the deduplicated instance.
613 This function will also create the required AuditorSvc."""
614 if not isinstance(auditor, GaudiConfig2.Configurable):
615 raise TypeError(f
"Attempt to add wrong type: {type(auditor).__name__} as auditor")
617 if auditor.__component_type__ !=
"Auditor":
618 raise TypeError(f
"Attempt to add wrong type: {auditor.__component_type__} as auditor")
623 newAuditor = self.
addService(CompFactory.AuditorSvc(Auditors=[auditor.getFullJobOptName()]))
629 """Add public tool and return the deduplicated instance."""
630 if not isinstance(newTool, GaudiConfig2.Configurable):
631 raise TypeError(f
"Attempt to add wrong type: {type(newTool).__name__} as public AlgTool")
633 if newTool.__component_type__ !=
"AlgTool":
634 raise TypeError(f
"Attempt to add wrong type: {newTool.__component_type__} as public AlgTool")
641 self.
_msg.warning(
"addPublicTool: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
643 newTool.__cpp_type__, newTool.name)
647 if "trackPublicTool" in ComponentAccumulator.debugMode:
654 """Get designated primary component"""
663 """ Merging in the other accumulator and getting the primary component"""
665 raise RuntimeError(
"merge called on object of type None: did you forget to return a CA from a config function?")
666 comp = other.getPrimary()
670 def __getOne(self, allcomps, name=None, typename="???"):
671 selcomps = allcomps
if name
is None else [ t
for t
in allcomps
if t.name == name ]
672 if len( selcomps ) == 0:
675 if len( selcomps ) == 1:
677 nmstr = f
'with name {name} ' if name
else ''
678 raise ConfigurationError(
"Number of {} available {}{} which is != 1 expected by this API".
format(typename, nmstr, len(selcomps)) )
684 """Returns single public tool, exception if either not found or to many found"""
691 """Returns single service, exception if either not found or to many found"""
693 return self._primarySvc
698 """Retuns a single auditor, exception if not found"""
703 lenBefore=len(s.Members)
704 s.Members = [a
for a
in s.Members
if not a.getName()==name]
705 lenAfter=len(s.Members)
706 if lenAfter == lenBefore:
707 self.
_msg.warning(
"Algorithm %s not found in sequence %s",name,sequence)
709 self.
_msg.
info(
"Removed algorithm %s from sequence %s",name,sequence)
713 self.
_msg.warning(
"Algorithm %s not found in self._sequence ???",name)
718 lenBefore=len(s.Members)
719 s.Members = [a
for a
in s.Members
if not a.getName()==name]
720 lenAfter=len(s.Members)
721 if lenAfter == lenBefore:
722 self.
_msg.warning(
"Algorithm %s not found in sequence %s",name,sequence)
724 self.
_msg.
info(
"Removed algorithm %s from sequence %s",name,sequence)
728 self.
_msg.warning(
"Algorithm %s not found in self._sequence ??? Returning 'None'",name)
735 if lenAfter == lenBefore:
736 self.
_msg.warning(
"Condition Algorithm %s not found",name)
738 self.
_msg.
info(
"Removed conditions Algorithm %s",name)
745 if lenAfter == lenBefore:
746 self.
_msg.warning(
"Service %s not found",name)
748 self.
_msg.
info(
"Removed Service %s",name)
755 if lenAfter == lenBefore:
756 self.
_msg.warning(
"Public tool %s not found",name)
758 self.
_msg.
info(
"Removed public tool %s",name)
765 if lenAfter == lenBefore:
766 self.
_msg.warning(
"Auditor %s not found",name)
768 self.
_msg.
info(
"Removed auditor %s",name)
779 self.
_msg.
debug(
"ApplicationMgr property '%s' already set to '%s'.", key, value)
782 self.
_msg.
info(
"ApplicationMgr property '%s' already set to '%s'. Overwriting with %s", key, self.
_theAppProps[key], value)
785 raise DeduplicationFailed(
"AppMgr property {} set twice: {} and {}".
format(key, self.
_theAppProps[key], value))
789 if stage
not in DbgStage.allowed_values:
790 raise RuntimeError(
"Allowed arguments for setDebugStage are [{}]".
format(
",".
join(DbgStage.allowed_values)))
794 def merge(self,other, sequenceName=None):
795 """Merging in the other accumulator"""
797 raise RuntimeError(
"merge called on object of type None: "
798 "did you forget to return a CA from a config function?")
800 if not isinstance(other,ComponentAccumulator):
801 raise TypeError(f
"Attempt to merge wrong type {type(other).__name__}. "
802 "Only instances of ComponentAccumulator can be added")
804 context = (Context.hint
if not ComponentAccumulator.debugMode
else
805 Context(
"When merging the ComponentAccumulator:\n{} \nto:\n{}".
format(other._inspect(), self.
_inspect())))
807 if other._privateTools
is not None:
808 if isinstance(other._privateTools, Sequence):
810 "merge called on ComponentAccumulator with a dangling (array of) private tools\n"))
813 "merge called on ComponentAccumulator with a dangling private tool "
814 f
"{other._privateTools.__cpp_type__}/{other._privateTools.name}"))
816 if not other._isMergable:
818 "Attempted to merge a top level ComponentAccumulator. Revert the order of merging\n"))
820 def mergeSequences( dest, src ):
824 if dest.name == src.name:
826 props = (dest._properties.keys() | src._properties.keys()) - {
'Members'}
827 for seqProp
in props:
829 if dest._properties[seqProp] != src._properties[seqProp]:
831 f
"Merging two sequences with name '{dest.name}' but property '{seqProp}' "
832 f
"has different values: {getattr(dest, seqProp)} vs {getattr(src, seqProp)}")
833 except KeyError
as e:
835 f
"Merging two sequences with name '{dest.name}' but property '{e}' is not "
836 f
"set in one of them")
838 for childIdx, c
in enumerate(src.Members):
842 mergeSequences(sub, c )
844 self.
_msg.
debug(
" Merging sequence %s to a destination sequence %s", c.name, dest.name )
846 for name, existingAlgs
in algorithmsByName.items():
848 algInstance, _, _ = existingAlgs[0]
856 for _, parent, idx
in existingAlgs:
860 dest.Members.append(c)
874 if not existingAlgInDest:
875 self.
_msg.
debug(
" Adding algorithm %s to a sequence %s", c.name, dest.name )
876 dest.Members.append(c)
888 for otherSeq
in other._allSequences:
891 destSeqName = otherSeq.name
892 if sequenceName
and otherSeq == other._sequence:
893 destSeqName = sequenceName
894 self.
_msg.
verbose(
" Will move sequence %s to %s", otherSeq.name, destSeqName )
898 mergeSequences(ourSeq, otherSeq)
900 self.
_msg.
verbose(
" Succeeded to merge sequence %s to %s", otherSeq.name, ourSeq.name )
902 self.
_msg.
verbose(
" Failed to merge sequence %s to any existing one, destination CA will have several top/dangling sequences", otherSeq.name )
912 for name
in other._algorithms:
918 for condAlg
in other._conditionsAlgs:
922 for svc
in other._services:
924 self.
addService(svc, create = svc.getFullJobOptName()
in other._servicesToCreate)
926 for pt
in other._publicTools:
931 for aud
in other._auditors:
936 for (k,v)
in other._theAppProps.items():
939 other._wasMerged=
True
951 """ Declares CA as merged
953 This is temporarily needed by HLT and should not be used elsewhere
958 """ returns iterable over all components """
966 def store(self,outfile, withDefaultHandles=False):
968 Saves CA in pickle form
970 when withDefaultHandles is True, also the handles that are not set are saved
976 if withDefaultHandles:
977 from AthenaConfiguration.Utils
import loadDefaultComps, exposeHandles
981 pickle.dump(self,outfile)
990 ROOT.gROOT.SetBatch(
True)
993 appPropsToSet, mspPropsToSet, bshPropsToSet = self.
gatherProps()
996 from Gaudi.Main
import BootstrapHelper
998 bsh = BootstrapHelper()
999 app = bsh.createApplicationMgr()
1001 for k, v
in appPropsToSet.items():
1002 self.
_msg.
debug(
"Setting property %s : %s", k, v)
1003 app.setProperty(k, v)
1007 msp = app.getService(
"MessageSvc")
1008 for k, v
in mspPropsToSet.items():
1009 self.
_msg.
debug(
"Setting property %s : %s", k, v)
1010 bsh.setProperty(msp, k.encode(), v.encode())
1013 for comp, name, value
in bshPropsToSet:
1014 self.
_msg.
debug(
"Adding %s.%s = %s", comp, name, value)
1015 app.setOption(f
"{comp}.{name}", value)
1028 svc.getFullJobOptName(),
1031 svcToCreate.append(svc.getFullJobOptName())
1034 for bs
in reversed(_basicServicesToCreateOrder):
1035 if bs
in svcToCreate:
1036 svcToCreate.insert(0, svcToCreate.pop( svcToCreate.index(bs) ) )
1038 extSvc.append(
"PyAthena::PyComponentMgr/PyComponentMgr")
1040 appPropsToSet[
"ExtSvc"] =
str(extSvc)
1041 appPropsToSet[
"CreateSvc"] =
str(svcToCreate)
1043 def getCompsToBeAdded(comp, namePrefix=""):
1044 name = namePrefix + comp.getName()
1045 for k, v
in comp._properties.items():
1048 if isinstance(v, GaudiConfig2.Configurable):
1050 bshPropsToSet.append((name, k, v.getFullJobOptName()))
1052 getCompsToBeAdded(v, namePrefix=name +
".")
1054 elif isinstance(v, GaudiHandles.PrivateToolHandleArray):
1056 bshPropsToSet.append(
1057 (name, k,
str([v1.getFullJobOptName()
for v1
in v]),)
1061 getCompsToBeAdded(v1, namePrefix=name +
".")
1066 if isinstance(v, list)
and v
and isinstance(v[0], DataHandle):
1067 v = [
str(x)
for x
in v]
1070 v = [alg.getFullJobOptName()
for alg
in comp.Members]
1071 vstr =
"" if v
is None else str(v)
1072 bshPropsToSet.append((name, k, vstr))
1075 from AthenaPython
import PyAthenaComps
1084 if svc.getName() !=
"MessageSvc":
1085 getCompsToBeAdded(svc)
1086 if isinstance(svc, PySvc):
1089 mspPropsToSet.update((k,
str(v))
for k,v
in svc._properties.items())
1093 getCompsToBeAdded(alg)
1094 if isinstance(alg, PyAlg):
1100 getCompsToBeAdded(alg)
1101 condalgseq.append(alg.getFullJobOptName())
1102 if isinstance(alg, PyAlg):
1104 bshPropsToSet.append((
"AthCondSeq",
"Members",
str(condalgseq)))
1108 getCompsToBeAdded(pt, namePrefix=
"ToolSvc.")
1112 getCompsToBeAdded(aud)
1114 return appPropsToSet, mspPropsToSet, bshPropsToSet
1117 from os
import environ
1118 outpklfile = environ.get(
"PICKLECAFILE",
None)
1119 if outpklfile
is not None:
1121 self.
_msg.
info(
"Storing configuration in pickle file %s",outpklfile)
1122 with open(outpklfile,
"wb")
as f:
1126 self.
_msg.
info(
"Exiting after configuration stage")
1127 from Gaudi.Main
import BootstrapHelper
1128 return BootstrapHelper.StatusCode(
True)
1137 environ[
'TDAQ_ERS_NO_SIGNAL_HANDLERS']=
'1'
1138 from AthenaCommon.Debugging
import allowPtrace, hookDebugger
1147 if maxEvents
is None:
1155 from sys
import exit
1161 self.
_msg.
info(f
"Athena job with pid {os.getpid()}")
1165 sc = app.initialize()
1166 if not sc.isSuccess():
1167 self.
_msg.
error(
"Failed to initialize AppMgr")
1171 if not sc.isSuccess():
1172 self.
_msg.
error(
"Failed to start AppMgr")
1181 from AthenaPython.PyAthena
import py_svc
1182 sg=
py_svc(
"StoreGateSvc/StoreGateSvc")
1185 sc = app.run(maxEvents)
1186 if not sc.isSuccess():
1187 self.
_msg.
error(
"Failure running application")
1196 sc1 = app.terminate()
1200 """ Utility to set properties of components using wildcards
1203 forcomps(ca, "*/HLTTop/*/*Hypo*").OutputLevel=VERBOSE
1205 The components name & locations in the CF tree are translated into the unix like path.
1206 Components of matching path are taken under consideration in setting the property.
1207 If the property is set successfully an INFO message is printed. Else, a warning is printed.
1209 The convention for path of nested components is as follows:
1210 Sequencer - only the name is used in the path
1211 Algorithm - full name - type/instance_name (aka full name) is used
1212 PrivateTools - the name of the property + the type/instance_name are added
1213 PublicTools - are located under ToolSvc/ and type/instance_name is used
1214 Services - located under SvcMgr/ and type/instance_name is used
1216 from AthenaConfiguration.PropSetterProxy
import PropSetterProxy
1217 return PropSetterProxy(self, path)
1221 """Setup and start a useful interactive session including auto-completion and history"""
1225 vars = sys.modules[
'__main__'].__dict__
1226 vars.update(globals())
1227 vars.update(localVarDic)
1230 from AthenaCommon.Interactive
import configureInteractivePrompt
1234 code.interact(local=vars)
1238 print(
"Interactive mode")
1239 print(
"\tThe ComponentAccumulator is known as 'self', you can inspect it but changes are not taken into account.")
1240 print(
"\tThe application is known as 'app' but not yet initialized.")
1241 print(
"\t^D will exit the interactive mode and athena will continue.")
1242 print(
"\texit() will terminate the program now.")
1247 print(
"Interactive mode")
1248 print(
"\tThe application is known as 'app' and initialized.")
1249 print(
"\tYou can process N events with 'app.run(N)'.")
1250 print(
"\tStoreGate is accessible as 'sg'.")
1251 print(
"\t^D will exit the interactive mode and athena will finalize.")
1257 from AthenaConfiguration.LegacySupport
import (conf2toConfigurable,
1263 raise RuntimeError(
"conf2toConfigurable cannot be called in a CA job")
1265 raise RuntimeError(
"CAtoGlobalWrapper cannot be called in a CA job")
1267 raise RuntimeError(
"appendCAtoAthena cannot be called in a CA job")