5 from AnaAlgorithm.Logging
import logging
6 logCPAlgCfgBlock = logging.getLogger(
'CPAlgCfgBlock')
10 """the information for a single option on a configuration block"""
12 def __init__ (self, type=None, info='', noneAction='ignore', required=False,
23 """Class encoding a blocks dependence on other blocks."""
39 return f
'ConfigBlockDependency(blockName="{self.blockName}", required={self.required})'
43 """the base class for classes implementing individual blocks of
46 A configuration block is a sequence of one or more algorithms that
47 should always be scheduled together, e.g. the muon four momentum
48 corrections could be a single block, muon selection could then be
49 another block. The blocks themselves generally have their own
50 configuration options/properties specific to the block, and will
51 perform a dynamic configuration based on those options as well as
54 The actual configuration of the algorithms in the block will
55 depend on what other blocks are scheduled before and afterwards,
56 most importantly some algorithms will introduce shallow copies
57 that subsequent algorithms will need to run on, and some
58 algorithms will add selection decorations that subquent algorithms
59 should use as preselections.
61 The algorithms get created in a multi-step process (that may be
62 extended in the future): As a first step each block retrieves
63 references to the containers it uses (essentially marking its spot
64 in the processing chain) and also registering any shallow copies
65 that will be made. In the second/last step each block then
66 creates the fully configured algorithms.
68 One goal is that when the algorithms get created they will have
69 their final configuration and there needs to be no
70 meta-configuration data attached to the algorithms, essentially an
71 inversion of the approach in AnaAlgSequence in which the
72 algorithms got created first with associated meta-configuration
73 and then get modified in susequent configuration steps.
75 For now this is mostly an empty base class, but another goal of
76 this approach is to make it easier to build another configuration
77 layer on top of this one, and this class will likely be extended
78 and get data members at that point.
80 The child class needs to implement two methods,
81 `collectReferences` and `makeAlgs` which are each given a single
82 `ConfigAccumulator` type argument. The first is for the first
83 configuration step, and should only collect references to the
84 containers to be used. The second is for the second configuration
85 step, and should create the actual algorithms.
95 info=(
'Used to specify this block when setting an'
96 ' option at an arbitrary location.'))
109 Add a dependency for the block. Dependency is corresponds to the
110 blockName of another block. If required is True, will throw an
111 error if dependency is not present; otherwise will move this
112 block after the required block. If required is False, will do
113 nothing if required block is not present; otherwise, it will
114 move block after required block.
118 self.
addOption(
'ignoreDependencies', [], type=list,
119 info=
'List of dependencies defined in the ConfigBlock to ignore.')
123 """Return True if there is a dependency."""
127 """Return the list of dependencies. """
131 type, info='', noneAction='ignore', required=False) :
132 """declare the given option on the configuration block
134 This should only be called in the constructor of the
137 NOTE: The backend to option handling is slated to be replaced
138 at some point. This particular function should essentially
139 stay the same, but some behavior may change.
142 raise KeyError (f
'duplicate option: {name}')
143 if type
not in [str, bool, int, float, list,
None] :
144 raise TypeError (f
'unknown option type: {type}')
145 noneActions = [
'error',
'set',
'ignore']
146 if noneAction
not in noneActions :
147 raise ValueError (f
'invalid noneAction: {noneAction} [allowed values: {noneActions}]')
148 setattr (self, name, defaultValue)
150 noneAction=noneAction, required=required, default=defaultValue)
154 """set the given option on the configuration block
156 NOTE: The backend to option handling is slated to be replaced
157 at some point. This particular function should essentially
158 stay the same, but some behavior may change.
162 raise KeyError (f
'unknown option "{name}" in block "{self.__class__.__name__}"')
163 noneAction = self.
_options[name].noneAction
164 if value
is not None or noneAction ==
'set' :
168 if optType
is float
and type(value)
is int:
170 if optType
is not None and optType !=
type(value):
171 raise ValueError(f
'{name} for block {self.__class__.__name__} should '
172 f
'be of type {optType} not {type(value)}')
173 setattr (self, name, value)
174 elif noneAction ==
'ignore' :
176 elif noneAction ==
'error' :
177 raise ValueError (f
'passed None for setting option {name} with noneAction=error')
181 """Returns config option value, if present; otherwise return None"""
183 return getattr(self, name)
187 """Return a copy of the options associated with the block"""
193 Prints options and their values
195 def printWrap(text, width=60, indent=" "):
196 wrapper = textwrap.TextWrapper(width=width, initial_indent=indent,
197 subsequent_indent=indent)
198 for line
in wrapper.wrap(text=text):
199 logCPAlgCfgBlock.info(line)
203 logCPAlgCfgBlock.info(indent + f
"\033[4m{opt}\033[0m: {self.getOptionValue(opt)}")
204 logCPAlgCfgBlock.info(indent*2 + f
"\033[4mtype\033[0m: {vals.type}")
205 logCPAlgCfgBlock.info(indent*2 + f
"\033[4mdefault\033[0m: {vals.default}")
206 logCPAlgCfgBlock.info(indent*2 + f
"\033[4mrequired\033[0m: {vals.required}")
207 logCPAlgCfgBlock.info(indent*2 + f
"\033[4mnoneAction\033[0m: {vals.noneAction}")
208 printWrap(f
"\033[4minfo\033[0m: {vals.info}", indent=indent*2)
210 logCPAlgCfgBlock.info(indent + f
"{ opt}: {self.getOptionValue(opt)}")
214 """whether the configuration block has the given option
216 WARNING: The backend to option handling is slated to be
217 replaced at some point. This particular function may change
218 behavior, interface or be removed/replaced entirely.
225 Implementation of == operator. Used for seaching configSeque.
226 E.g. if blockName in configSeq: