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, index=None)
 __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 29 of file ConfigSequence.py.

Constructor & Destructor Documentation

◆ __init__()

python.ConfigSequence.ConfigSequence.__init__ ( self)

Definition at line 43 of file ConfigSequence.py.

43 def __init__ (self) :
44 self._blocks = []
45
46

Member Function Documentation

◆ __iadd__()

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

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

Definition at line 274 of file ConfigSequence.py.

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

◆ __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 291 of file ConfigSequence.py.

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

◆ append()

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

Definition at line 47 of file ConfigSequence.py.

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

◆ applyConfigOverrides()

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

Definition at line 68 of file ConfigSequence.py.

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

◆ 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 126 of file ConfigSequence.py.

126 def fullConfigure (self, config) :
127 """do the full configuration on this sequence
128
129 This sequence needs to be the only sequence, i.e. it needs to
130 contain all the blocks that will be configured, as it will
131 perform all configuration steps at once.
132 """
133 for block in self._blocks:
134 if re.compile ('^[_a-zA-Z0-9]*$').match (block.instanceName()) is None :
135 raise ValueError (f'invalid block instance name: {block.instanceName()} for {block.factoryName()}')
136
137 self.reorderAlgs()
138 self.makeAlgs (config)
139 config.nextPass ()
140 self.makeAlgs (config)
141 self.applyConfigOverrides(config)
142
143

◆ getOptions()

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

Definition at line 201 of file ConfigSequence.py.

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

◆ 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 247 of file ConfigSequence.py.

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

◆ 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 52 of file ConfigSequence.py.

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

◆ printOptions()

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

Definition at line 192 of file ConfigSequence.py.

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

◆ 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 80 of file ConfigSequence.py.

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

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

◆ setOptions()

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

Definition at line 226 of file ConfigSequence.py.

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

◆ 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 144 of file ConfigSequence.py.

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

Member Data Documentation

◆ _blocks

python.ConfigSequence.ConfigSequence._blocks = []
protected

Definition at line 44 of file ConfigSequence.py.


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