ATLAS Offline Software
Loading...
Searching...
No Matches
python.ComponentAccumulator.ComponentAccumulator Class Reference
Inheritance diagram for python.ComponentAccumulator.ComponentAccumulator:
Collaboration diagram for python.ComponentAccumulator.ComponentAccumulator:

Public Member Functions

 __init__ (self, sequence='AthAlgSeq')
 setAsTopLevel (self)
 empty (self)
 __del__ (self)
 __getstate__ (self)
 __setstate__ (self, state)
 printCondAlgs (self, summariseProps=False, onlyComponents=[], printDefaults=False)
 printConfig (self, withDetails=False, summariseProps=False, onlyComponents=[], printDefaults=False, printSequenceTreeOnly=False, prefix=None)
 getIO (self)
 addSequence (self, newseq, primary=False, parentName=None)
 getSequence (self, sequenceName=None)
 setPrivateTools (self, privTool)
 popPrivateTools (self, quiet=False)
 popToolsAndMerge (self, other)
 getCurrentPerfmonDomain (self)
 flagPerfmonDomain (self, name)
 getInvertedPerfmonDomains (self)
 getAlgPerfmonDomain (self, name)
 addAlgToPerfmonDomains (self, name, domain, overwrite=False)
 printPerfmonDomains (self)
 addEventAlgo (self, algorithms, sequenceName=None, primary=False, domain=None)
 getEventAlgo (self, name=None)
 getEventAlgos (self, seqName=None)
 addCondAlgo (self, algo, primary=False, domain=None)
 getCondAlgos (self)
 getCondAlgo (self, name)
 addService (self, newSvc, primary=False, create=False)
 addAuditor (self, auditor)
 addPublicTool (self, newTool, primary=False)
 getPrimary (self)
 getPrimaryAndMerge (self, other)
 getPublicTools (self)
 getPublicTool (self, name=None)
 getServices (self)
 getService (self, name=None)
 getAuditor (self, name)
 dropEventAlgo (self, name, sequence="AthAlgSeq")
 popEventAlgo (self, name, sequence="AthAlgSeq")
 dropCondAlgo (self, name)
 dropService (self, name)
 dropPublicTool (self, name)
 dropAuditor (self, name)
 getAppProps (self)
 setAppProperty (self, key, value, overwrite=False)
 setDebugStage (self, stage)
 merge (self, other, sequenceName=None)
 wasMerged (self)
 store (self, outfile, withDefaultHandles=False)
 createApp (self)
 gatherProps (self)
 run (self, maxEvents=None)
 foreach_component (self, path)

Public Attributes

str interactive = ""

Static Public Attributes

str debugMode = ""

Protected Member Functions

 _inspect (self)
 _cleanup (self)
 _cacheEvict (self)
 _allComponents (self)

Protected Attributes

 _msg = logging.getLogger('ComponentAccumulator')
 _sequence = sequence
list _allSequences = [self._sequence]
dict _algorithms = {}
list _conditionsAlgs = []
list _services = []
list _servicesToCreate = []
list _auditors = []
 _privateTools = None
 _primaryComp = None
 _currentDomain = None
dict _domainsRegistry = {}
 _theAppProps = dict()
list _publicTools = []
bool _wasMerged = False
bool _isMergable = True
str _lastAddedComponent = "Unknown"
str _creationCallStack = Context.hint if "trackCA" not in ComponentAccumulator.debugMode else shortCallStack()
 _componentsContext = dict()
 _debugStage = DbgStage()

Static Protected Attributes

bool _checkUnmerged = True

Private Member Functions

 __getOne (self, allcomps, name=None, typename="???")
 __verifyFinalSequencesStructure (self)

Detailed Description

Definition at line 73 of file ComponentAccumulator.py.

Constructor & Destructor Documentation

◆ __init__()

python.ComponentAccumulator.ComponentAccumulator.__init__ ( self,
sequence = 'AthAlgSeq' )

Definition at line 80 of file ComponentAccumulator.py.

80 def __init__(self,sequence='AthAlgSeq'):
81 # Ensure that we are not operating in the legacy Athena Configurable mode
82 # where only a single global instance exists
83 if not isComponentAccumulatorCfg():
84 raise ConfigurationError(
85 """
86 ComponentAccumulator initialised with legacy (global) Configurable behavior!
87 CA Deduplication is impossible in this mode.
88 Create the CA using the AthenaCommon.Configurable.ConfigurableCABehavior context manager.
89 """
90 )
91 self._msg=logging.getLogger('ComponentAccumulator')
92 if isinstance(sequence, str):
93 kwargs={'IgnoreFilterPassed' : True,
94 'StopOverride' : True }
95 if sequence == 'AthAlgSeq' :
96 kwargs.setdefault('ProcessDynamicDataDependencies',True)
97 kwargs.setdefault('ExtraDataForDynamicConsumers',[])
98
99 # (Nested) default sequence of event processing algorithms per sequence + their private tools
100 sequence = CompFactory.AthSequencer(sequence, **kwargs)
101
102 self._sequence = sequence
103 self._allSequences = [self._sequence]
104 self._algorithms = {} #Dictionary of algorithm instances keyed by name
105 self._conditionsAlgs = [] #Unordered list of conditions algorithms + their private tools
106 self._services = [] #List of service, not yet sure if the order matters here in the MT age
107 self._servicesToCreate = []
108 self._auditors = [] #List of auditors
109 self._privateTools = None #A placeholder to carry a private tool(s) not yet attached to its parent
110 self._primaryComp = None #A placeholder to designate the primary service
111 self._currentDomain = None #Currently marked PerfMon domain
112 self._domainsRegistry = {} #PerfMon domains registry
113
114 self._theAppProps = dict() #Properties of the ApplicationMgr
115
116 #Backward compatibility hack: Allow also public tools:
117 self._publicTools = []
118
119 #To check if this accumulator was merged:
120 self._wasMerged = False
121 self._isMergable = True
122 self._lastAddedComponent = "Unknown"
123 self._creationCallStack = Context.hint if "trackCA" not in ComponentAccumulator.debugMode else shortCallStack()
124 self._componentsContext = dict()
125 self._debugStage = DbgStage()
126 self.interactive = ""
127

◆ __del__()

python.ComponentAccumulator.ComponentAccumulator.__del__ ( self)

Definition at line 171 of file ComponentAccumulator.py.

171 def __del__(self):
172 if self._checkUnmerged and not getattr(self,'_wasMerged',True) and not self.empty():
173 log = logging.getLogger("ComponentAccumulator")
174 log.error("ComponentAccumulator was never merged. %s\n", self._inspect())
175 import traceback
176 traceback.print_stack()
177 if getattr(self,'_privateTools',None) is not None:
178 log = logging.getLogger("ComponentAccumulator")
179 log.error("Deleting a ComponentAccumulator with dangling private tool(s): %s",
180 " ".join([t.name for t in self._privateTools]) if isinstance(self._privateTools, Sequence) else self._privateTools.name)
181

Member Function Documentation

◆ __getOne()

python.ComponentAccumulator.ComponentAccumulator.__getOne ( self,
allcomps,
name = None,
typename = "???" )
private

Definition at line 654 of file ComponentAccumulator.py.

654 def __getOne(self, allcomps, name=None, typename="???"):
655 selcomps = allcomps if name is None else [ t for t in allcomps if t.name == name ]
656 if len( selcomps ) == 0:
657 raise ConfigurationError(f"Requested component of name {name} but is missing" )
658
659 if len( selcomps ) == 1:
660 return selcomps[0]
661 nmstr = f'with name {name} ' if name else ''
662 raise ConfigurationError("Number of {} available {}{} which is != 1 expected by this API".format(typename, nmstr, len(selcomps)) )
663

◆ __getstate__()

python.ComponentAccumulator.ComponentAccumulator.__getstate__ ( self)

Definition at line 187 of file ComponentAccumulator.py.

187 def __getstate__(self):
188 state = self.__dict__.copy()
189 # Remove the unpicklable entries.
190 del state['_msg']
191 return state
192

◆ __setstate__()

python.ComponentAccumulator.ComponentAccumulator.__setstate__ ( self,
state )

Definition at line 193 of file ComponentAccumulator.py.

193 def __setstate__(self,state):
194 self.__dict__.update(state)
195 #Re-enstate logger
196 self._msg=logging.getLogger('ComponentAccumulator')
197
198

◆ __verifyFinalSequencesStructure()

python.ComponentAccumulator.ComponentAccumulator.__verifyFinalSequencesStructure ( self)
private

Definition at line 928 of file ComponentAccumulator.py.

928 def __verifyFinalSequencesStructure(self):
929 if len(self._allSequences) != 1:
930 raiseWithCurrentContext(ConfigurationError('It is not allowed for the storable CA to have more than one top sequence, now it has: {}'
931 .format(','.join([ s.name for s in self._allSequences]))))
932
933

◆ _allComponents()

python.ComponentAccumulator.ComponentAccumulator._allComponents ( self)
protected
returns iterable over all components 

Definition at line 941 of file ComponentAccumulator.py.

941 def _allComponents(self):
942 """ returns iterable over all components """
943 import itertools
944 return itertools.chain(self._publicTools,
945 self._privateTools if self._privateTools else [],
946 self._algorithms.values(),
947 self._conditionsAlgs)
948
949

◆ _cacheEvict()

python.ComponentAccumulator.ComponentAccumulator._cacheEvict ( self)
protected
Called by AccumulatorCache when deleting item from cache

Definition at line 182 of file ComponentAccumulator.py.

182 def _cacheEvict(self):
183 """Called by AccumulatorCache when deleting item from cache"""
184 self.popPrivateTools(quiet=True)
185 self.wasMerged()
186

◆ _cleanup()

python.ComponentAccumulator.ComponentAccumulator._cleanup ( self)
protected

Definition at line 149 of file ComponentAccumulator.py.

149 def _cleanup(self):
150 # Delete internal data structures, to be called after all properties are transferred to the C++ application
151 del self._sequence
152 del self._allSequences
153 del self._algorithms
154 del self._conditionsAlgs
155 del self._services
156 del self._publicTools
157 del self._auditors
158
159 # Clear all AccumulatorCaches
160 from AthenaConfiguration.AccumulatorCache import AccumulatorDecorator
161 AccumulatorDecorator.clearCache()
162
163 # Run garbage collector
164 import gc
165 gc.collect()
166

◆ _inspect()

python.ComponentAccumulator.ComponentAccumulator._inspect ( self)
protected

Definition at line 131 of file ComponentAccumulator.py.

131 def _inspect(self): #Create a string some basic info about this CA, useful for debugging
132 summary = "This CA contains {0} service(s), {1} conditions algorithm(s), {2} event algorithm(s) and {3} public tool(s):\n"\
133 .format(len(self._services),len(self._conditionsAlgs),len(self._algorithms),len(self._publicTools))
134
135 if self._privateTools:
136 if isinstance(self._privateTools, list):
137 summary += " Private AlgTool: " + self._privateTools[-1].getFullJobOptName() + "\n"
138 else:
139 summary += " Private AlgTool: " + self._privateTools.getFullJobOptName() + "\n"
140
141 if self._primaryComp:
142 summary += " Primary Component: " + self._primaryComp.getFullJobOptName() + "\n"
143
144 summary += " Sequence(s): " + ", ".join([s.name+(" (main)" if s == self._sequence else "") for s in self._allSequences]) + "\n"
145 summary += " Last component added: " + self._lastAddedComponent+"\n"
146 summary += " Created by: " + self._creationCallStack
147 return summary
148

◆ addAlgToPerfmonDomains()

python.ComponentAccumulator.ComponentAccumulator.addAlgToPerfmonDomains ( self,
name,
domain,
overwrite = False )
Add the algorithm to the domains registry. 

Definition at line 436 of file ComponentAccumulator.py.

436 def addAlgToPerfmonDomains(self, name, domain, overwrite=False):
437 """ Add the algorithm to the domains registry. """
438 if name not in self._domainsRegistry:
439 if domain:
440 self._domainsRegistry[name] = domain
441 self._msg.debug(f"Added algorithm {name} to the PerfMon domain {domain}")
442 else:
443 if overwrite and domain:
444 self._msg.info(f"Reassigned algorithm {name} "
445 f"from {self._domainsRegistry[name]} "
446 f"to {domain} PerfMon domain")
447 self._domainsRegistry[name] = domain
448 else:
449 self._msg.debug(f"Algorithm {name} is already in the PerfMon "
450 "domain, if you want to reassign do overwrite=True")
451
const bool debug

◆ addAuditor()

python.ComponentAccumulator.ComponentAccumulator.addAuditor ( self,
auditor )
Add Auditor to ComponentAccumulator and return the deduplicated instance.
This function will also create the required AuditorSvc.

Definition at line 595 of file ComponentAccumulator.py.

595 def addAuditor(self, auditor):
596 """Add Auditor to ComponentAccumulator and return the deduplicated instance.
597 This function will also create the required AuditorSvc."""
598 if not isinstance(auditor, GaudiConfig2.Configurable):
599 raise TypeError(f"Attempt to add wrong type: {type(auditor).__name__} as auditor")
600
601 if auditor.__component_type__ != "Auditor":
602 raise TypeError(f"Attempt to add wrong type: {auditor.__component_type__} as auditor")
603
604 context = createContextForDeduplication("Merging with existing auditors", auditor.name, self._componentsContext) # noqa : F841
605
606 deduplicate(auditor, self._auditors) #may raise on conflict
607 newAuditor = self.addService(CompFactory.AuditorSvc(Auditors=[auditor.getFullJobOptName()]))
608 self._lastAddedComponent = auditor.name
609 return newAuditor
610
611

◆ addCondAlgo()

python.ComponentAccumulator.ComponentAccumulator.addCondAlgo ( self,
algo,
primary = False,
domain = None )
Add Conditions algorithm

Definition at line 530 of file ComponentAccumulator.py.

530 def addCondAlgo(self,algo,primary=False,domain=None):
531 """Add Conditions algorithm"""
532 if not isinstance(algo, GaudiConfig2.Configurable):
533 raise TypeError(f"Attempt to add wrong type: {type(algo).__name__} as conditions algorithm")
534
535 if algo.__component_type__ != "Algorithm":
536 raise TypeError(f"Attempt to add wrong type: {algo.__component_type__} as conditions algorithm")
537
538 context = createContextForDeduplication("Merging with existing Conditions Algorithm", algo.name, self._componentsContext) # noqa : F841
539
540 deduplicate(algo, self._conditionsAlgs) #will raise on conflict
541 if primary:
542 if self._primaryComp:
543 self._msg.warning("addCondAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
544 self._primaryComp.__cpp_type__, self._primaryComp.name,
545 algo.__cpp_type__, algo.name)
546 #keep a ref of the de-duplicated conditions algorithm as primary component
547 self._primaryComp = self.__getOne(self._conditionsAlgs, algo.name, "ConditionsAlgos")
548
549 self._lastAddedComponent=algo.name
550 if "trackCondAlgo" in ComponentAccumulator.debugMode:
551 self._componentsContext[algo.name] = shortCallStack()
552
553 # Assign the algorithm to a domain
554 self.addAlgToPerfmonDomains(algo.name, 'Conditions' if not domain else domain)
555
556 return algo
557

◆ addEventAlgo()

python.ComponentAccumulator.ComponentAccumulator.addEventAlgo ( self,
algorithms,
sequenceName = None,
primary = False,
domain = None )

Definition at line 464 of file ComponentAccumulator.py.

464 def addEventAlgo(self, algorithms,sequenceName=None,primary=False,domain=None):
465 if not isinstance(algorithms, Sequence):
466 #Swallow both single algorithms as well as lists or tuples of algorithms
467 algorithms=[algorithms,]
468
469 if sequenceName is None:
470 # If there is an AthAlgSeq add the event algorithm there by default
471 # See ATEAM-825 for a more detailed discussion for this choice
472 seq = findSubSequence(self._sequence, 'AthAlgSeq')
473 if seq is None:
474 seq = self._sequence
475 else:
476 seq = findSubSequence(self._sequence, sequenceName)
477 if seq is None:
478 self.printConfig()
479 raise ConfigurationError("Can not find sequence {}".format(sequenceName))
480
481 for algo in algorithms:
482 if not isinstance(algo, GaudiConfig2.Configurable):
483 raise TypeError(f"Attempt to add wrong type: {type(algo).__name__} as event algorithm")
484
485 if algo.__component_type__ != "Algorithm":
486 raise TypeError(f"Attempt to add an {algo.__component_type__} as event algorithm")
487
488 if algo.name in self._algorithms:
489 context = createContextForDeduplication("Merging with existing Event Algorithm", algo.name, self._componentsContext) # noqa : F841
490 deduplicateOne(algo, self._algorithms[algo.name])
491 deduplicateOne(self._algorithms[algo.name], algo)
492 else:
493 self._algorithms[algo.name]=algo
494
495 existingAlgInDest = findAlgorithm(seq, algo.name)
496 if not existingAlgInDest:
497 seq.Members.append(self._algorithms[algo.name])
498 # Assign the algorithm to a domain
499 self.addAlgToPerfmonDomains(algo.name, self._currentDomain if not domain else domain)
500
501 if primary:
502 if len(algorithms)>1:
503 self._msg.warning("Called addEvenAlgo with a list of algorithms and primary==True. "
504 "Designating the first algorithm as primary component")
505 if self._primaryComp:
506 self._msg.warning("addEventAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
507 self._primaryComp.__cpp_type__, self._primaryComp.name,
508 algorithms[0].__cpp_type__, algorithms[0].name)
509 #keep a ref of the algorithm as primary component
510 self._primaryComp = algorithms[0]
511 self._lastAddedComponent = algorithms[-1].name
512
513 if "trackEventAlgo" in ComponentAccumulator.debugMode:
514 for algo in algorithms:
515 self._componentsContext[algo.name] = shortCallStack()
516
517 return None
518

◆ addPublicTool()

python.ComponentAccumulator.ComponentAccumulator.addPublicTool ( self,
newTool,
primary = False )
Add public tool and return the deduplicated instance.

Definition at line 612 of file ComponentAccumulator.py.

612 def addPublicTool(self, newTool, primary=False):
613 """Add public tool and return the deduplicated instance."""
614 if not isinstance(newTool, GaudiConfig2.Configurable):
615 raise TypeError(f"Attempt to add wrong type: {type(newTool).__name__} as public AlgTool")
616
617 if newTool.__component_type__ != "AlgTool":
618 raise TypeError(f"Attempt to add wrong type: {newTool.__component_type__} as public AlgTool")
619
620 context = createContextForDeduplication("Merging with existing Public Tool", newTool.name, self._componentsContext) # noqa : F841
621
622 deduplicate(newTool,self._publicTools)
623 if primary:
624 if self._primaryComp:
625 self._msg.warning("addPublicTool: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
626 self._primaryComp.__cpp_type__, self._primaryComp.name,
627 newTool.__cpp_type__, newTool.name)
628 #keep a ref of the de-duplicated tool as primary component
629 self._primaryComp=self.__getOne( self._publicTools, newTool.name, "Public Tool")
630 self._lastAddedComponent=newTool.name
631 if "trackPublicTool" in ComponentAccumulator.debugMode:
632 self._componentsContext[newTool.name] = shortCallStack()
633 # return the new public tool
634 return self.__getOne(self._publicTools, newTool.name, "Public Tool")
635
636

◆ addSequence()

python.ComponentAccumulator.ComponentAccumulator.addSequence ( self,
newseq,
primary = False,
parentName = None )
Adds new sequence. If second argument is present then it is added under another sequence  

Definition at line 322 of file ComponentAccumulator.py.

322 def addSequence(self, newseq, primary=False, parentName = None ):
323 """ Adds new sequence. If second argument is present then it is added under another sequence """
324
325 if not isSequence(newseq):
326 raise TypeError('{} is not a sequence'.format(newseq.name))
327
328 if not isinstance(newseq, GaudiConfig2.Configurable):
329 raise ConfigurationError('{} is not the Conf2 Sequence, ComponentAccumulator handles only the former'.format(newseq.name))
330
331 algorithmsInside = findAllAlgorithmsByName(newseq)
332 if len(algorithmsInside) != 0:
333 raise ConfigurationError('{} contains algorithms (or sub-sequences contain them). That is not supported. Construct ComponentAccumulator and merge it instead'.format(newseq.name))
334
335
336 if parentName is None:
337 parent=self._sequence
338 else:
339 parent = findSubSequence(self._sequence, parentName )
340 if parent is None:
341 raise ConfigurationError("Missing sequence {} to add new sequence to".format(parentName))
342
343 parent.Members.append(newseq)
344 if "trackSequence" in ComponentAccumulator.debugMode:
345 self._componentsContext[newseq] = shortCallStack()
346
347 if primary:
348 if self._primaryComp:
349 self._msg.warning("addEventAlgo: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
350 self._primaryComp.__cpp_type__, self._primaryComp.name,
351 newseq.__cpp_type__, newseq.name)
352 #keep a ref of the sequence as primary component
353 self._primaryComp = newseq
354 return newseq
355
356

◆ addService()

python.ComponentAccumulator.ComponentAccumulator.addService ( self,
newSvc,
primary = False,
create = False )
Add service and return the deduplicated instance

Definition at line 566 of file ComponentAccumulator.py.

566 def addService(self, newSvc, primary=False, create=False):
567 """Add service and return the deduplicated instance"""
568 if not isinstance(newSvc, GaudiConfig2.Configurable):
569 raise TypeError(f"Attempt to add wrong type: {type(newSvc).__name__} as service")
570
571 if newSvc.__component_type__ != "Service":
572 raise TypeError(f"Attempt to add wrong type: {newSvc.__component_type__} as service")
573
574 context = createContextForDeduplication("Merging with existing Service", newSvc.name, self._componentsContext) # noqa : F841
575
576 deduplicate(newSvc, self._services) #may raise on conflict
577 if primary:
578 if self._primaryComp:
579 self._msg.warning("addService: Overwriting primary component of this CA. Was %s/%s, now %s/%s",
580 self._primaryComp.__cpp_type__, self._primaryComp.name,
581 newSvc.__cpp_type__, newSvc.name)
582 #keep a ref of the de-duplicated service as primary component
583 self._primaryComp=self.__getOne( self._services, newSvc.name, "Services")
584 self._lastAddedComponent=newSvc.name
585
586 if create:
587 sname = newSvc.getFullJobOptName()
588 if sname not in self._servicesToCreate:
589 self._servicesToCreate.append(sname)
590 if "trackService" in ComponentAccumulator.debugMode:
591 self._componentsContext[newSvc.name] = shortCallStack()
592 return self.__getOne( self._services, newSvc.name, "Services")
593
594

◆ createApp()

python.ComponentAccumulator.ComponentAccumulator.createApp ( self)

Definition at line 969 of file ComponentAccumulator.py.

969 def createApp(self):
970 # Create the Gaudi object early.
971 # Without this here, pyroot can sometimes get confused
972 # and report spurious type mismatch errors about this object.
973 import ROOT
974 ROOT.gROOT.SetBatch(True)
975 ROOT.Gaudi
976
977 appPropsToSet, mspPropsToSet, bshPropsToSet = self.gatherProps()
978
979 self._wasMerged = True
980 from Gaudi.Main import BootstrapHelper
981
982 bsh = BootstrapHelper()
983 app = bsh.createApplicationMgr()
984
985 for k, v in appPropsToSet.items():
986 self._msg.debug("Setting property %s : %s", k, v)
987 app.setProperty(k, v)
988
989 app.configure()
990
991 msp = app.getService("MessageSvc")
992 for k, v in mspPropsToSet.items():
993 self._msg.debug("Setting property %s : %s", k, v)
994 bsh.setProperty(msp, k.encode(), v.encode())
995
996 # Feed the jobO service with the remaining options
997 for comp, name, value in bshPropsToSet:
998 self._msg.debug("Adding %s.%s = %s", comp, name, value)
999 app.setOption(f"{comp}.{name}", value)
1000
1001 sys.stdout.flush()
1002 return app
1003

◆ dropAuditor()

python.ComponentAccumulator.ComponentAccumulator.dropAuditor ( self,
name )

Definition at line 745 of file ComponentAccumulator.py.

745 def dropAuditor(self,name):
746 lenBefore=len(self._auditors)
747 self._auditors = [a for a in self._auditors if a.getName()!=name]
748 lenAfter=len(self._auditors)
749 if lenAfter == lenBefore:
750 self._msg.warning("Auditor %s not found",name)
751 else:
752 self._msg.info("Removed auditor %s",name)
753 return
754

◆ dropCondAlgo()

python.ComponentAccumulator.ComponentAccumulator.dropCondAlgo ( self,
name )

Definition at line 715 of file ComponentAccumulator.py.

715 def dropCondAlgo(self,name):
716 lenBefore=len(self._conditionsAlgs)
717 self._conditionsAlgs = [a for a in self._conditionsAlgs if a.getName()!=name]
718 lenAfter=len(self._conditionsAlgs)
719 if lenAfter == lenBefore:
720 self._msg.warning("Condition Algorithm %s not found",name)
721 else:
722 self._msg.info("Removed conditions Algorithm %s",name)
723 return
724

◆ dropEventAlgo()

python.ComponentAccumulator.ComponentAccumulator.dropEventAlgo ( self,
name,
sequence = "AthAlgSeq" )

Definition at line 685 of file ComponentAccumulator.py.

685 def dropEventAlgo(self,name,sequence="AthAlgSeq"):
686 s=self.getSequence(sequence)
687 lenBefore=len(s.Members)
688 s.Members = [a for a in s.Members if not a.getName()==name]
689 lenAfter=len(s.Members)
690 if lenAfter == lenBefore:
691 self._msg.warning("Algorithm %s not found in sequence %s",name,sequence)
692 else:
693 self._msg.info("Removed algorithm %s from sequence %s",name,sequence)
694 try:
695 del self._algorithms[name]
696 except KeyError:
697 self._msg.warning("Algorithm %s not found in self._sequence ???",name)
698 return
699

◆ dropPublicTool()

python.ComponentAccumulator.ComponentAccumulator.dropPublicTool ( self,
name )

Definition at line 735 of file ComponentAccumulator.py.

735 def dropPublicTool(self,name):
736 lenBefore=len(self._publicTools)
737 self._publicTools = [p for p in self._publicTools if p.getName()!=name]
738 lenAfter=len(self._publicTools)
739 if lenAfter == lenBefore:
740 self._msg.warning("Public tool %s not found",name)
741 else:
742 self._msg.info("Removed public tool %s",name)
743 return
744

◆ dropService()

python.ComponentAccumulator.ComponentAccumulator.dropService ( self,
name )

Definition at line 725 of file ComponentAccumulator.py.

725 def dropService(self,name):
726 lenBefore=len(self._services)
727 self._services = [s for s in self._services if s.getName()!=name]
728 lenAfter=len(self._services)
729 if lenAfter == lenBefore:
730 self._msg.warning("Service %s not found",name)
731 else:
732 self._msg.info("Removed Service %s",name)
733 return
734

◆ empty()

python.ComponentAccumulator.ComponentAccumulator.empty ( self)

Definition at line 167 of file ComponentAccumulator.py.

167 def empty(self):
168 return (len(self._sequence.Members)+len(self._conditionsAlgs)+len(self._services)+
169 len(self._publicTools)+len(self._theAppProps) == 0)
170
static const Attributes_t empty

◆ flagPerfmonDomain()

python.ComponentAccumulator.ComponentAccumulator.flagPerfmonDomain ( self,
name )
Mark the beginning of a new PerfMon domain. 

Definition at line 414 of file ComponentAccumulator.py.

414 def flagPerfmonDomain(self, name):
415 """ Mark the beginning of a new PerfMon domain. """
416 self._msg.debug(f"Toggling the current algorithm domain to {name}")
417 self._currentDomain = name
418

◆ foreach_component()

python.ComponentAccumulator.ComponentAccumulator.foreach_component ( self,
path )
Utility to set properties of components using wildcards.

Example:
  ca.foreach_component("*/HLTTop/*/*Hypo*").OutputLevel = VERBOSE

The components name and location in the CF tree are translated into a UNIX-like path
and are matched using the `fnmatch` library. If the property is set successfully
an INFO message is printed else a WARNING.

The convention for paths of nested components is as follows:
  Sequence     : only the name is used in the path
  Algorithm    : "type/name" is used
  Private Tool : ToolHandle property name plus "type/name" is used
  Public Tool  : located under "ToolSvc/" and "type/name" is used
  Service      : located under "SvcMgr/" and "type/name" is used

Definition at line 1190 of file ComponentAccumulator.py.

1190 def foreach_component(self, path):
1191 """Utility to set properties of components using wildcards.
1192
1193 Example:
1194 ca.foreach_component("*/HLTTop/*/*Hypo*").OutputLevel = VERBOSE
1195
1196 The components name and location in the CF tree are translated into a UNIX-like path
1197 and are matched using the `fnmatch` library. If the property is set successfully
1198 an INFO message is printed else a WARNING.
1199
1200 The convention for paths of nested components is as follows:
1201 Sequence : only the name is used in the path
1202 Algorithm : "type/name" is used
1203 Private Tool : ToolHandle property name plus "type/name" is used
1204 Public Tool : located under "ToolSvc/" and "type/name" is used
1205 Service : located under "SvcMgr/" and "type/name" is used
1206 """
1207 from AthenaConfiguration.PropSetterProxy import PropSetterProxy
1208 return PropSetterProxy(self, path)
1209
1210

◆ gatherProps()

python.ComponentAccumulator.ComponentAccumulator.gatherProps ( self)

Definition at line 1004 of file ComponentAccumulator.py.

1004 def gatherProps(self):
1005 appPropsToSet = {k: str(v) for k, v in self._theAppProps.items()}
1006 mspPropsToSet = {}
1007 bshPropsToSet = []
1008 svcToCreate = []
1009 extSvc = []
1010 for svc in self._services:
1011 extSvc += [
1012 svc.getFullJobOptName(),
1013 ]
1014 if svc.getFullJobOptName() in self._servicesToCreate:
1015 svcToCreate.append(svc.getFullJobOptName())
1016
1017 # order basic services
1018 for bs in reversed(_basicServicesToCreateOrder):
1019 if bs in svcToCreate:
1020 svcToCreate.insert(0, svcToCreate.pop( svcToCreate.index(bs) ) )
1021
1022 extSvc.append("PyAthena::PyComponentMgr/PyComponentMgr")
1023
1024 appPropsToSet["ExtSvc"] = str(extSvc)
1025 appPropsToSet["CreateSvc"] = str(svcToCreate)
1026
1027 def getCompsToBeAdded(comp, namePrefix=""):
1028 name = namePrefix + comp.getName()
1029 for k, v in comp._properties.items():
1030 # Handle special cases of properties:
1031 # 1.PrivateToolHandles
1032 if isinstance(v, GaudiConfig2.Configurable):
1033 # Add the name of the tool as property to the parent
1034 bshPropsToSet.append((name, k, v.getFullJobOptName()))
1035 # Recursively add properties of this tool to the JobOptionSvc
1036 getCompsToBeAdded(v, namePrefix=name + ".")
1037 # 2. PrivateToolHandleArray
1038 elif isinstance(v, GaudiHandles.PrivateToolHandleArray):
1039 # Add names of tools as properties to the parent
1040 bshPropsToSet.append(
1041 (name, k, str([v1.getFullJobOptName() for v1 in v]),)
1042 )
1043 # Recursively add properties of tools to JobOptionsSvc
1044 for v1 in v:
1045 getCompsToBeAdded(v1, namePrefix=name + ".")
1046 else:
1047 # For a list of DataHandle, we need to stringify
1048 # each element individually. Otherwise, we get the repr
1049 # version of the elements, which Gaudi JO will choke on.
1050 if isinstance(v, list) and v and isinstance(v[0], DataHandle):
1051 v = [str(x) for x in v]
1052 # For sequences, need to convert the list of algs to names
1053 elif isSequence(comp) and k == "Members":
1054 v = [alg.getFullJobOptName() for alg in comp.Members]
1055 vstr = "" if v is None else str(v)
1056 bshPropsToSet.append((name, k, vstr))
1057
1058 try:
1059 from AthenaPython import PyAthenaComps
1060 PyAlg = PyAthenaComps.Alg
1061 PySvc = PyAthenaComps.Svc
1062 except ImportError:
1063 PyAlg = type(None)
1064 PySvc = type(None)
1065
1066 # Services
1067 for svc in self._services:
1068 if svc.getName() != "MessageSvc": # MessageSvc will exist already! Needs special treatment
1069 getCompsToBeAdded(svc)
1070 if isinstance(svc, PySvc):
1071 svc.setup()
1072 else:
1073 mspPropsToSet.update((k,str(v)) for k,v in svc._properties.items())
1074
1075 # Algorithms and Sequences
1076 for alg in iterSequences(self._sequence):
1077 getCompsToBeAdded(alg)
1078 if isinstance(alg, PyAlg):
1079 alg.setup()
1080
1081 # Cond Algs
1082 condalgseq = []
1083 for alg in self._conditionsAlgs:
1084 getCompsToBeAdded(alg)
1085 condalgseq.append(alg.getFullJobOptName())
1086 if isinstance(alg, PyAlg):
1087 alg.setup()
1088 bshPropsToSet.append(("AthCondSeq", "Members", str(condalgseq)))
1089
1090 # Public Tools
1091 for pt in self._publicTools:
1092 getCompsToBeAdded(pt, namePrefix="ToolSvc.")
1093
1094 # Auditors
1095 for aud in self._auditors:
1096 getCompsToBeAdded(aud)
1097
1098 return appPropsToSet, mspPropsToSet, bshPropsToSet
1099

◆ getAlgPerfmonDomain()

python.ComponentAccumulator.ComponentAccumulator.getAlgPerfmonDomain ( self,
name )
Return the PerfMon domain of the given algorithm 

Definition at line 428 of file ComponentAccumulator.py.

428 def getAlgPerfmonDomain(self, name):
429 """ Return the PerfMon domain of the given algorithm """
430 if name in self._domainsRegistry:
431 return self._domainsRegistry[name]
432 else:
433 self._msg.info(f"Algorithm {name} is not in PerfMon domains registry")
434 return None
435

◆ getAppProps()

python.ComponentAccumulator.ComponentAccumulator.getAppProps ( self)

Definition at line 755 of file ComponentAccumulator.py.

755 def getAppProps(self):
756 return self._theAppProps
757

◆ getAuditor()

python.ComponentAccumulator.ComponentAccumulator.getAuditor ( self,
name )
Retuns a single auditor, exception if not found

Definition at line 681 of file ComponentAccumulator.py.

681 def getAuditor(self,name):
682 """Retuns a single auditor, exception if not found"""
683 return self.__getOne(self._auditors,name,"Auditors")
684

◆ getCondAlgo()

python.ComponentAccumulator.ComponentAccumulator.getCondAlgo ( self,
name )
Get conditions algorithm by name

Definition at line 562 of file ComponentAccumulator.py.

562 def getCondAlgo(self, name):
563 """Get conditions algorithm by name"""
564 return self.__getOne( self._conditionsAlgs, name, "conditions algorithms")
565

◆ getCondAlgos()

python.ComponentAccumulator.ComponentAccumulator.getCondAlgos ( self)
Get all conditions algorithms

Definition at line 558 of file ComponentAccumulator.py.

558 def getCondAlgos(self):
559 """Get all conditions algorithms"""
560 return self._conditionsAlgs
561

◆ getCurrentPerfmonDomain()

python.ComponentAccumulator.ComponentAccumulator.getCurrentPerfmonDomain ( self)
Get the current PerfMon domain. 

Definition at line 410 of file ComponentAccumulator.py.

410 def getCurrentPerfmonDomain(self):
411 """ Get the current PerfMon domain. """
412 return self._currentDomain
413

◆ getEventAlgo()

python.ComponentAccumulator.ComponentAccumulator.getEventAlgo ( self,
name = None )
Get algorithm with `name`

Definition at line 519 of file ComponentAccumulator.py.

519 def getEventAlgo(self, name=None):
520 """Get algorithm with `name`"""
521 if name not in self._algorithms:
522 raise ConfigurationError("Can not find an algorithm of name {} ".format(name))
523 return self._algorithms[name]
524

◆ getEventAlgos()

python.ComponentAccumulator.ComponentAccumulator.getEventAlgos ( self,
seqName = None )
Get all algorithms within sequence

Definition at line 525 of file ComponentAccumulator.py.

525 def getEventAlgos(self, seqName=None):
526 """Get all algorithms within sequence"""
527 seq = self._sequence if seqName is None else findSubSequence(self._sequence, seqName )
528 return [s for s in iterSequences(seq) if not isSequence(s)]
529

◆ getInvertedPerfmonDomains()

python.ComponentAccumulator.ComponentAccumulator.getInvertedPerfmonDomains ( self)
 The actual registry keeps "alg":"domain".
This function inverts the registry to get "domain":["algs"].

Definition at line 419 of file ComponentAccumulator.py.

419 def getInvertedPerfmonDomains(self):
420 """ The actual registry keeps "alg":"domain".
421 This function inverts the registry to get "domain":["algs"].
422 """
423 result = {}
424 for i, v in self._domainsRegistry.items():
425 result[v] = [i] if v not in result.keys() else result[v] + [i]
426 return result
427

◆ getIO()

python.ComponentAccumulator.ComponentAccumulator.getIO ( self)
Returns information about inputs needed and outputs produced by this CA

It is a list of dictionaries containing the: type, key, R / W, the component and name of the property via which it is set

Definition at line 280 of file ComponentAccumulator.py.

280 def getIO(self):
281 """
282 Returns information about inputs needed and outputs produced by this CA
283
284 It is a list of dictionaries containing the: type, key, R / W, the component and name of the property via which it is set
285 """
286 def __getHandles(comp):
287 io = []
288 for i in comp.ExtraInputs:
289 io.append({"type": i[0],
290 "key": i[1],
291 "comp": comp.getFullJobOptName(),
292 "mode": "R",
293 "prop": "ExtraInputs"})
294 for i in comp.ExtraOutputs:
295 io.append({"type": i[0],
296 "key": i[1],
297 "comp": comp.getFullJobOptName(),
298 "mode": "W",
299 "prop": "ExtraOutputs"})
300
301 for prop, descr in comp._descriptors.items():
302 if isinstance(descr.default, DataHandle):
303 io.append( {"type": descr.default.type(),
304 "key": comp._properties[prop] if prop in comp._properties else descr.default.path(),
305 "comp": comp.getFullJobOptName(),
306 "mode": descr.default.mode(),
307 "prop": prop })
308 # TODO we should consider instantiating c++ defaults and fetching corresponsing props
309 if "PrivateToolHandle" == descr.cpp_type and prop in comp._properties:
310 io.extend( __getHandles(comp._properties[prop]) )
311 if "PrivateToolHandleArray" == descr.cpp_type and prop in comp._properties:
312 for tool in getattr(comp, prop):
313 io.extend( __getHandles(tool))
314 return io
315
316 ret = []
317 for comp in self._allComponents():
318 ret.extend(__getHandles(comp))
319 return ret
320
321

◆ getPrimary()

python.ComponentAccumulator.ComponentAccumulator.getPrimary ( self)
Get designated primary component

Definition at line 637 of file ComponentAccumulator.py.

637 def getPrimary(self):
638 """Get designated primary component"""
639 if self._privateTools:
640 return self.popPrivateTools()
641 elif self._primaryComp:
642 return self._primaryComp
643 else:
644 raise ConfigurationError("Called getPrimary() but no primary component nor private AlgTool is known.\n{}".format(self._inspect()))
645

◆ getPrimaryAndMerge()

python.ComponentAccumulator.ComponentAccumulator.getPrimaryAndMerge ( self,
other )
Merging in the other accumulator and getting the primary component

Definition at line 646 of file ComponentAccumulator.py.

646 def getPrimaryAndMerge(self, other):
647 """ Merging in the other accumulator and getting the primary component"""
648 if other is None:
649 raise RuntimeError("merge called on object of type None: did you forget to return a CA from a config function?")
650 comp = other.getPrimary()
651 self.merge(other)
652 return comp
653

◆ getPublicTool()

python.ComponentAccumulator.ComponentAccumulator.getPublicTool ( self,
name = None )
Returns single public tool, exception if either not found or to many found

Definition at line 667 of file ComponentAccumulator.py.

667 def getPublicTool(self, name=None):
668 """Returns single public tool, exception if either not found or to many found"""
669 return self.__getOne( self._publicTools, name, "PublicTools")
670

◆ getPublicTools()

python.ComponentAccumulator.ComponentAccumulator.getPublicTools ( self)

Definition at line 664 of file ComponentAccumulator.py.

664 def getPublicTools(self):
665 return self._publicTools
666

◆ getSequence()

python.ComponentAccumulator.ComponentAccumulator.getSequence ( self,
sequenceName = None )

Definition at line 357 of file ComponentAccumulator.py.

357 def getSequence(self,sequenceName=None):
358 if sequenceName is None:
359 return self._sequence
360 else:
361 return findSubSequence(self._sequence,sequenceName)
362

◆ getService()

python.ComponentAccumulator.ComponentAccumulator.getService ( self,
name = None )
Returns single service, exception if either not found or to many found

Definition at line 674 of file ComponentAccumulator.py.

674 def getService(self, name=None):
675 """Returns single service, exception if either not found or to many found"""
676 if name is None:
677 return self._primarySvc
678 else:
679 return self.__getOne( self._services, name, "Services")
680

◆ getServices()

python.ComponentAccumulator.ComponentAccumulator.getServices ( self)

Definition at line 671 of file ComponentAccumulator.py.

671 def getServices(self):
672 return self._services
673

◆ merge()

python.ComponentAccumulator.ComponentAccumulator.merge ( self,
other,
sequenceName = None )
Merging in the other accumulator

Definition at line 778 of file ComponentAccumulator.py.

778 def merge(self,other, sequenceName=None):
779 """Merging in the other accumulator"""
780 if other is None:
781 raise RuntimeError("merge called on object of type None: "
782 "did you forget to return a CA from a config function?")
783
784 if not isinstance(other,ComponentAccumulator):
785 raise TypeError(f"Attempt to merge wrong type {type(other).__name__}. "
786 "Only instances of ComponentAccumulator can be added")
787
788 context = (Context.hint if not ComponentAccumulator.debugMode else # noqa: F841
789 Context("When merging the ComponentAccumulator:\n{} \nto:\n{}".format(other._inspect(), self._inspect())))
790
791 if other._privateTools is not None:
792 if isinstance(other._privateTools, Sequence):
793 raiseWithCurrentContext(RuntimeError(
794 "merge called on ComponentAccumulator with a dangling (array of) private tools\n"))
795 else:
796 raiseWithCurrentContext(RuntimeError(
797 "merge called on ComponentAccumulator with a dangling private tool "
798 f"{other._privateTools.__cpp_type__}/{other._privateTools.name}"))
799
800 if not other._isMergable:
801 raiseWithCurrentContext(ConfigurationError(
802 "Attempted to merge a top level ComponentAccumulator. Revert the order of merging\n"))
803
804 def mergeSequences( dest, src ):
805
806 # Ensure sequences of same name have same properties. This is called many times
807 # and is highly optimized. Make sure you profile before modifying this code.
808 if dest.name == src.name:
809 # Compare all set properties ignoring 'Members'
810 props = (dest._properties.keys() | src._properties.keys()) - {'Members'}
811 for seqProp in props:
812 try:
813 if dest._properties[seqProp] != src._properties[seqProp]:
814 raise RuntimeError(
815 f"Merging two sequences with name '{dest.name}' but property '{seqProp}' "
816 f"has different values: {getattr(dest, seqProp)} vs {getattr(src, seqProp)}")
817 except KeyError as e:
818 raise RuntimeError(
819 f"Merging two sequences with name '{dest.name}' but property '{e}' is not "
820 f"set in one of them")
821
822 for childIdx, c in enumerate(src.Members):
823 if isSequence( c ):
824 sub = findSubSequence( dest, c.name ) #depth=1 ???
825 if sub:
826 mergeSequences(sub, c )
827 else:
828 self._msg.debug(" Merging sequence %s to a destination sequence %s", c.name, dest.name )
829 algorithmsByName = findAllAlgorithmsByName(c) # dictionary: algName (alg, parentSeq, indexInParentSeq)
830 for name, existingAlgs in algorithmsByName.items():
831 # all algorithms from incoming CA are already deduplicated, so we can only handle the fist one
832 algInstance, _, _ = existingAlgs[0]
833 if name not in self._algorithms:
834 self._algorithms[name] = algInstance
835 else:
836 dedupContext1 = createContextForDeduplication("While merging sequences adding incoming algorithm", c.name, other._componentsContext) # noqa : F841
837 dedupContext2 = createContextForDeduplication("While merging sequences adding to existing algorithm", c.name, self._componentsContext) # noqa : F841
838 deduplicateOne(self._algorithms[name], algInstance)
839 deduplicateOne(algInstance, self._algorithms[name])
840 for _, parent, idx in existingAlgs: # put the deduplicated algo back into original sequences
841 parent.Members[idx] = self._algorithms[name]
842 # Add the algorithm to the PerfMon domains
843 self.addAlgToPerfmonDomains(name, other._domainsRegistry[name] if name in other._domainsRegistry else self._currentDomain)
844 dest.Members.append(c)
845
846 else: # an algorithm
847 if c.name in self._algorithms:
848 dedupContext1 = createContextForDeduplication("While merging sequences adding incoming algorithm", c.name, other._componentsContext) # noqa : F841
849 dedupContext2 = createContextForDeduplication("While merging sequences adding to existing algorithm", c.name, self._componentsContext) # noqa : F841
850
851 deduplicateOne(self._algorithms[c.name], c)
852 deduplicateOne(c, self._algorithms[c.name])
853 src.Members[childIdx] = self._algorithms[c.name]
854 else:
855 self._algorithms[c.name] = c
856
857 existingAlgInDest = findAlgorithm( dest, c.name, depth=1 )
858 if not existingAlgInDest:
859 self._msg.debug(" Adding algorithm %s to a sequence %s", c.name, dest.name )
860 dest.Members.append(c)
861
862 # Add the algorithm to the PerfMon domains
863 self.addAlgToPerfmonDomains(c.name, other._domainsRegistry[c.name] if c.name in other._domainsRegistry else self._currentDomain)
864
865 # Merge sequences:
866 # mergeSequences(destSeq, other._sequence)
867 # if sequenceName is provided it means we should be ignoring the actual MAIN seq name there and use the sequenceName
868 # that means the first search in the destination sequence needs to be cheated
869 # the sequenceName argument is only relevant for the MAIN sequence,
870 # secondary top sequences are treated as if the sequenceName argument would not be provided
871
872 for otherSeq in other._allSequences:
873 found=False
874 for ourSeq in self._allSequences:
875 destSeqName = otherSeq.name
876 if sequenceName and otherSeq == other._sequence: # if sequence moving is requested (sequenceName != None) it concerns only the main sequence
877 destSeqName = sequenceName
878 self._msg.verbose(" Will move sequence %s to %s", otherSeq.name, destSeqName )
879
880 ourSeq = findSubSequence(ourSeq, destSeqName) # try to add sequence to the main structure first, to each seq in parent?
881 if ourSeq:
882 mergeSequences(ourSeq, otherSeq)
883 found=True
884 self._msg.verbose(" Succeeded to merge sequence %s to %s", otherSeq.name, ourSeq.name )
885 else:
886 self._msg.verbose(" Failed to merge sequence %s to any existing one, destination CA will have several top/dangling sequences", otherSeq.name )
887 if not found: # just copy the sequence as a dangling one
888 self._allSequences.append( otherSeq )
889 mergeSequences( self._allSequences[-1], otherSeq )
890
891
892
893
894
895 # Additional checking and updating other accumulator's algorithms list
896 for name in other._algorithms:
897 if name not in self._algorithms:
898 raiseWithCurrentContext(ConfigurationError('Error in merging. Algorithm {} missing in destination accumulator\n'.format(name)))
899 other._algorithms[name] = self._algorithms[name]
900
901 #self._conditionsAlgs+=other._conditionsAlgs
902 for condAlg in other._conditionsAlgs:
903 addContext = createContextForDeduplication("Merging incoming Conditions Algorithm", condAlg.name, other._componentsContext) # noqa : F841
904 self.addCondAlgo(condAlg) #Profit from deduplicaton here
905
906 for svc in other._services:
907 addContext = createContextForDeduplication("Merging incoming Service", svc.name, other._componentsContext) # noqa : F841
908 self.addService(svc, create = svc.getFullJobOptName() in other._servicesToCreate) #Profit from deduplicaton here
909
910 for pt in other._publicTools:
911 addContext = createContextForDeduplication("Merging incoming Public Tool", pt.name, other._componentsContext) # noqa : F841
912 self.addPublicTool(pt) #Profit from deduplicaton here
913
914
915 for aud in other._auditors:
916 addContext = createContextForDeduplication("Merging incoming Auditor", aud.name, other._componentsContext) # noqa : F841
917 self.addAuditor(aud) #Profit from deduplicaton here
918
919 #Merge AppMgr properties:
920 for (k,v) in other._theAppProps.items():
921 self.setAppProperty(k,v) #Will warn about overrides
922 pass
923 other._wasMerged=True
924
925 self._lastAddedComponent = other._lastAddedComponent #+ ' (Merged)'
926 self._componentsContext.update(other._componentsContext) # update the context so it contains an information about the new components (and refreshed old components)
927
Definition merge.py:1

◆ popEventAlgo()

python.ComponentAccumulator.ComponentAccumulator.popEventAlgo ( self,
name,
sequence = "AthAlgSeq" )

Definition at line 700 of file ComponentAccumulator.py.

700 def popEventAlgo(self,name,sequence="AthAlgSeq"):
701 s=self.getSequence(sequence)
702 lenBefore=len(s.Members)
703 s.Members = [a for a in s.Members if not a.getName()==name]
704 lenAfter=len(s.Members)
705 if lenAfter == lenBefore:
706 self._msg.warning("Algorithm %s not found in sequence %s",name,sequence)
707 else:
708 self._msg.info("Removed algorithm %s from sequence %s",name,sequence)
709 try:
710 return self._algorithms.pop(name)
711 except KeyError:
712 self._msg.warning("Algorithm %s not found in self._sequence ??? Returning 'None'",name)
713 return None
714

◆ popPrivateTools()

python.ComponentAccumulator.ComponentAccumulator.popPrivateTools ( self,
quiet = False )
Get the (list of) private AlgTools from this ComponentAccumulator.
The CA will not keep any reference to the AlgTool. Throw an exception if
no tools are available unless quiet=True.

Definition at line 388 of file ComponentAccumulator.py.

388 def popPrivateTools(self, quiet=False):
389 """Get the (list of) private AlgTools from this ComponentAccumulator.
390 The CA will not keep any reference to the AlgTool. Throw an exception if
391 no tools are available unless quiet=True.
392 """
393 tool = self._privateTools
394 if not quiet and tool is None:
395 raise ConfigurationError("Private tool(s) requested, but none are present")
396 self._privateTools=None
397 return tool
398

◆ popToolsAndMerge()

python.ComponentAccumulator.ComponentAccumulator.popToolsAndMerge ( self,
other )
 Merging in the other accumulator and getting the (list of) private AlgTools
from this ComponentAccumulator.

Definition at line 399 of file ComponentAccumulator.py.

399 def popToolsAndMerge(self, other):
400 """ Merging in the other accumulator and getting the (list of) private AlgTools
401 from this ComponentAccumulator.
402 """
403 if other is None:
404 raise RuntimeError("popToolsAndMerge called on object of type None: "
405 "did you forget to return a CA from a config function?")
406 tool = other.popPrivateTools()
407 self.merge(other)
408 return tool
409

◆ printCondAlgs()

python.ComponentAccumulator.ComponentAccumulator.printCondAlgs ( self,
summariseProps = False,
onlyComponents = [],
printDefaults = False )

Definition at line 199 of file ComponentAccumulator.py.

199 def printCondAlgs(self, summariseProps=False, onlyComponents=[], printDefaults=False):
200 self._msg.info( "Condition Algorithms" )
201 for (c, flag) in filterComponents (self._conditionsAlgs, onlyComponents):
202 self._msg.info( " \\__ %s (cond alg)%s", c.name, self._componentsContext.get(c.name,""))
203 if summariseProps and flag:
204 printProperties(self._msg, c, 1, printDefaults)
205 return
206
207
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130

◆ printConfig()

python.ComponentAccumulator.ComponentAccumulator.printConfig ( self,
withDetails = False,
summariseProps = False,
onlyComponents = [],
printDefaults = False,
printSequenceTreeOnly = False,
prefix = None )

Definition at line 212 of file ComponentAccumulator.py.

213 onlyComponents = [], printDefaults=False, printSequenceTreeOnly=False, prefix=None):
214 msg = logging.getLogger(prefix) if prefix else self._msg
215
216 msg.info( "Event Algorithm Sequences" )
217
218 def printSeqAndAlgs(seq, nestLevel = 0,
219 onlyComponents = []):
220 def __prop(name):
221 if name in seq._properties:
222 return seq._properties[name]
223 return seq._descriptors[name].default
224 if withDetails:
225 msg.info( "%s\\__ %s (seq: %s %s)", " "*nestLevel, seq.name,
226 "SEQ" if __prop("Sequential") else "PAR",
227 "OR" if __prop("ModeOR") else "AND" + self._componentsContext.get(seq.name, "") )
228 else:
229 msg.info( "%s\\__ %s", " "*nestLevel, seq.name)
230
231 nestLevel += 3
232 for (c, flag) in filterComponents(seq.Members, onlyComponents):
233 if isSequence(c):
234 printSeqAndAlgs(c, nestLevel, onlyComponents = onlyComponents )
235 else:
236 if withDetails:
237 msg.info( "%s\\__ %s (alg) %s", " "*nestLevel, c.getFullJobOptName(), self._componentsContext.get(c.name, ""))
238 else:
239 msg.info( "%s\\__ %s", " "*nestLevel, c.name )
240 if summariseProps and flag:
241 printProperties(msg, c, nestLevel, printDefaults)
242
243
244 for n,s in enumerate(self._allSequences):
245 msg.info( "Top sequence %d", n )
246 printSeqAndAlgs(s, onlyComponents = onlyComponents)
247
248 if printSequenceTreeOnly:
249 return
250
251 self.printCondAlgs (summariseProps = summariseProps,
252 onlyComponents = onlyComponents)
253 msg.info( "Services" )
254 msg.info( [ s[0].name + (" (created) " if s[0].name in self._servicesToCreate else "")
255 for s in filterComponents (self._services, onlyComponents) ] )
256 msg.info( "Public Tools" )
257 msg.info( "[" )
258 for (t, flag) in filterComponents (self._publicTools, onlyComponents):
259 msg.info( " %s,", t.getFullJobOptName() + self._componentsContext.get(t.name,""))
260 # Not nested, for now
261 if summariseProps and flag:
262 printProperties(msg, t, printDefaults)
263 msg.info( "]" )
264 msg.info( "Private Tools")
265 msg.info( "[" )
266 if self._privateTools:
267 for tool in self._privateTools if isinstance(self._privateTools, Sequence) else [self._privateTools]:
268 msg.info( " %s,", tool.getFullJobOptName() + self._componentsContext.get(tool.name,""))
269 if summariseProps:
270 printProperties(msg, tool, printDefaults)
271 msg.info( "]" )
272 if self._auditors:
273 msg.info( "Auditors" )
274 msg.info( [ a[0].name for a in filterComponents(self._auditors, onlyComponents) ] )
275
276 msg.info( "theApp properties" )
277 for k, v in self._theAppProps.items():
278 msg.info(" %s : %s", k, v)
279

◆ printPerfmonDomains()

python.ComponentAccumulator.ComponentAccumulator.printPerfmonDomains ( self)
Print the PerfMon domains. 

Definition at line 452 of file ComponentAccumulator.py.

452 def printPerfmonDomains(self):
453 """ Print the PerfMon domains. """
454 invertedDomains = self.getInvertedPerfmonDomains()
455 self._msg.info(":: This CA contains the following PerfMon domains ::")
456 self._msg.info(f":: There are a total of {len(self._domainsRegistry)} "
457 f"registered algorithms in {len(invertedDomains)} domains ::")
458 for domain, algs in invertedDomains.items():
459 self._msg.info(f"+ Domain : {domain}")
460 for alg in algs:
461 self._msg.info("\\_ %s", alg)
462 self._msg.info(":: End of PerfMon domains ::")
463

◆ run()

python.ComponentAccumulator.ComponentAccumulator.run ( self,
maxEvents = None )

Definition at line 1100 of file ComponentAccumulator.py.

1100 def run(self,maxEvents=None):
1101 from os import environ
1102 outpklfile = environ.get("PICKLECAFILE", None)
1103 if outpklfile is not None:
1104 if outpklfile: # non-empty string
1105 self._msg.info("Storing configuration in pickle file %s",outpklfile)
1106 with open(outpklfile, "wb") as f:
1107 self.store(f)
1108 else: # empty string, just exit
1109 self.wasMerged()
1110 self._msg.info("Exiting after configuration stage")
1111 from Gaudi.Main import BootstrapHelper
1112 return BootstrapHelper.StatusCode(True)
1113
1114 # Make sure python output is flushed before triggering output from Gaudi.
1115 # Otherwise, observed output ordering may differ between py2/py3.
1116 sys.stdout.flush()
1117
1118
1119 #Set TDAQ_ERS_NO_SIGNAL_HANDLERS to avoid interference with
1120 #TDAQ signal handling
1121 environ['TDAQ_ERS_NO_SIGNAL_HANDLERS']='1'
1122 from AthenaCommon.Debugging import allowPtrace, hookDebugger
1123 allowPtrace()
1124
1125 checkSequenceConsistency(self._sequence)
1126
1127 app = self.createApp()
1128 self.__verifyFinalSequencesStructure()
1129
1130 #Determine maxEvents
1131 if maxEvents is None:
1132 if "EvtMax" in self._theAppProps:
1133 maxEvents=self._theAppProps["EvtMax"]
1134 else:
1135 maxEvents=-1
1136
1137 if self.interactive == 'init':
1138 printInteractiveMsg_init()
1139 from sys import exit # noqa: F401
1140 startInteractive(locals())
1141
1142 #At this point, we don't need the internal structures of this CA any more, clean them up
1143 self._cleanup()
1144
1145 self._msg.info(f"Athena job with pid {os.getpid()}")
1146
1147 if (self._debugStage.value == "init"):
1148 hookDebugger()
1149 sc = app.initialize()
1150 if not sc.isSuccess():
1151 self._msg.error("Failed to initialize AppMgr")
1152 return sc
1153
1154 sc = app.start()
1155 if not sc.isSuccess():
1156 self._msg.error("Failed to start AppMgr")
1157 return sc
1158
1159 if (self._debugStage.value=="exec"):
1160 hookDebugger()
1161
1162
1163 if self.interactive == 'run':
1164 printInteractiveMsg_run()
1165 from AthenaPython.PyAthena import py_svc
1166 sg=py_svc("StoreGateSvc/StoreGateSvc")
1167 startInteractive(locals())
1168 else:
1169 sc = app.run(maxEvents)
1170 if not sc.isSuccess():
1171 self._msg.error("Failure running application")
1172 return sc
1173
1174 scStop=app.stop()
1175 if not scStop.isSuccess():
1176 self._msg.error("Failed to stop AppMgr")
1177 return scStop
1178
1179 if (self._debugStage.value == "fini"):
1180 hookDebugger()
1181
1182 scFin=app.finalize()
1183 if not scFin.isSuccess():
1184 self._msg.error("Failed to finalize AppMgr")
1185 return scFin
1186
1187 sc1 = app.terminate()
1188 return sc1
1189
Definition run.py:1

◆ setAppProperty()

python.ComponentAccumulator.ComponentAccumulator.setAppProperty ( self,
key,
value,
overwrite = False )

Definition at line 758 of file ComponentAccumulator.py.

758 def setAppProperty(self,key,value,overwrite=False):
759 if (overwrite or key not in (self._theAppProps)):
760 self._theAppProps[key]=value
761 else:
762 if self._theAppProps[key] == value:
763 self._msg.debug("ApplicationMgr property '%s' already set to '%s'.", key, value)
764 elif isinstance(self._theAppProps[key], Sequence) and not isinstance(self._theAppProps[key],str):
765 value=self._theAppProps[key] + [el for el in value if el not in self._theAppProps[key]]
766 self._msg.info("ApplicationMgr property '%s' already set to '%s'. Overwriting with %s", key, self._theAppProps[key], value)
767 self._theAppProps[key]=value
768 else:
769 raise DeduplicationFailed("AppMgr property {} set twice: {} and {}".format(key, self._theAppProps[key], value))
770
771

◆ setAsTopLevel()

python.ComponentAccumulator.ComponentAccumulator.setAsTopLevel ( self)

Definition at line 128 of file ComponentAccumulator.py.

128 def setAsTopLevel(self):
129 self._isMergable = False
130

◆ setDebugStage()

python.ComponentAccumulator.ComponentAccumulator.setDebugStage ( self,
stage )

Definition at line 772 of file ComponentAccumulator.py.

772 def setDebugStage(self,stage):
773 if stage not in DbgStage.allowed_values:
774 raise RuntimeError("Allowed arguments for setDebugStage are [{}]".format(",".join(DbgStage.allowed_values)))
775 self._debugStage.value = stage
776
777

◆ setPrivateTools()

python.ComponentAccumulator.ComponentAccumulator.setPrivateTools ( self,
privTool )
Use this method to carry private AlgTool(s) to the caller when returning this ComponentAccumulator.
The method accepts either a single private AlgTool or a list of private AlgTools (typically assigned to ToolHandleArray)

Definition at line 363 of file ComponentAccumulator.py.

363 def setPrivateTools(self,privTool):
364 """Use this method to carry private AlgTool(s) to the caller when returning this ComponentAccumulator.
365 The method accepts either a single private AlgTool or a list of private AlgTools (typically assigned to ToolHandleArray)
366 """
367 if self._privateTools is not None:
368 raise ConfigurationError("This ComponentAccumulator holds already a (list of) private tool(s). "
369 "Only one (list of) private tool(s) is allowed")
370
371 if isinstance(privTool, Sequence):
372 for t in privTool:
373 if t.__component_type__ != 'AlgTool':
374 raise ConfigurationError("ComponentAccumulator.setPrivateTools accepts only ConfigurableAlgTools "
375 f"or lists of ConfigurableAlgTools. Encountered {type(t)} in a list")
376 else:
377 if privTool.__component_type__ != "AlgTool":
378 raise ConfigurationError("ComponentAccumulator.setPrivateTools accepts only ConfigurableAlgTools "
379 f"or lists of ConfigurableAlgTools. Encountered {type(privTool)}")
380
381 self._privateTools=privTool
382 if "trackPrivateTool" in ComponentAccumulator.debugMode:
383 for tool in self._privateTools if isinstance(privTool, Sequence) else [self._privateTools]:
384 self._componentsContext[tool.name] = shortCallStack()
385
386 return
387

◆ store()

python.ComponentAccumulator.ComponentAccumulator.store ( self,
outfile,
withDefaultHandles = False )
Saves CA in pickle form

when withDefaultHandles is True, also the handles that are not set are saved

Definition at line 950 of file ComponentAccumulator.py.

950 def store(self,outfile, withDefaultHandles=False):
951 """
952 Saves CA in pickle form
953
954 when withDefaultHandles is True, also the handles that are not set are saved
955 """
956
957 checkSequenceConsistency(self._sequence)
958
959 self.wasMerged()
960 if withDefaultHandles:
961 from AthenaConfiguration.Utils import loadDefaultComps, exposeHandles
962 loadDefaultComps(self._allComponents())
963 exposeHandles(self._allComponents())
964 import pickle
965 pickle.dump(self,outfile)
966 return
967
968

◆ wasMerged()

python.ComponentAccumulator.ComponentAccumulator.wasMerged ( self)
 Declares CA as merged

This is temporarily needed by HLT and should not be used elsewhere

Definition at line 934 of file ComponentAccumulator.py.

934 def wasMerged(self):
935 """ Declares CA as merged
936
937 This is temporarily needed by HLT and should not be used elsewhere
938 """
939 self._wasMerged=True
940

Member Data Documentation

◆ _algorithms

dict python.ComponentAccumulator.ComponentAccumulator._algorithms = {}
protected

Definition at line 104 of file ComponentAccumulator.py.

◆ _allSequences

python.ComponentAccumulator.ComponentAccumulator._allSequences = [self._sequence]
protected

Definition at line 103 of file ComponentAccumulator.py.

◆ _auditors

python.ComponentAccumulator.ComponentAccumulator._auditors = []
protected

Definition at line 108 of file ComponentAccumulator.py.

◆ _checkUnmerged

bool python.ComponentAccumulator.ComponentAccumulator._checkUnmerged = True
staticprotected

Definition at line 78 of file ComponentAccumulator.py.

◆ _componentsContext

python.ComponentAccumulator.ComponentAccumulator._componentsContext = dict()
protected

Definition at line 124 of file ComponentAccumulator.py.

◆ _conditionsAlgs

python.ComponentAccumulator.ComponentAccumulator._conditionsAlgs = []
protected

Definition at line 105 of file ComponentAccumulator.py.

◆ _creationCallStack

str python.ComponentAccumulator.ComponentAccumulator._creationCallStack = Context.hint if "trackCA" not in ComponentAccumulator.debugMode else shortCallStack()
protected

Definition at line 123 of file ComponentAccumulator.py.

◆ _currentDomain

python.ComponentAccumulator.ComponentAccumulator._currentDomain = None
protected

Definition at line 111 of file ComponentAccumulator.py.

◆ _debugStage

python.ComponentAccumulator.ComponentAccumulator._debugStage = DbgStage()
protected

Definition at line 125 of file ComponentAccumulator.py.

◆ _domainsRegistry

dict python.ComponentAccumulator.ComponentAccumulator._domainsRegistry = {}
protected

Definition at line 112 of file ComponentAccumulator.py.

◆ _isMergable

bool python.ComponentAccumulator.ComponentAccumulator._isMergable = True
protected

Definition at line 121 of file ComponentAccumulator.py.

◆ _lastAddedComponent

str python.ComponentAccumulator.ComponentAccumulator._lastAddedComponent = "Unknown"
protected

Definition at line 122 of file ComponentAccumulator.py.

◆ _msg

python.ComponentAccumulator.ComponentAccumulator._msg = logging.getLogger('ComponentAccumulator')
protected

Definition at line 91 of file ComponentAccumulator.py.

◆ _primaryComp

python.ComponentAccumulator.ComponentAccumulator._primaryComp = None
protected

Definition at line 110 of file ComponentAccumulator.py.

◆ _privateTools

python.ComponentAccumulator.ComponentAccumulator._privateTools = None
protected

Definition at line 109 of file ComponentAccumulator.py.

◆ _publicTools

python.ComponentAccumulator.ComponentAccumulator._publicTools = []
protected

Definition at line 117 of file ComponentAccumulator.py.

◆ _sequence

python.ComponentAccumulator.ComponentAccumulator._sequence = sequence
protected

Definition at line 102 of file ComponentAccumulator.py.

◆ _services

python.ComponentAccumulator.ComponentAccumulator._services = []
protected

Definition at line 106 of file ComponentAccumulator.py.

◆ _servicesToCreate

list python.ComponentAccumulator.ComponentAccumulator._servicesToCreate = []
protected

Definition at line 107 of file ComponentAccumulator.py.

◆ _theAppProps

python.ComponentAccumulator.ComponentAccumulator._theAppProps = dict()
protected

Definition at line 114 of file ComponentAccumulator.py.

◆ _wasMerged

bool python.ComponentAccumulator.ComponentAccumulator._wasMerged = False
protected

Definition at line 120 of file ComponentAccumulator.py.

◆ debugMode

str python.ComponentAccumulator.ComponentAccumulator.debugMode = ""
static

Definition at line 77 of file ComponentAccumulator.py.

◆ interactive

str python.ComponentAccumulator.ComponentAccumulator.interactive = ""

Definition at line 126 of file ComponentAccumulator.py.


The documentation for this class was generated from the following file: