ATLAS Offline Software
DualUseConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 useComponentAccumulator = False
4 isAthena = False
5 
6 try:
7  # If we are in an Athena release configuread with ComponentAccumulator
8  # then use the dedicated CA implementation
9  from AthenaConfiguration.ComponentFactory import isComponentAccumulatorCfg
10  useComponentAccumulator = isComponentAccumulatorCfg()
11  isAthena = True
12 except ImportError:
13  pass
14 
15 
16 def createComponent( typeName, instanceName, componentType ):
17  """Create a generic configurable
18 
19  This function is used to create an component "configurable" in a
20  dual-use way, either returning an actual Athena configurable, or
21  an appropriately configured PythonConfig instance.
22 
23  Keyword arguments:
24  typeName -- The C++ type name of the component
25  instanceName -- The instance name of the component to create
26  componentType -- The type of component in AnalysisBase
27 
28  """
29 
30  global isAthena
31  global useComponentAccumulator
32 
33  if isAthena:
34  # Try to get a configurable for this C++ class "from Athena".
35  # If this succeeds, we're obviously in an Athena environment.
36 
37  # Look up the Athena configurable of this component:
38  from AthenaConfiguration.ComponentFactory import CompFactory
39  componentClass = CompFactory.getComp(typeName)
40 
41  # Return the object:
42  return componentClass( instanceName )
43 
44  else:
45  # If that didn't work, then apparently we're in an EventLoop
46  # environment, so we need to use PythonConfig as the base class
47  # for the user's class.
48  from AnaAlgorithm.PythonConfig import PythonConfig
49  component = PythonConfig( '%s/%s' % ( typeName, instanceName ) )
50  component.setComponentType( componentType )
51  return component
52 
53  pass
54 
55 
56 def createAlgorithm( typeName, instanceName ):
57  """Create an algorithm configurable
58 
59  This function is used to create an algorithm "configurable" in a dual-use
60  way, either returning an actual Athena configurable, or an appropriately
61  configured EL::AnaAlgorithmConfig instance.
62 
63  Keyword arguments:
64  typeName -- The C++ type name of the algorithm
65  instanceName -- The instance name of the algorithm to create
66  """
67  return createComponent( typeName, instanceName, 'AnaAlgorithm' )
68 
69 
70 def createReentrantAlgorithm( typeName, instanceName ):
71  """Create a reentrant algorithm configurable
72 
73  This function is used to create an algorithm "configurable" in a dual-use
74  way, either returning an actual Athena configurable, or an appropriately
75  configured EL::AnaAlgorithmConfig instance.
76 
77  Keyword arguments:
78  typeName -- The C++ type name of the algorithm
79  instanceName -- The instance name of the algorithm to create
80  """
81  return createComponent( typeName, instanceName, 'AnaReentrantAlgorithm' )
82 
83 
84 def createPublicTool( typeName, toolName ):
85  """Helper function for setting up a public tool for a dual-use algorithm
86 
87  This function is meant to be used in the analysis algorithm sequence
88  configurations for setting up public tools on the analysis algorithms.
89  Public tools that could then be configured with a syntax shared between
90  Athena and EventLoop.
91 
92  Keyword arguments:
93  typeName -- The C++ type name of the private tool
94  toolName -- The property name with which the tool handle was declared on
95  the algorithm. Also the instance name of the tool.
96  """
97 
98  global isAthena
99  global useComponentAccumulator
100 
101  if isAthena:
102  # Look up the Athena configurable of this tool:
103  from AthenaConfiguration.ComponentFactory import CompFactory
104  toolClass = CompFactory.getComp( typeName )
105 
106  if useComponentAccumulator:
107  # ComponentAccumulator will add the tool to ToolSvc
108  # Avoid importing AthenaCommon.AppMgr in a CA Athena job
109  # as it modifies Gaudi behaviour
110  return toolClass( toolName )
111  else:
112  # Add an instance of the tool to the ToolSvc:
113  from AthenaCommon.AppMgr import ToolSvc
114  if not hasattr( ToolSvc, toolName ):
115  ToolSvc += toolClass( toolName )
116  pass
117 
118  # Return the member on the ToolSvc:
119  return getattr( ToolSvc, toolName )
120 
121  else:
122  # If that didn't work, then apparently we're in an EventLoop
123  # environment, so let's use the EventLoop specific formalism.
124  return createComponent( typeName, toolName, 'AsgTool' )
125 
126 
127 def createService( typeName, serviceName, sequence=None ):
128  """Helper function for setting up a service for a dual-use algorithm
129 
130  This function is meant to be used to set up services in a dual-use
131  manner, particularly for the common CP algorithms. This allows to
132  use the same syntax in EventLoop and Athena, hiding the
133  differences internally. Since in EventLoop the service gets added
134  to a sequence (but in Athena does not), that sequence needs to be
135  passed into this function.
136 
137  Keyword arguments:
138  typeName -- The C++ type name of the service
139  serviceName -- The name with which the service handle was configured on
140  the algorithm. Also the instance name of the service.
141  sequence -- an optional argument of an algorithm sequence to add it to
142  in EventLoop (ignored in Athena)
143 
144  """
145 
146  global isAthena
147  global useComponentAccumulator
148 
149  if isAthena:
150 
151  # Look up the Athena configurable of this tool:
152  from AthenaConfiguration.ComponentFactory import CompFactory
153  serviceClass = CompFactory.getComp( typeName )
154 
155  if useComponentAccumulator:
156  # ComponentAccumulator will add the tool to ToolSvc
157  # Avoid importing AthenaCommon.AppMgr in a CA Athena job
158  # as it modifies Gaudi behaviour
159  return serviceClass( serviceName )
160  else:
161  # Add an instance of the service to the ServiceMgr:
162  from AthenaCommon.AppMgr import ServiceMgr
163  if not hasattr( ServiceMgr, serviceName ):
164  ServiceMgr += serviceClass( serviceName )
165  pass
166 
167  # Return the member on the ServiceMgr:
168  return getattr( ServiceMgr, serviceName )
169 
170  else:
171  # If that didn't work, then apparently we're in an EventLoop
172  # environment, so let's use the EventLoop specific formalism.
173  service = createComponent( typeName, serviceName, 'AsgService' )
174  if sequence is not None :
175  sequence += service
176  pass
177  return service
178 
179 
180 def addPrivateTool( alg, toolName, typeName ):
181  """Helper function for declaring a private tool for a dual-use algorithm
182 
183  This function is meant to be used in the analysis algorithm sequence
184  configurations for setting up private tools on the analysis algorithms.
185  Private tools that could then be configured with a syntax shared between
186  Athena and EventLoop.
187 
188  Keyword arguments:
189  alg -- The algorithm to set up the private tool on
190  toolName -- The property name with which the tool handle was declared on
191  the algorithm. Also the instance name of the tool.
192  typeName -- The C++ type name of the private tool
193  """
194 
195  global isAthena
196 
197  if isAthena:
198 
199  # First try to set up the private tool in an "Athena way".
200 
201  # Tokenize the tool's name. In case it is a subtool of a tool, or
202  # something possibly even deeper.
203  toolNames = toolName.split( '.' )
204 
205  # Look up the component that we need to set up the private tool on:
206  component = alg
207  for tname in toolNames[ 0 : -1 ]:
208  component = getattr( component, tname )
209  pass
210 
211  # Now look up the Athena configurable describing this tool:
212  from AthenaConfiguration.ComponentFactory import CompFactory
213  toolClass = CompFactory.getComp(typeName)
214 
215  # Finally, set up the tool handle property:
216  setattr( component, toolNames[ -1 ], toolClass( toolNames[ -1 ] ) )
217 
218  else:
219 
220  # If that failed, then we should be in an EventLoop environment. So
221  # let's rely on the standalone specific formalism for setting up the
222  # private tool.
223  alg.addPrivateTool( toolName, typeName )
224  pass
225 
226  return
227 
228 
229 def addPrivateToolInArray( alg, toolName, typeName ):
230  """Helper function for declaring a private tool in an array for a
231  dual-use algorithm
232 
233  This function is meant to be used in the analysis algorithm
234  sequence configurations for setting up private tools in arrays on
235  the analysis algorithms. Private tools that could then be
236  configured with a syntax shared between Athena and EventLoop.
237 
238  Keyword arguments:
239  alg -- The algorithm to set up the private tool on
240  toolName -- The property name with which the tool handle was declared on
241  the algorithm. Also the instance name of the tool.
242  typeName -- The C++ type name of the private tool
243 
244  """
245 
246  global isAthena
247 
248  if isAthena:
249 
250  # First try to set up the private tool in an "Athena way".
251 
252  # Tokenize the tool's name. In case it is a subtool of a tool, or
253  # something possibly even deeper.
254  toolNames = toolName.split( '.' )
255 
256  # Look up the component that we need to set up the private tool on:
257  component = alg
258  for tname in toolNames[ 0 : -1 ]:
259  component = getattr( component, tname )
260  pass
261 
262  # Now look up the Athena configurable describing this tool:
263  from AthenaConfiguration.ComponentFactory import CompFactory
264  toolClass = CompFactory.getComp(typeName)
265 
266  # Finally, set up the tool handle property:
267  getattr( component, toolNames[ -1 ] ).append (toolClass( toolNames[ -1 ] ) )
268  return getattr( component, toolNames[ -1 ] )
269 
270  else:
271 
272  # If that failed, then we should be in an EventLoop environment. So
273  # let's rely on the standalone specific formalism for setting up the
274  # private tool.
275  return alg.addPrivateToolInArray( toolName, typeName )
276 
277  return
python.DualUseConfig.createPublicTool
def createPublicTool(typeName, toolName)
Definition: DualUseConfig.py:84
python.DualUseConfig.addPrivateTool
def addPrivateTool(alg, toolName, typeName)
Definition: DualUseConfig.py:180
python.DualUseConfig.createReentrantAlgorithm
def createReentrantAlgorithm(typeName, instanceName)
Definition: DualUseConfig.py:70
python.DualUseConfig.createService
def createService(typeName, serviceName, sequence=None)
Definition: DualUseConfig.py:127
python.DualUseConfig.addPrivateToolInArray
def addPrivateToolInArray(alg, toolName, typeName)
Definition: DualUseConfig.py:229
python.DualUseConfig.createAlgorithm
def createAlgorithm(typeName, instanceName)
Definition: DualUseConfig.py:56
python.JetAnalysisCommon.isComponentAccumulatorCfg
isComponentAccumulatorCfg
Definition: JetAnalysisCommon.py:263
python.DualUseConfig.createComponent
def createComponent(typeName, instanceName, componentType)
Definition: DualUseConfig.py:16