Forked from
atlas / athena
109758 commits behind the upstream repository.
-
Tomasz Bold authoredTomasz Bold authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ComponentAccumulator.py 34.44 KiB
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
from AthenaCommon.Logging import logging
from AthenaCommon.Configurable import Configurable,ConfigurableService,ConfigurableAlgorithm,ConfigurableAlgTool
from AthenaCommon.CFElements import isSequence,findSubSequence,findAlgorithm,flatSequencers,findOwningSequence,\
checkSequenceConsistency, findAllAlgorithmsByName
from AthenaCommon.AlgSequence import AthSequencer
import GaudiKernel.GaudiHandles as GaudiHandles
from Deduplication import deduplicate, deduplicateComponent, DeduplicationFailed
import ast
import collections
from UnifyProperties import unifySet
class ConfigurationError(RuntimeError):
pass
_servicesToCreate=frozenset(('GeoModelSvc','TileInfoLoader'))
class ComponentAccumulator(object):
def __init__(self,sequenceName='AthAlgSeq'):
self._msg=logging.getLogger('ComponentAccumulator')
if not Configurable.configurableRun3Behavior:
msg = "discoverd Configurable.configurableRun3Behavior=False while working with ComponentAccumulator"
self._msg.error(msg)
raise ConfigurationError(msg)
self._sequence=AthSequencer(sequenceName,Sequential=True) #(Nested) sequence of event processing algorithms per sequence + their private tools
self._conditionsAlgs=[] #Unordered list of conditions algorithms + their private tools
self._services=[] #List of service, not yet sure if the order matters here in the MT age
self._eventInputs=set() #List of items (as strings) to be read from the input (required at least for BS-reading).
self._outputPerStream={} #Dictionary of {streamName,set(items)}, all as strings
self._privateTools=None #A placeholder to carry a private tool(s) not yet attached to its parent
self._primaryComp=None #A placeholder to designate the primary service
self._theAppProps=dict() #Properties of the ApplicationMgr
#Backward compatiblity hack: Allow also public tools:
self._publicTools=[]
#To check if this accumulator was merged:
self._wasMerged=False
self._isMergable=True
self._algorithms = {}
def empty(self):
return len(self._sequence)+len(self._conditionsAlgs)+len(self._services)+\
len(self._publicTools)+len(self._outputPerStream)+len(self._theAppProps) == 0
def __del__(self):
if not self._wasMerged and not self.empty():
raise RuntimeError("ComponentAccumulator was not merged!")
#log = logging.getLogger("ComponentAccumulator")
#log.error("The ComponentAccumulator listed below was never merged!")
if self._privateTools is not None:
raise RuntimeError("Deleting a ComponentAccumulator with and dangling private tool(s)")
#pass
def printConfig(self, withDetails=False, summariseProps=False):
self._msg.info( "Event Inputs" )
self._msg.info( self._eventInputs )
self._msg.info( "Event Algorithm Sequences" )
def printProperties(c, nestLevel = 0):
for propname, propval in c.getValuedProperties().iteritems():
# Ignore empty lists
if propval==[]:
continue
# Printing EvtStore could be relevant for Views?
if propname in ["DetStore","EvtStore"]:
continue
propstr = str(propval)
if isinstance(propval,GaudiHandles.PublicToolHandleArray):
ths = [th.getFullName() for th in propval]
propstr = "PublicToolHandleArray([ {0} ])".format(', '.join(ths))
elif isinstance(propval,GaudiHandles.PrivateToolHandleArray):
ths = [th.getFullName() for th in propval]
propstr = "PrivateToolHandleArray([ {0} ])".format(', '.join(ths))
elif isinstance(propval,ConfigurableAlgTool):
propstr = propval.getFullName()
self._msg.info( " "*nestLevel +" * {0}: {1}".format(propname,propstr) )
return
if withDetails:
self._msg.info( self._sequence )
else:
def printSeqAndAlgs(seq, nestLevel = 0):
def __prop(name):
if name in seq.getValuedProperties():
return seq.getValuedProperties()[name]
return seq.getDefaultProperties()[name]
self._msg.info( " "*nestLevel +"\\__ "+ seq.name() +" (seq: %s %s)",
"SEQ" if __prop("Sequential") else "PAR", "OR" if __prop("ModeOR") else "AND" )
nestLevel += 3
for c in seq.getChildren():
if isSequence(c):
printSeqAndAlgs(c, nestLevel )
else:
self._msg.info( " "*nestLevel +"\\__ "+ c.name() +" (alg)" )
if summariseProps:
printProperties(c, nestLevel)
printSeqAndAlgs(self._sequence)
self._msg.info( "Condition Algorithms" )
self._msg.info( [ a.getName() for a in self._conditionsAlgs ] )
self._msg.info( "Services" )
self._msg.info( [ s.getName() for s in self._services ] )
self._msg.info( "Outputs" )
self._msg.info( self._outputPerStream )
self._msg.info( "Public Tools" )
self._msg.info( "[" )
for t in self._publicTools:
self._msg.info( " {0},".format(t.getFullName()) )
# Not nested, for now
if summariseProps:
printProperties(t)
self._msg.info( "]" )
def addSequence(self, newseq, parentName = None ):
""" Adds new sequence. If second argument is present then it is added under another sequence """
if not isSequence(newseq):
raise TypeError('{} is not a sequence'.format(newseq.name()))
if parentName is None:
parent=self._sequence
else:
parent = findSubSequence(self._sequence, parentName )
if parent is None:
raise ConfigurationError("Missing sequence %s to add new sequence to" % parentName )
parent += newseq
algsByName = findAllAlgorithmsByName(newseq)
for name, existingAlgs in algsByName.iteritems():
startingIndex = 0
if name not in self._algorithms:
firstAlg, parent, idx = existingAlgs[0]
self._algorithms[name] = firstAlg
startingIndex = 1
for alg, parent, idx in existingAlgs[startingIndex:]:
deduplicateComponent(self._algorithms[name], alg)
parent.overwriteChild(idx, self._algorithms[name])
checkSequenceConsistency(self._sequence)
return newseq
def moveSequence(self, sequence, destination ):
""" moves sequence from one sub-sequence to another, primary use case HLT Control Flow """
seq = findSubSequence(self._sequence, sequence )
if seq is None:
raise ConfigurationError("Can not find sequence to move %s " % sequence )
owner = findOwningSequence(self._sequence, sequence)
if owner is None:
raise ConfigurationError("Can not find the sequence owning the %s " % sequence )
dest = findSubSequence(self._sequence, destination )
if dest is None:
raise ConfigurationError("Can not find destination sequence %s to move to " % destination )
owner.remove( seq )
dest += seq
checkSequenceConsistency(self._sequence)
return seq
def getSequence(self,sequenceName=None):
if sequenceName is None:
return self._sequence
else:
return findSubSequence(self._sequence,sequenceName)
def 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)
"""
if self._privateTools is not None:
raise ConfigurationError("This ComponentAccumulator holds already a (list of) private tool. Only one (list of) private tool(s) is allowed")
if isinstance(privTool,collections.Sequence):
for t in privTool:
if not isinstance(t,ConfigurableAlgTool):
raise ConfigurationError("ComponentAccumulator.setPrivateTools accepts only ConfigurableAlgTools or lists of ConfigurableAlgTools. Encountered %s in a list" % type(t))
else:
if not isinstance(privTool,ConfigurableAlgTool):
raise ConfigurationError("ComponentAccumulator.setPrivateTools accepts only cCnfigurableAlgTools or lists of ConfigurableAlgTools. Encountered %s " % type(privTool))
self._privateTools=privTool
return
def popPrivateTools(self):
"""Get the (list of) private AlgTools from this ComponentAccumulator.
The CA will not keep any reference to the AlgTool.
"""
tool=self._privateTools
self._privateTools=None
return tool
def popToolsAndMerge(self, other):
""" Merging in the other accumulator and getting the (list of) private AlgTools from this CompoentAccumulator.
"""
if other is None:
raise RuntimeError("merge called on object of type None: did you forget to return a CA from a config function?")
tool = other.popPrivateTools()
self.merge(other)
return tool
def addEventAlgo(self, algorithms,sequenceName=None,primary=False):
if not isinstance(algorithms,collections.Sequence):
#Swallow both single algorithms as well as lists or tuples of algorithms
algorithms=[algorithms,]
if sequenceName is None:
seq=self._sequence
else:
seq = findSubSequence(self._sequence, sequenceName )
if seq is None:
self.printConfig()
raise ConfigurationError("Can not find sequence %s" % sequenceName )
for algo in algorithms:
if not isinstance(algo, ConfigurableAlgorithm):
raise TypeError("Attempt to add wrong type: %s as event algorithm" % type( algo ).__name__)
if algo.name() in self._algorithms:
deduplicateComponent(self._algorithms[algo.name()], algo)
else:
self._algorithms[algo.name()] = algo
existingAlgInDest = findAlgorithm(seq, algo.name())
if not existingAlgInDest:
seq += self._algorithms[algo.name()]
if primary:
if len(algorithms)>1:
self._msg.warning("Called addEvenAlgo with a list of algorithms and primary==True. Designating the first algorithm as primary component")
if self._primaryComp:
self._msg.warning("Overwriting primary component of this CA. Was %s/%s, now %s/%s",
self._primaryComp.getType(), self._primaryComp.getName(), algorithms[0].getType(), algorithms[0].getName())
#keep a ref of the algorithm as primary component
self._primaryComp=algorithms[0]
return None
def getEventAlgo(self,name=None):
if name not in self._algorithms:
raise ConfigurationError("Can not find an algorithm of name %s "% name)
return self._algorithms[name]
def getEventAlgos(self,seqName=None):
if seqName is None:
seq=self._sequence
else:
seq = findSubSequence(self._sequence, seqName )
return list( set( sum( flatSequencers( seq, algsCollection=self._algorithms ).values(), []) ) )
def addCondAlgo(self,algo,primary=False):
if not isinstance(algo, ConfigurableAlgorithm):
raise TypeError("Attempt to add wrong type: %s as conditions algorithm" % type( algo ).__name__)
pass
deduplicate(algo,self._conditionsAlgs) #will raise on conflict
if primary:
if self._primaryComp:
self._msg.warning("Overwriting primary component of this CA. Was %s/%s, now %s/%s",
self._primaryComp.getType(),self._primaryComp.getName(),algo.getType(),algo.getName())
#keep a ref of the de-duplicated conditions algorithm as primary component
self._primaryComp=self.__getOne( self._conditionsAlgs, algo.getName(), "ConditionsAlgos")
return algo
def getCondAlgo(self,name):
hits=[a for a in self._conditionsAlgs if a.getName()==name]
if (len(hits)>1):
raise ConfigurationError("More than one conditions algorithm with name %s found" % name)
return hits[0]
def addService(self,newSvc,primary=False):
if not isinstance(newSvc,ConfigurableService):
raise TypeError("Attempt to add wrong type: %s as service" % type( newSvc ).__name__)
pass
deduplicate(newSvc,self._services) #will raise on conflict
if primary:
if self._primaryComp:
self._msg.warning("Overwriting primary component of this CA. Was %s/%s, now %s/%s",
self._primaryComp.getType(),self._primaryComp.getName(),newSvc.getType(),newSvc.getName())
#keep a ref of the de-duplicated public tool as primary component
self._primaryComp=self.__getOne( self._services, newSvc.getName(), "Services")
return
def addPublicTool(self,newTool,primary=False):
if not isinstance(newTool,ConfigurableAlgTool):
raise TypeError("Attempt to add wrong type: %s as AlgTool" % type( newTool ).__name__)
if newTool.getParent() != "ToolSvc":
newTool.setParent("ToolSvc")
deduplicate(newTool,self._publicTools)
if primary:
if self._primaryComp:
self._msg.warning("Overwriting primary component of this CA. Was %s/%s, now %s/%s",
self._primaryComp.getType(),self._primaryComp.getName(),newTool.getType(),newTool.getName())
#keep a ref of the de-duplicated service as primary component
self._primaryComp=self.__getOne( self._publicTools, newTool.getName(), "Public Tool")
return
def getPrimary(self):
if self._primaryComp:
return self._primaryComp
else:
return self.popPrivateTools()
def __call__(self):
return self.getPrimary()
def __getOne(self, allcomps, name=None, typename="???"):
selcomps = allcomps if name is None else [ t for t in allcomps if t.getName() == name ]
if len( selcomps ) == 1:
return selcomps[0]
raise ConfigurationError("Number of %s available %d which is != 1 expected by this API" % (typename, len(selcomps)) )
def getPublicTools(self):
return self._publicTools
def getPublicTool(self, name=None):
"""Returns single public tool, exception if either not found or to many found"""
return self.__getOne( self._publicTools, name, "PublicTools")
def getServices(self):
return self._services
def getService(self, name=None):
"""Returns single service, exception if either not found or to many found"""
if name is None:
return self._primarySvc
else:
return self.__getOne( self._services, name, "Services")
def addEventInput(self,condObj):
#That's a string, should do some sanity checks on formatting
self._eventInput.add(condObj)
pass
def addOutputToStream(self,streamName,outputs):
if streamName in self._outputsPerStream:
self._outputsPerStream[streamName].update(set(outputs))
else:
self._outputsPerStream[streamName]=set(outputs)
pass
def setAppProperty(self,key,value,overwrite=False):
if (overwrite or key not in (self._theAppProps)):
self._theAppProps[key]=value
else:
if isinstance(self._theAppProps[key],collections.Sequence) and not isinstance(self._theAppProps[key],str):
value=unifySet(self._theAppProps[key],value)
self._msg.info("ApplicationMgr property '%s' already set to '%s'. Overwriting with %s", key, self._theAppProps[key], value)
self._theAppProps[key]=value
else:
raise DeduplicationFailed("AppMgr property %s set twice: %s and %s",key,(self._theAppProps[key],value))
pass
def merge(self,other, sequenceName=None):
"""Merging in the other accumulator"""
if other is None:
raise RuntimeError("merge called on object of type None: did you forget to return a CA from a config function?")
if not isinstance(other,ComponentAccumulator):
raise TypeError("Attempt merge wrong type %s. Only instances of ComponentAccumulator can be added" % type(other).__name__)
if (other._privateTools is not None):
if isinstance(other._privateTools,ConfigurableAlgTool):
raise RuntimeError("merge called with a ComponentAccumulator a dangling private tool %s/%s",
other._privateTools.getType(),other._privateTools.getName())
else:
raise RuntimeError("merge called with a ComponentAccumulator a dangling (array of) private tools")
if not other._isMergable:
raise ConfigurationError("Attempted to merge the accumulator that was unsafely manipulated (likely with foreach_component, ...)")
#destSubSeq = findSubSequence(self._sequence, sequence)
#if destSubSeq == None:
# raise ConfigurationError( "Nonexistent sequence %s in %s (or its sub-sequences)" % ( sequence, self._sequence.name() ) ) #
def mergeSequences( dest, src ):
for childIdx, c in enumerate(src.getChildren()):
if isSequence( c ):
sub = findSubSequence( dest, c.name() ) #depth=1 ???
if sub:
mergeSequences(sub, c )
else:
self._msg.debug(" Merging sequence %s to a sequence %s", c.name(), dest.name() )
algorithmsByName = findAllAlgorithmsByName(c)
for name, existingAlgs in algorithmsByName.iteritems():
startingIndex = 0
if name not in self._algorithms:
firstAlg, parent, idx = existingAlgs[0]
self._algorithms[name] = firstAlg
startingIndex = 1
for alg, parent, idx in existingAlgs[startingIndex:]:
deduplicateComponent(self._algorithms[name], alg)
parent.overwriteChild(idx, self._algorithms[name])
dest += c
else: # an algorithm
if c.name() in self._algorithms:
deduplicateComponent(self._algorithms[c.name()], c)
src.overwriteChild(childIdx, self._algorithms[c.name()])
else:
self._algorithms[c.name()] = c
existingAlgInDest = findAlgorithm( dest, c.name(), depth=1 )
if not existingAlgInDest:
self._msg.debug("Adding algorithm %s to a sequence %s", c.name(), dest.name() )
dest += c
checkSequenceConsistency(self._sequence)
#Merge sequences:
#if (self._sequence.getName()==other._sequence.getName()):
if sequenceName:
destSeq = self.getSequence( sequenceName )
else:
destSeq=findSubSequence(self._sequence,other._sequence.name()) or self._sequence
mergeSequences(destSeq,other._sequence)
# Additional checking and updating other accumulator's algorithms list
for name, alg in other._algorithms.iteritems():
if name not in self._algorithms:
raise ConfigurationError('Error in merging. Algorithm {} missing in destination accumulator'.format(name))
other._algorithms[name] = self._algorithms[name]
#self._conditionsAlgs+=other._conditionsAlgs
for condAlg in other._conditionsAlgs:
self.addCondAlgo(condAlg) #Profit from deduplicaton here
for svc in other._services:
self.addService(svc) #Profit from deduplicaton here
for pt in other._publicTools:
self.addPublicTool(pt) #Profit from deduplicaton here
for k in other._outputPerStream.keys():
if k in self._outputPerStream:
self._outputPerStream[k].update(other._outputPerStream[k])
else: #New stream type
self._outputPerStream[k]=other._outputPerStream[k]
#Merge AppMgr properties:
for (k,v) in other._theAppProps.iteritems():
self.setAppProperty(k,v) #Will warn about overrides
pass
other._wasMerged=True
def appendToGlobals(self):
self.wasMerged()
#Cache old configurable behavior
oldstat=Configurable.configurableRun3Behavior
#Turn configurable behavior to old-style (eg return pre-existing instances instead of new'ing them)
Configurable.configurableRun3Behavior=0
from AthenaCommon.AppMgr import ToolSvc, ServiceMgr, theApp
for s in self._services:
deduplicate(s,ServiceMgr)
if s.getJobOptName() in _servicesToCreate \
and s.getJobOptName() not in theApp.CreateSvc:
theApp.CreateSvc.append(s.getJobOptName())
for t in self._publicTools:
deduplicate(t,ToolSvc)
condseq=AthSequencer ("AthCondSeq")
for c in self._conditionsAlgs:
deduplicate(c,condseq)
for seqName, algoList in flatSequencers( self._sequence ).iteritems():
seq=AthSequencer(seqName)
for alg in algoList:
seq+=alg
for (k,v) in self._theAppProps.iteritems():
if k not in [ 'CreateSvc', 'ExtSvc']:
setattr(theApp,k,v)
#Re-instante previous configurable behavior
Configurable.configurableRun3Behavior=oldstat
return
def appendConfigurable(self,confElem):
name=confElem.getJobOptName() # to be FIXED
# if self._jocat.has_key(name):
# self._msg.info("Not adding duplicate configurable: %s" % name )
# return
#Hack for public Alg tools, drop multiple mentions of ToolSvc
nTS=0
for n in name.split("."):
if n=="ToolSvc":
nTS+=1
else:
break
if nTS>2:
name=".".join(name.split(".")[nTS-1:])
for k, v in confElem.getValuedProperties().items():
if isinstance(v,Configurable):
self._jocat[name][k]=v.getFullName()
elif isinstance(v,GaudiHandles.GaudiHandleArray):
self._jocat[name][k]=str([ v1.getFullName() for v1 in v ])
else:
if name not in self._jocat:
self._jocat[name] = {}
self._jocat[name][k]=str(v)
#print "All Children:",confElem.getAllChildren()
for ch in confElem.getAllChildren():
self.appendConfigurable(ch)
return
def store(self,outfile,nEvents=10,useBootStrapFile=True,threaded=False):
from AthenaCommon.Utils.unixtools import find_datafile
import pickle
self._isMergable = True # this is CA we store, it is ok it is not mergable
if useBootStrapFile:
import glob
# first load basics from the bootstrap-pickle
# a better solution to be discussed
# prefer local file
localbs = glob.glob("bootstrap.pkl")
if len( localbs ) == 0:
# if local bootstrap is missing, use one from the release
bsfilename=find_datafile("bootstrap.pkl")
else:
bsfilename = "./"+localbs[0]
bsfile=open(bsfilename)
self._jocat=pickle.load(bsfile)
self._jocfg=pickle.load(bsfile)
self._pycomps=pickle.load(bsfile)
bsfile.close()
else:
from AthenaConfiguration.MainServicesConfig import MainServicesThreadedCfg, MainServicesSerialCfg
if threaded:
from AthenaConfiguration.AllConfigFlags import ConfigFlags
flags = ConfigFlags.clone()
flags.Concurrency.NumThreads = 1
flags.Concurrency.NumConcurrentEvents = 1
basecfg = MainServicesThreadedCfg(flags)
basecfg.printConfig()
basecfg.merge(self)
self = basecfg
self.printConfig()
else: #Serial
basecfg = MainServicesSerialCfg()
basecfg.merge(self)
self = basecfg
self._jocat={}
self._jocfg={}
self._pycomps={}
self._jocfg["ApplicationMgr"]={}
self._jocfg["ApplicationMgr"]["ExtSvc"] = "['ToolSvc/ToolSvc', \
'AuditorSvc/AuditorSvc', \
'MessageSvc/MessageSvc', \
'IncidentSvc/IncidentSvc',\
'EvtPersistencySvc/EventPersistencySvc',\
'HistogramSvc/HistogramDataSvc',\
'NTupleSvc/NTupleSvc',\
'RndmGenSvc/RndmGenSvc',\
'ChronoStatSvc/ChronoStatSvc',\
'StatusCodeSvc/StatusCodeSvc',\
'StoreGateSvc/StoreGateSvc',\
'StoreGateSvc/DetectorStore',\
'StoreGateSvc/HistoryStore',\
'ClassIDSvc/ClassIDSvc',\
'AthDictLoaderSvc/AthDictLoaderSvc',\
'AthenaSealSvc/AthenaSealSvc',\
'CoreDumpSvc/CoreDumpSvc',\
'JobOptionsSvc/JobOptionsSvc']"
#Code seems to be wrong here
for seqName, algoList in flatSequencers( self._sequence, algsCollection=self._algorithms ).iteritems():
self._jocat[seqName] = {}
for alg in algoList:
self._jocat[alg.name()] = {}
for k, v in self._sequence.getValuedProperties().items():
self._jocat[self._sequence.getName()][k]=str(v)
#EventAlgorithms
for seqName, algoList in flatSequencers( self._sequence, algsCollection=self._algorithms ).iteritems():
evtalgseq=[]
for alg in algoList:
self.appendConfigurable( alg )
evtalgseq.append( alg.getFullName() )
for seqName, algoList in flatSequencers( self._sequence, algsCollection=self._algorithms ).iteritems():
# part of the sequence may come from the bootstrap, we need to retain the content, that is done here
for prop in self._jocat[seqName]:
if prop == "Members":
mergedSequence = ast.literal_eval(self._jocat[seqName]["Members"]) + [alg.getFullName() for alg in algoList]
self._jocat[seqName]["Members"] = str( mergedSequence )
#Conditions Algorithms:
condalgseq=[]
for alg in self._conditionsAlgs:
self.appendConfigurable(alg)
condalgseq.append(alg.getFullName())
self._jocat["AthCondSeq"]["Members"]=str(condalgseq)
#Public Tools:
for pt in self._publicTools:
#print "Appending public Tool",pt.getFullName(),pt.getJobOptName()
self.appendConfigurable(pt)
#Hack for now:
self._jocfg["ApplicationMgr"]["CreateSvc"]=['ToolSvc/ToolSvc', 'AthDictLoaderSvc/AthDictLoaderSvc', 'AthenaSealSvc/AthenaSealSvc', 'CoreDumpSvc/CoreDumpSvc']
svcList=ast.literal_eval(self._jocfg["ApplicationMgr"]["ExtSvc"])
for svc in self._services:
if svc.getJobOptName() in _servicesToCreate:
self._jocfg["ApplicationMgr"]["CreateSvc"].append( svc.getFullName() )
svcList.append(svc.getFullName())
#for k, v in svc.getValuedProperties().items():
# self._jocat[svcname][k]=str(v)
self.appendConfigurable(svc)
self._jocfg["ApplicationMgr"]["ExtSvc"]=str(svcList)
self._jocfg["ApplicationMgr"]["EvtMax"]=nEvents
for (k,v) in self._theAppProps.iteritems():
if k not in [ 'CreateSvc', 'ExtSvc']:
self._jocfg["ApplicationMgr"][k]=v
#from pprint import pprint
#pprint (self._jocat)
pickle.dump( self._jocat, outfile )
pickle.dump( self._jocfg, outfile )
pickle.dump( self._pycomps, outfile )
self._wasMerged=True
def wasMerged(self):
""" Declares CA as merged
This is temporarily needed by HLT and should not be used elsewhere
"""
self._wasMerged=True
def createApp(self,OutputLevel=3):
self._wasMerged=True
from Gaudi.Main import BootstrapHelper
bsh=BootstrapHelper()
app=bsh.createApplicationMgr()
for (k,v) in self._theAppProps.iteritems():
app.setProperty(k,str(v))
#Assemble createSvc property:
svcToCreate=[]
extSvc=[]
for svc in self._services:
extSvc+=[svc.getFullName(),]
if svc.getJobOptName() in _servicesToCreate:
svcToCreate+=[svc.getFullName(),]
#print self._services
#print extSvc
#print svcToCreate
app.setProperty("ExtSvc",str(extSvc))
app.setProperty("CreateSvc",str(svcToCreate))
app.configure()
msp=app.getService("MessageSvc")
bsh.setProperty(msp,"OutputLevel",str(OutputLevel))
#Feed the jobO service with the remaining options
jos=app.getService("JobOptionsSvc")
def addCompToJos(comp):
name=comp.getJobOptName()
for k, v in comp.getValuedProperties().items():
if isinstance(v,Configurable):
self._msg.debug("Adding "+name+"."+k+" = "+v.getFullName())
bsh.addPropertyToCatalogue(jos,name,k,v.getFullName())
addCompToJos(v)
elif isinstance(v,GaudiHandles.GaudiHandleArray):
bsh.addPropertyToCatalogue(jos,name,k,str([ v1.getFullName() for v1 in v ]))
else:
if not isSequence(comp) and k!="Members": #This property his handled separatly
self._msg.debug("Adding "+name+"."+k+" = "+str(v))
bsh.addPropertyToCatalogue(jos,name,k,str(v))
pass
pass
for ch in comp.getAllChildren():
addCompToJos(ch)
return
#Add services
for svc in self._services:
addCompToJos(svc)
pass
#Add tree of algorithm sequences:
for seqName, algoList in flatSequencers( self._sequence, algsCollection=self._algorithms ).iteritems():
self._msg.debug("Members of %s : %s" % (seqName,str([alg.getFullName() for alg in algoList])))
bsh.addPropertyToCatalogue(jos,seqName,"Members",str( [alg.getFullName() for alg in algoList]))
for alg in algoList:
addCompToJos(alg)
pass
pass
condalgseq=[]
for alg in self._conditionsAlgs:
addCompToJos(alg)
condalgseq.append(alg.getFullName())
bsh.addPropertyToCatalogue(jos,"AthCondSeq","Members",str(condalgseq))
pass
#Public Tools:
for pt in self._publicTools:
addCompToJos(pt)
pass
return app
def run(self,maxEvents=None,OutputLevel=3):
app = self.createApp (OutputLevel)
#Determine maxEvents
if maxEvents is None:
if "EvtMax" in self._theAppProps:
maxEvents=self._theAppProps["EvtMax"]
else:
maxEvents=-1
self._msg.info("INITIALIZE STEP")
sc = app.initialize()
if not sc.isSuccess():
self._msg.error("Failed to initialize AppMgr")
return sc
app.printAlgsSequences() #could be removed later ....
sc = app.start()
if not sc.isSuccess():
self._msg.error("Failed to start AppMgr")
return sc
sc = app.run(maxEvents)
if not sc.isSuccess():
self._msg.error("Failure running application")
return sc
app.stop().ignore()
app.finalize().ignore()
sc1 = app.terminate()
return sc1
def foreach_component(self, path):
""" Utility to set properties of components using wildcards
Example:
forcomps(ca, "*/HLTTop/*/*Hypo*").OutputLevel=VERBOSE
The compoments name & locations in the CF tree are translated into the unix like path.
Components of matching path are taken under consideration in setting the property.
If the property is set succesfully an INFO message is printed. Else, a warning is printed.
The convention for path of nested components is as follows:
Sequencer - only the name is used in the path
Algorithm - full name - type/instance_name (aka full name) is used
PrivateTools - the name of the property + the type/instance_name are added
PublicTools - are located under ToolSvc/ and type/instance_name is used
Services - located under SvcMgr/ and type/instance_name is used
"""
from AthenaConfiguration.PropSetterProxy import PropSetterProxy
self._isMergable=False
return PropSetterProxy(self, path)
def CAtoGlobalWrapper(cfgmethod,flags):
Configurable.configurableRun3Behavior+=1
result=cfgmethod(flags)
Configurable.configurableRun3Behavior-=1
result.appendToGlobals()
return