Commit d6b07dae authored by Nils Krumnack's avatar Nils Krumnack
Browse files

add a addPrivateToolInArray function to DualUseConfig.py

Unfortunately I don't have a really good way to test if it works, but
the underlying C++ is tested, and this is hopefully a close enough
duplication of what's happening for non-array tools that this is good
enough.

Originally I tried to do something more involved, but that became sort
of tedious given the logic of the python class.  Maybe at some point I
will come back and restructure the python class somewhat.  Hopefully
this is still workable as is.
parent 2978514a
......@@ -216,6 +216,47 @@ class AnaAlgorithmConfig( ROOT.EL.AnaAlgorithmConfig ):
pass
def addPrivateToolInArray( self, name, type ):
"""Create a private tool in an array for the algorithm
This function is used in 'standalone' mode to declare a
private tool in a tool array for the algorithm, or a private
tool in a tool array for an already declared private tool.
Can be used like:
tool = config.addPrivateToolInArray( 'tool1', 'ToolType1' )
tool = config.addPrivateToolInArray( 'tool1.tool2', 'ToolType2' )
Keyword arguments:
name -- The full name of the private tool
type -- The C++ type of the private tool
"""
# And now set up the Python object that will take care of setting
# properties on this tool.
# Tokenize the tool's name. In case it is a subtool of a tool, or
# something possibly even deeper.
toolNames = name.split( '.' )
# Look up the component that we need to set up the private tool on.
component = self
for tname in toolNames[ 0 : -1 ]:
component = getattr( component, tname )
pass
# Finally, tell the C++ code what to do.
actualName = self.createPrivateToolInArray( name, type )
# Tokenize the actual tool's name. In case it is a subtool of
# a tool, or something possibly even deeper.
actualToolNames = actualName.split( '.' )
# Now set up a smart object as a property on that component.
config = PrivateToolConfig( self, actualName, type )
component._props[ actualToolNames[ -1 ] ] = config
return config
@staticmethod
def _printHeader( title ):
"""Produce a nice header when printing the configuration
......@@ -442,6 +483,15 @@ class TestAlgPrivateTool( unittest.TestCase ):
self.assertEqual( self.config.Tool1.Prop2, [ 1, 2, 3 ] )
pass
## Test setting up and using one private tool
def test_privatetoolarray( self ):
tool = self.config.addPrivateToolInArray( "Tool1", "ToolType1" )
tool.Prop1 = "Value1"
tool.Prop2 = [ 1, 2, 3 ]
self.assertEqual( tool.Prop1, "Value1" )
self.assertEqual( tool.Prop2, [ 1, 2, 3 ] )
pass
## Test setting up and using a private tool of a private tool
def test_privatetoolofprivatetool( self ):
self.config.addPrivateTool( "Tool1", "ToolType1" )
......
......@@ -130,3 +130,56 @@ def addPrivateTool( alg, toolName, typeName ):
pass
return
def addPrivateToolInArray( alg, toolName, typeName ):
"""Helper function for declaring a private tool in an array for a
dual-use algorithm
This function is meant to be used in the analysis algorithm
sequence configurations for setting up private tools in arrays on
the analysis algorithms. Private tools that could then be
configured with a syntax shared between Athena and EventLoop.
Keyword arguments:
alg -- The algorithm to set up the private tool on
toolName -- The property name with which the tool handle was declared on
the algorithm. Also the instance name of the tool.
typeName -- The C++ type name of the private tool
"""
try:
# First try to set up the private tool in an "Athena way".
# Tokenize the tool's name. In case it is a subtool of a tool, or
# something possibly even deeper.
toolNames = toolName.split( '.' )
# Look up the component that we need to set up the private tool on:
component = alg
for tname in toolNames[ 0 : -1 ]:
component = getattr( component, tname )
pass
# Let's replace all '::' namespace delimeters in the type name
# with '__'. Just because that's how the Athena code behaves...
pythonTypeName = typeName.replace( '::', '__' )
# Now look up the Athena configurable describing this tool:
from AthenaCommon import CfgMgr
toolClass = getattr( CfgMgr, pythonTypeName )
# Finally, set up the tool handle property:
getattr( component, toolNames[ -1 ] ).append (toolClass( toolNames[ -1 ] ) )
return getattr( component, toolNames[ -1 ] )
except ( ImportError, AttributeError ):
# If that failed, then we should be in an EventLoop environment. So
# let's rely on the standalone specific formalism for setting up the
# private tool.
return alg.addPrivateToolInArray( toolName, typeName )
return
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment