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

Public Member Functions

 __init__ (self)
 append (self, block)
 makeAlgs (self, config)
 applyConfigOverrides (self, config)
 reorderAlgs (self)
 fullConfigure (self, config)
 setOptionValue (self, name, value, **kwargs)
 printOptions (self, verbose=False)
 getOptions (self)
 setOptions (self, options)
 groupBlocks (self, groupName='')
 setFactoryName (self, factoryName)
 __iadd__ (self, sequence)
 __iter__ (self)

Protected Attributes

list _blocks = []

Detailed Description

a sequence of ConfigBlock objects

This could in principle just be a simple python list, and maybe we
change it to that at some point (10 Mar 22).  Having it as its own
class allows to implement some helper functions.

This implements an interface similar to ConfigBlock, but it
doesn't derive from it, as ConfigBlock will likely gain
functionality in the future that wouldn't work for a sequence (or
wouldn't work in the same way).

Definition at line 31 of file ConfigSequence.py.

Constructor & Destructor Documentation

◆ __init__()

python.ConfigSequence.ConfigSequence.__init__ ( self)

Definition at line 45 of file ConfigSequence.py.

45 def __init__ (self) :
46 self._blocks = []
47
48

Member Function Documentation

◆ __iadd__()

python.ConfigSequence.ConfigSequence.__iadd__ ( self,
sequence )
Add another sequence to this one

This function is used to add another sequence to this sequence
using the '+=' operator.

Definition at line 278 of file ConfigSequence.py.

278 def __iadd__( self, sequence ):
279 """Add another sequence to this one
280
281 This function is used to add another sequence to this sequence
282 using the '+=' operator.
283 """
284 # Check that the received object is of the right type:
285 if not isinstance( sequence, ConfigSequence ):
286 raise TypeError( 'The received object is not of type ConfigSequence' )
287
288 for block in sequence._blocks :
289 self._blocks.append (block)
290
291 # Return the modified object:
292 return self
293
294

◆ __iter__()

python.ConfigSequence.ConfigSequence.__iter__ ( self)
Create an iterator over all the configurations in this sequence

This is to allow for a Python-like iteration over all
configuration blocks that are part of the sequence.

Definition at line 295 of file ConfigSequence.py.

295 def __iter__( self ):
296 """Create an iterator over all the configurations in this sequence
297
298 This is to allow for a Python-like iteration over all
299 configuration blocks that are part of the sequence.
300 """
301 # Create the iterator to process the internal list of algorithms:
302 return self._blocks.__iter__()

◆ append()

python.ConfigSequence.ConfigSequence.append ( self,
block )
append a configuration block to the sequence

Definition at line 49 of file ConfigSequence.py.

49 def append (self, block) :
50 """append a configuration block to the sequence"""
51 self._blocks.append (block)
52
53

◆ applyConfigOverrides()

python.ConfigSequence.ConfigSequence.applyConfigOverrides ( self,
config )
Apply any properties that were set in the block's
'propertyOverrides' option.

Definition at line 70 of file ConfigSequence.py.

70 def applyConfigOverrides(self, config):
71 """
72 Apply any properties that were set in the block's
73 'propertyOverrides' option.
74 """
75 for block in self._blocks:
76 if not block.isUsedForConfig(config):
77 continue
78 config.setAlgPostfix(block.instanceName())
79 block.applyConfigOverrides(config)
80 config.setAlgPostfix('') # reset algPostfix after all blocks are configured
81

◆ fullConfigure()

python.ConfigSequence.ConfigSequence.fullConfigure ( self,
config )
do the full configuration on this sequence

This sequence needs to be the only sequence, i.e. it needs to
contain all the blocks that will be configured, as it will
perform all configuration steps at once.

Definition at line 130 of file ConfigSequence.py.

130 def fullConfigure (self, config) :
131 """do the full configuration on this sequence
132
133 This sequence needs to be the only sequence, i.e. it needs to
134 contain all the blocks that will be configured, as it will
135 perform all configuration steps at once.
136 """
137 for block in self._blocks:
138 instanceName = block.instanceName()
139 if _instanceNameExpr.match (instanceName) is None :
140 raise ValueError (f'invalid block instance name: {instanceName} for {block.factoryName()}')
141
142 self.reorderAlgs()
143 self.makeAlgs (config)
144 self.applyConfigOverrides(config)
145 config.renameFinalContainers()
146
147

◆ getOptions()

python.ConfigSequence.ConfigSequence.getOptions ( self)
get information on options for last block in sequence

Definition at line 205 of file ConfigSequence.py.

205 def getOptions(self):
206 """get information on options for last block in sequence"""
207 # get groupName for last added block
208 groupName = self._blocks[-1].getOptionValue('groupName')
209 blocks = [self._blocks[-1]]
210 # get all blocks with the same groupName
211 if groupName:
212 for block in self._blocks[:-1]:
213 if block.getOptionValue('groupName') == groupName:
214 blocks.append(block)
215 options = []
216 # get options for all blocks with same groupName
217 for block in blocks:
218 for name, o in block.getOptions().items():
219 val = getattr(block, name)
220 valDefault = o.default
221 valType = o.type
222 valRequired = o.required
223 noneAction = o.noneAction
224 options.append({'name': name, 'defaultValue': valDefault,
225 'type': valType, 'required': valRequired,
226 'noneAction': noneAction, 'value': val})
227 return options
228
229

◆ groupBlocks()

python.ConfigSequence.ConfigSequence.groupBlocks ( self,
groupName = '' )
Assigns all blocks in configSequence groupName. If no name is
provided, the name is set to group_ plus an integer.

Blocks with the same groupName can be configured together.

Definition at line 251 of file ConfigSequence.py.

251 def groupBlocks(self, groupName=''):
252 """
253 Assigns all blocks in configSequence groupName. If no name is
254 provided, the name is set to group_ plus an integer.
255
256 Blocks with the same groupName can be configured together.
257 """
258 if not groupName:
259 groupName = f"group_{randrange(10**8):08}"
260 for block in self._blocks:
261 block.setOptionValue('groupName', groupName)
262
263

◆ makeAlgs()

python.ConfigSequence.ConfigSequence.makeAlgs ( self,
config )
call makeAlgs() on all blocks

This will create the actual algorithm configurables based on
how the blocks are configured right now.

Definition at line 54 of file ConfigSequence.py.

54 def makeAlgs (self, config) :
55 """call makeAlgs() on all blocks
56
57 This will create the actual algorithm configurables based on
58 how the blocks are configured right now.
59 """
60 for block in self._blocks:
61 if not block.isUsedForConfig(config):
62 continue
63 config.setAlgPostfix(block.instanceName())
64 block.checkExpertSettings (config)
65 block.makeAlgs (config)
66 config.setAlgPostfix('') # reset algPostfix after all blocks are configured
67 ConfigBlock.instance_counts.clear() # reset for a possible next config run
68
69

◆ printOptions()

python.ConfigSequence.ConfigSequence.printOptions ( self,
verbose = False )
Prints options and their values for each config block in a config sequence

Definition at line 196 of file ConfigSequence.py.

196 def printOptions(self, verbose=False):
197 """
198 Prints options and their values for each config block in a config sequence
199 """
200 for config in self:
201 logCPAlgCfgSeq.info(config.__class__.__name__)
202 config.printOptions(verbose=verbose)
203
204

◆ reorderAlgs()

python.ConfigSequence.ConfigSequence.reorderAlgs ( self)
Check for blocks with dependencies.

If a block required another block that is not present, will
throw an error; Otherwise, will move block immediately after
required block. If dependency is not required, will move
after other block, if it is present.

Note: this implementation can only move blocks forward.

Definition at line 82 of file ConfigSequence.py.

82 def reorderAlgs(self):
83 """
84 Check for blocks with dependencies.
85
86 If a block required another block that is not present, will
87 throw an error; Otherwise, will move block immediately after
88 required block. If dependency is not required, will move
89 after other block, if it is present.
90
91 Note: this implementation can only move blocks forward.
92 """
93 def moveBlock(blocks):
94 for i, block in enumerate(blocks):
95 # the 'ignoreDependencies' option is added with a dep.
96 ignore = block.getOptionValue('ignoreDependencies')
97 if block.hasDependencies():
98 depIdx = i
99 for dep in block.getDependencies():
100 if dep.blockName in ignore:
101 continue
102 # find dep with largest idx
103 depIndices = [index for index, value in enumerate(blocks)
104 if value.getBlockName() == dep.blockName]
105 if depIndices:
106 lastIdx = max(depIndices)
107 if lastIdx > depIdx:
108 depIdx = lastIdx
109 elif dep.required:
110 raise ValueError(f"{dep} block is required"
111 f" for {block} but was not found.")
112 # check to see if block is already in front of deps
113 if depIdx > i:
114 logCPAlgCfgSeq.info(f"Moving {block} after {blocks[depIdx]}")
115 # depIdx > i so after pop, depIdx -= 1 -> depIdx is after dep
116 blocks.insert(depIdx, blocks.pop(i))
117 return False
118 # nothing to move
119 return True
120 MAXTRIES = 1000
121 for _ in range(MAXTRIES):
122 if moveBlock(self._blocks):
123 # sorted
124 break
125 else:
126 raise Exception("Could not order blocks based on dependencies"
127 f" in {MAXTRIES} moves.")
128
129
#define max(a, b)
Definition cfImp.cxx:41

◆ setFactoryName()

python.ConfigSequence.ConfigSequence.setFactoryName ( self,
factoryName )
Set the factory name for all blocks in the sequence.

This is used to set a common factory name for all blocks, which
can be useful for debugging or logging purposes.

Definition at line 264 of file ConfigSequence.py.

264 def setFactoryName(self, factoryName):
265 """
266 Set the factory name for all blocks in the sequence.
267
268 This is used to set a common factory name for all blocks, which
269 can be useful for debugging or logging purposes.
270 """
271 if len(self._blocks) == 1:
272 self._blocks[0].setFactoryName(factoryName)
273 else:
274 # append [index] to factoryName for each block
275 for index, block in enumerate(self._blocks):
276 block.setFactoryName(f"{factoryName}[{index}:{block.__class__.__name__}]")
277

◆ setOptions()

python.ConfigSequence.ConfigSequence.setOptions ( self,
options )
Set options for a ConfigBlock

Definition at line 230 of file ConfigSequence.py.

230 def setOptions(self, options):
231 """Set options for a ConfigBlock"""
232 algOptions = self.getOptions()
233 for opt in algOptions:
234 name = opt['name']
235 if name in options:
236 self.setOptionValue (f'.{name}', options[name])
237 logCPAlgCfgSeq.debug(f" {name}: {options[name]}")
238 else:
239 if opt['required']:
240 raise ValueError(f'{name} is required but not included in config')
241 # add default used to config
242 defaultVal = opt['value'] if opt['value'] is not None else opt['defaultValue']
243 # do not overwrite groupName unless set by user
244 if name != 'groupName':
245 options[name] = defaultVal
246 logCPAlgCfgSeq.debug(f" {name}: {defaultVal}")
247 # refresh and return options
248 return self.getOptions()
249
250

◆ setOptionValue()

python.ConfigSequence.ConfigSequence.setOptionValue ( self,
name,
value,
** kwargs )
set the given option on the sequence

The name should generally be of the form
"groupName.optionName" to identify what group the option
belongs to.

For simplicity I also allow a ".optionName" here, which will
then set the property in the last group added.  That makes it
fairly straightforward to add new blocks, set options on them,
and then move on to the next blocks.  Please note that this
mechanism ought to be viewed as strictly as a temporary
convenience, and this short cut may go away once better
alternatives are available.

WARNING: The backend to option handling is slated to be
replaced at some point.  This particular function may change
behavior, interface or be removed/replaced entirely.

Definition at line 148 of file ConfigSequence.py.

148 def setOptionValue (self, name, value, **kwargs) :
149 """set the given option on the sequence
150
151 The name should generally be of the form
152 "groupName.optionName" to identify what group the option
153 belongs to.
154
155 For simplicity I also allow a ".optionName" here, which will
156 then set the property in the last group added. That makes it
157 fairly straightforward to add new blocks, set options on them,
158 and then move on to the next blocks. Please note that this
159 mechanism ought to be viewed as strictly as a temporary
160 convenience, and this short cut may go away once better
161 alternatives are available.
162
163 WARNING: The backend to option handling is slated to be
164 replaced at some point. This particular function may change
165 behavior, interface or be removed/replaced entirely.
166 """
167 names = name.split('.')
168 # <optionName>
169 optionName = names.pop(-1)
170 # <groupName>.<optionName>, or
171 # .<optionName> (backwards compatibility)
172 groupName = names.pop(0) if names else ''
173 if names:
174 raise ValueError(f'Option name can be either <groupName>.<optionName>'
175 f' or <optionName> not {name}')
176 blocks = self._blocks
177 # check if last block added has an instance name
178 if not groupName:
179 groupName = blocks[-1].getOptionValue('groupName')
180 if groupName:
181 used = False
182 # set optionName for all blocks with groupName
183 for block in blocks:
184 if ( block.getOptionValue('groupName') == groupName
185 and block.hasOption(optionName) ):
186 block.setOptionValue (optionName, value, **kwargs)
187 used = True
188 if not used:
189 raise ValueError(f'{optionName} not found in blocks with '
190 f'group name {groupName}')
191 else:
192 # set option for last added block
193 blocks[-1].setOptionValue (optionName, value, **kwargs)
194
195

Member Data Documentation

◆ _blocks

python.ConfigSequence.ConfigSequence._blocks = []
protected

Definition at line 46 of file ConfigSequence.py.


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