3 from AnaAlgorithm.Logging
import logging
4 logCPAlgCfgSeq = logging.getLogger(
'CPAlgCfgSeq')
6 from functools
import wraps
7 from random
import randrange
10 Decorates a configSequence or function with 'seq' as a
13 Sets groupName to the name of the decorated funtion or
14 calss plus and integer for each ConfigBlock in the configSequence.
16 Blocks with the same groupName can be configured together.
19 def wrapper(**kwargs):
21 groupName = f
"{func.__name__}_{randrange(10**8):08}"
22 for block
in kwargs[
'seq']:
23 block.setOptionValue(
'groupName', groupName)
28 """a sequence of ConfigBlock objects
30 This could in principle just be a simple python list, and maybe we
31 change it to that at some point (10 Mar 22). Having it as its own
32 class allows to implement some helper functions.
34 This implements an interface similar to ConfigBlock, but it
35 doesn't derive from it, as ConfigBlock will likely gain
36 functionality in the future that wouldn't work for a sequence (or
37 wouldn't work in the same way).
46 """append a configuration block to the sequence"""
51 """call makeAlgs() on all blocks
53 This will create the actual algorithm configurables based on
54 how the blocks are configured right now.
57 block.makeAlgs (config)
61 Check for blocks with dependencies.
63 If a block required another block that is not present, will
64 throw an error; Otherwise, will move block immediately after
65 required block. If dependency is not required, will move
66 after other block, if it is present.
68 Note: this implementation can only move blocks forward.
70 def moveBlock(blocks):
71 for i, block
in enumerate(blocks):
73 ignore = block.getOptionValue(
'ignoreDependencies')
74 if block.hasDependencies():
76 for dep
in block.getDependencies():
81 tmpIdx = blocks.index(dep.blockName)
85 raise ValueError(f
"{dep} block is required"
86 f
" for {block} but was not found.")
89 logCPAlgCfgSeq.info(f
"Moving {block} after {blocks[depIdx]}")
91 blocks.insert(depIdx, blocks.pop(i))
96 for _
in range(MAXTRIES):
101 raise Exception(
"Could not order blocks based on dependencies"
102 f
" in {MAXTRIES} moves.")
106 """do the full configuration on this sequence
108 This sequence needs to be the only sequence, i.e. it needs to
109 contain all the blocks that will be configured, as it will
110 perform all configuration steps at once.
119 """set the given option on the sequence
121 The name should generally be of the form
122 "groupName.optionName" to identify what group the option
125 For simplicity I also allow a ".optionName" here, which will
126 then set the property in the last group added. That makes it
127 fairly straightforward to add new blocks, set options on them,
128 and then move on to the next blocks. Please note that this
129 mechanism ought to be viewed as strictly as a temporary
130 convenience, and this short cut may go away once better
131 alternatives are available.
133 WARNING: The backend to option handling is slated to be
134 replaced at some point. This particular function may change
135 behavior, interface or be removed/replaced entirely.
137 names = name.split(
'.')
139 optionName = names.pop(-1)
142 groupName = names.pop(0)
if names
else ''
144 raise ValueError(f
'Option name can be either <groupName>.<optionName>'
145 f
' or <optionName> not {name}')
149 groupName = blocks[-1].getOptionValue(
'groupName')
154 if ( block.getOptionValue(
'groupName') == groupName
155 and block.hasOption(optionName) ):
156 block.setOptionValue (optionName, value, **kwargs)
159 raise ValueError(f
'{optionName} not found in blocks with '
160 f
'group name {groupName}')
163 blocks[-1].setOptionValue (optionName, value, **kwargs)
168 Prints options and their values for each config block in a config sequence
171 logCPAlgCfgSeq.info(config.__class__.__name__)
172 config.printOptions(verbose=verbose)
176 """get information on options for last block in sequence"""
178 groupName = self.
_blocks[-1].getOptionValue(
'groupName')
182 for block
in self.
_blocks[:-1]:
183 if block.getOptionValue(
'groupName') == groupName:
188 for name, o
in block.getOptions().
items():
189 val = getattr(block, name)
190 valDefault = o.default
192 valRequired = o.required
193 noneAction = o.noneAction
194 options.append({
'name': name,
'defaultValue': valDefault,
195 'type': valType,
'required': valRequired,
196 'noneAction': noneAction,
'value': val})
201 """Set options for a ConfigBlock"""
203 for opt
in algOptions:
207 logCPAlgCfgSeq.info(f
" {name}: {options[name]}")
210 raise ValueError(f
'{name} is required but not included in config')
212 defaultVal = opt[
'defaultValue']
214 if name !=
'groupName':
215 options[name] = defaultVal
216 logCPAlgCfgSeq.info(f
" {name}: {defaultVal}")
222 Assigns all blocks in configSequence groupName. If no name is
223 provided, the name is set to group_ plus an integer.
225 Blocks with the same groupName can be configured together.
228 groupName = f
"group_{randrange(10**8):08}"
230 block.setOptionValue(
'groupName', groupName)
234 """Add another sequence to this one
236 This function is used to add another sequence to this sequence
237 using the '+=' operator.
240 if not isinstance( sequence, ConfigSequence ):
241 raise TypeError(
'The received object is not of type ConfigSequence' )
243 for block
in sequence._blocks :
251 """Create an iterator over all the configurations in this sequence
253 This is to allow for a Python-like iteration over all
254 configuration blocks that are part of the sequence.