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

Public Member Functions

 __init__ (self, *, flags=None, algSeq=None, noSysSuffix=False, noSystematics=None, dataType=None, isPhyslite=None, geometry=None, dsid=0, campaign=None, runNumber=None, autoconfigFromFlags=None, dataYear=0)
 noSystematics (self)
 flags (self)
 autoconfigFlags (self)
 dataType (self)
 isPhyslite (self)
 geometry (self)
 dsid (self)
 campaign (self)
 runNumber (self)
 dataYear (self)
 generatorInfo (self)
 hltSummary (self)
 algPostfix (self)
 setAlgPostfix (self, str postfix)
 getAlgorithm (self, str name)
 createAlgorithm (self, type, name, reentrant=False)
 createService (self, type, name)
 createPublicTool (self, type, name)
 addPrivateTool (self, propertyName, toolType)
 setSourceName (self, containerName, sourceName, *, originalName=None, isMet=False)
 writeName (self, containerName, *, isMet=None)
 readName (self, containerName)
 copyName (self, containerName)
 wantCopy (self, containerName)
 originalName (self, containerName)
 getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False)
 setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False)
 isMetContainer (self, containerName)
 readNameAndSelection (self, containerName, *, excludeFrom=None)
 nextPass (self)
 getPreselection (self, containerName, selectionName, *, asList=False)
 getFullSelection (self, containerName, selectionName, *, skipBase=False, excludeFrom=None)
 getSelectionCutFlow (self, containerName, selectionName)
 addEventCutFlow (self, selection, decorations)
 getEventCutFlow (self, selection)
 addSelection (self, containerName, selectionName, decoration, **kwargs)
 addOutputContainer (self, containerName, outputContainerName)
 checkOutputContainer (self, containerName)
 getOutputContainerOrigin (self, outputContainerName)
 addOutputVar (self, containerName, variableName, outputName, *, noSys=False, enabled=True)
 getOutputVars (self, containerName)
 getSelectionNames (self, containerName, excludeFrom=None)

Public Attributes

 CA = None

Protected Attributes

 _flags = flags
 _dataType = dataType
 _isPhyslite = isPhyslite
 _hltSummary = hltSummary
 _algSeq = algSeq
 _noSystematics = noSystematics
 _noSysSuffix = noSysSuffix
str _algPostfix = ''
dict _containerConfig = {}
dict _outputContainers = {}
int _pass = 0
dict _algorithms = {}
dict _currentAlg = None
 _selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]+')
dict _eventcutflow = {}

Detailed Description

a class that accumulates a configuration from blocks into an
algorithm sequence

This is used as argument to the ConfigurationBlock methods, which
need to be called in the correct order.  This class will track all
meta-information that needs to be communicated between blocks
during configuration, and also add the created algorithms to the
sequence.

Use/access of containers in the event store is handled via
references that this class hands out.  This happens in a separate
step before the algorithms are created, as the naming of
containers will depend on where in the chain the container is
used.

Definition at line 127 of file ConfigAccumulator.py.

Constructor & Destructor Documentation

◆ __init__()

python.ConfigAccumulator.ConfigAccumulator.__init__ ( self,
* ,
flags = None,
algSeq = None,
noSysSuffix = False,
noSystematics = None,
dataType = None,
isPhyslite = None,
geometry = None,
dsid = 0,
campaign = None,
runNumber = None,
autoconfigFromFlags = None,
dataYear = 0 )

Definition at line 144 of file ConfigAccumulator.py.

144 def __init__ (self, *, flags=None, algSeq=None, noSysSuffix=False, noSystematics=None, dataType=None, isPhyslite=None, geometry=None, dsid=0, campaign=None, runNumber=None, autoconfigFromFlags=None, dataYear=0):
145
146 # Historically we have used the identifier
147 # `autoconfigFromFlags`, but in the rest of the code base
148 # `flags` is used. So for now we allow either, and can hopefully
149 # at some point remove the former (21 Aug 25).
150 if autoconfigFromFlags is not None:
151 if flags is not None:
152 raise ValueError("Cannot pass both flags and autoconfigFromFlags arguments")
153 flags = autoconfigFromFlags
154 warnings.warn ('Using autoconfigFromFlags parameter is deprecated, use flags instead', category=deprecationWarningCategory, stacklevel=2)
155 self._flags = flags
156
157 # Historically the user was expected to pass in meta-data
158 # manually, which was a complete underestimate of the amount of
159 # meta-data needed. The current recommendation is to pass in a
160 # configuration flags object instead. The code below will raise
161 # an error if both are done, and if no configuration flags are
162 # passed in, it will try to create a flags object from the
163 # passed in parameters.
164 if self._flags is not None:
165 if dataType is not None:
166 raise ValueError("Cannot pass both dataType and flags/autoconfigFromFlags arguments")
167 if isPhyslite is not None:
168 raise ValueError("Cannot pass both isPhyslite and flags/autoconfigFromFlags arguments")
169 if geometry is not None:
170 raise ValueError("Cannot pass both geometry and flags/autoconfigFromFlags arguments")
171 if dsid != 0:
172 raise ValueError("Cannot pass both dsid and flags/autoconfigFromFlags arguments")
173 if campaign is not None:
174 raise ValueError("Cannot pass both campaign and flags/autoconfigFromFlags arguments")
175 if runNumber is not None:
176 raise ValueError("Cannot pass both runNumber and flags/autoconfigFromFlags arguments")
177 if dataYear != 0:
178 raise ValueError("Cannot pass both dataYear and flags/autoconfigFromFlags arguments")
179
180 if self._flags.Input.isMC:
181 if self._flags.Sim.ISF.Simulator.usesFastCaloSim():
182 dataType = DataType.FastSim
183 else:
184 dataType = DataType.FullSim
185 else:
186 dataType = DataType.Data
187 isPhyslite = 'StreamDAOD_PHYSLITE' in self._flags.Input.ProcessingTags
188 from TrigDecisionTool.TrigDecisionToolHelpers import (
189 getRun3NavigationContainerFromInput_forAnalysisBase)
190 hltSummary = getRun3NavigationContainerFromInput_forAnalysisBase(self._flags)
191 else:
192 warnings.warn ('it is deprecated to configure meta-data for analysis configuration manually, please read the configuration flags via the meta-data reader', category=deprecationWarningCategory, stacklevel=2)
193 from AthenaConfiguration.AllConfigFlags import initConfigFlags
194 flags = initConfigFlags()
195 if dataType is None:
196 raise ValueError ("need to specify dataType if flags are not set")
197 # legacy mappings of string arguments
198 if isinstance(dataType, str):
199 if dataType == 'mc':
200 dataType = DataType.FullSim
201 elif dataType == 'afii':
202 dataType = DataType.FastSim
203 else:
204 dataType = DataType(dataType)
205 if isPhyslite is None:
206 isPhyslite = False
207 if geometry is not None:
208 # allow possible string argument for `geometry` and convert it to enum
209 geometry = LHCPeriod(geometry)
210 if geometry is LHCPeriod.Run1:
211 raise ValueError ("invalid Run geometry: %s" % geometry.value)
212 flags.GeoModel.Run = geometry
213 if dsid != 0:
214 flags.Input.MCChannelNumber = dsid
215 if campaign is not None:
216 flags.Input.MCCampaign = campaign
217 if dataYear != 0:
218 flags.Input.DataYear = dataYear
219 if runNumber is None:
220 # not sure if we should just use a default run number
221 # here, or just report nothing
222 runNumber = 284500
223 flags.Input.RunNumbers = [runNumber]
224 hltSummary = 'HLTNav_Summary_DAODSlimmed'
225 flags.lock()
226 self._flags = flags
227
228 # These don't seem to have a direct equivalent in the
229 # configuration flags. For now I'm keeping them (21 Aug 25), but
230 # they might be replaced with something that is more directly in
231 # the configuration flags in the future.
232 self._dataType = dataType
233 self._isPhyslite = isPhyslite
234 self._hltSummary = hltSummary
235
236 # From here on, we are no longer dealing with flags or
237 # meta-data, but actual internal variables we need to manage the
238 # creation of components.
239 self._algSeq = algSeq
240 self._noSystematics = noSystematics
241 self._noSysSuffix = noSysSuffix
242 self._algPostfix = ''
243 self._containerConfig = {}
244 self._outputContainers = {}
245 self._pass = 0
246 self._algorithms = {}
247 self._currentAlg = None
248 self._selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]+')
249 self.setSourceName ('EventInfo', 'EventInfo')
250 self._eventcutflow = {}
251
252 # If we are in an Athena environment with ComponentAccumulator configuration
253 # then the AlgSequence, which is Gaudi.AthSequencer, does not support '+=',
254 # and we in any case want to produce an output ComponentAccumulator
255 self.CA = None
256 if DualUseConfig.useComponentAccumulator:
257 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
258 self.CA = ComponentAccumulator()
259 # if we have a component accumulator the user is not required to pass
260 # in a sequence, but if they do let's add it
261 if algSeq :
262 self.CA.addSequence(algSeq)
263 else :
264 if algSeq is None :
265 raise ValueError ("need to pass algSeq if not using ComponentAccumulator")
266
267

Member Function Documentation

◆ addEventCutFlow()

python.ConfigAccumulator.ConfigAccumulator.addEventCutFlow ( self,
selection,
decorations )
register a new event cutflow, adding it to the dictionary with key 'selection'
and value 'decorations', a list of decorated selections

Definition at line 711 of file ConfigAccumulator.py.

711 def addEventCutFlow (self, selection, decorations) :
712
713 """register a new event cutflow, adding it to the dictionary with key 'selection'
714 and value 'decorations', a list of decorated selections
715 """
716 if self._pass == 0:
717 if selection in self._eventcutflow.keys():
718 raise ValueError ('the event cutflow dictionary already contains an entry ' + selection)
719 else:
720 self._eventcutflow[selection] = decorations
721
722

◆ addOutputContainer()

python.ConfigAccumulator.ConfigAccumulator.addOutputContainer ( self,
containerName,
outputContainerName )
register a copy of a container used in outputs

Definition at line 744 of file ConfigAccumulator.py.

744 def addOutputContainer (self, containerName, outputContainerName) :
745 """register a copy of a container used in outputs"""
746 if containerName not in self._containerConfig :
747 raise KeyError ("container unknown: " + containerName)
748 if outputContainerName in self._outputContainers :
749 raise KeyError ("duplicate output container name: " + outputContainerName)
750 self._outputContainers[outputContainerName] = containerName
751
752

◆ addOutputVar()

python.ConfigAccumulator.ConfigAccumulator.addOutputVar ( self,
containerName,
variableName,
outputName,
* ,
noSys = False,
enabled = True )
add an output variable for the given container to the output

Definition at line 769 of file ConfigAccumulator.py.

770 *, noSys=False, enabled=True) :
771 """add an output variable for the given container to the output
772 """
773
774 if containerName not in self._containerConfig :
775 raise KeyError ("container unknown: " + containerName)
776 baseConfig = self._containerConfig[containerName].outputs
777 if outputName in baseConfig :
778 raise KeyError ("duplicate output variable name: " + outputName)
779 config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled)
780 baseConfig[outputName] = config
781
782

◆ addPrivateTool()

python.ConfigAccumulator.ConfigAccumulator.addPrivateTool ( self,
propertyName,
toolType )
add a private tool to the current algorithm

Definition at line 434 of file ConfigAccumulator.py.

434 def addPrivateTool (self, propertyName, toolType) :
435 """add a private tool to the current algorithm"""
436 if self._pass == 0 :
437 DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
438
439

◆ addSelection()

python.ConfigAccumulator.ConfigAccumulator.addSelection ( self,
containerName,
selectionName,
decoration,
** kwargs )
add another selection decoration to the selection of the given
name for the given container

Definition at line 731 of file ConfigAccumulator.py.

732 **kwargs) :
733 """add another selection decoration to the selection of the given
734 name for the given container"""
735 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
736 raise ValueError ('invalid selection name: ' + selectionName)
737 if containerName not in self._containerConfig :
738 self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
739 config = self._containerConfig[containerName]
740 selection = SelectionConfig (selectionName, decoration, **kwargs)
741 config.selections.append (selection)
742
743

◆ algPostfix()

python.ConfigAccumulator.ConfigAccumulator.algPostfix ( self)
the current postfix to be appended to algorithm names

Blocks should not call this directly, but rather implement the
instanceName method, which will be used to generate the postfix
automatically.

Definition at line 321 of file ConfigAccumulator.py.

321 def algPostfix (self) :
322 """the current postfix to be appended to algorithm names
323
324 Blocks should not call this directly, but rather implement the
325 instanceName method, which will be used to generate the postfix
326 automatically."""
327 return self._algPostfix
328

◆ autoconfigFlags()

python.ConfigAccumulator.ConfigAccumulator.autoconfigFlags ( self)
Athena configuration flags

This is a backward compatibility version of the flags property,
which is preferred.

Definition at line 278 of file ConfigAccumulator.py.

278 def autoconfigFlags (self) :
279 """Athena configuration flags
280
281 This is a backward compatibility version of the flags property,
282 which is preferred."""
283 return self._flags
284

◆ campaign()

python.ConfigAccumulator.ConfigAccumulator.campaign ( self)
the MC campaign we run on

Definition at line 301 of file ConfigAccumulator.py.

301 def campaign(self) :
302 """the MC campaign we run on"""
303 return self._flags.Input.MCCampaign
304

◆ checkOutputContainer()

python.ConfigAccumulator.ConfigAccumulator.checkOutputContainer ( self,
containerName )
check whether a given container has been registered in outputs

Definition at line 753 of file ConfigAccumulator.py.

753 def checkOutputContainer (self, containerName) :
754 """check whether a given container has been registered in outputs"""
755 return containerName in self._outputContainers.values()
756
757

◆ copyName()

python.ConfigAccumulator.ConfigAccumulator.copyName ( self,
containerName )
register that a copy of the container will be made and return
its name

Definition at line 486 of file ConfigAccumulator.py.

486 def copyName (self, containerName) :
487 """register that a copy of the container will be made and return
488 its name"""
489 if containerName not in self._containerConfig :
490 raise Exception ("unknown container: " + containerName)
491 self._containerConfig[containerName].index += 1
492 return self._containerConfig[containerName].currentName()
493
494

◆ createAlgorithm()

python.ConfigAccumulator.ConfigAccumulator.createAlgorithm ( self,
type,
name,
reentrant = False )
create a new algorithm and register it as the current algorithm

Definition at line 356 of file ConfigAccumulator.py.

356 def createAlgorithm (self, type, name, reentrant=False) :
357 """create a new algorithm and register it as the current algorithm"""
358 name = name + self._algPostfix
359 if self._pass == 0 :
360 if name in self._algorithms :
361 raise Exception ('duplicate algorithms: ' + name + ' with algPostfix=' + self._algPostfix)
362 if reentrant:
363 alg = DualUseConfig.createReentrantAlgorithm (type, name)
364 else:
365 alg = DualUseConfig.createAlgorithm (type, name)
366
367 if DualUseConfig.useComponentAccumulator:
368 if self._algSeq :
369 self.CA.addEventAlgo(alg,self._algSeq.name)
370 else :
371 self.CA.addEventAlgo(alg)
372 else:
373 self._algSeq += alg
374 self._algorithms[name] = alg
375 self._currentAlg = alg
376 return alg
377 else :
378 if name not in self._algorithms :
379 raise Exception ('unknown algorithm requested: ' + name)
380 self._currentAlg = self._algorithms[name]
381 if self.CA and self._currentAlg != self.CA.getEventAlgo(name) :
382 raise Exception ('change to algorithm object: ' + name)
383 return self._algorithms[name]
384
385

◆ createPublicTool()

python.ConfigAccumulator.ConfigAccumulator.createPublicTool ( self,
type,
name )
create a new public tool and register it as the "current algorithm"

Definition at line 410 of file ConfigAccumulator.py.

410 def createPublicTool (self, type, name) :
411 '''create a new public tool and register it as the "current algorithm"'''
412 if self._pass == 0 :
413 if name in self._algorithms :
414 raise Exception ('duplicate public tool: ' + name)
415 tool = DualUseConfig.createPublicTool (type, name)
416 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
417 # as it modifies Gaudi behaviour
418 if DualUseConfig.isAthena:
419 if DualUseConfig.useComponentAccumulator:
420 self.CA.addPublicTool(tool)
421 else:
422 # We're not, so let's remember this as a "normal" algorithm:
423 self._algSeq += tool
424 self._algorithms[name] = tool
425 self._currentAlg = tool
426 return tool
427 else :
428 if name not in self._algorithms :
429 raise Exception ('unknown public tool requested: ' + name)
430 self._currentAlg = self._algorithms[name]
431 return self._algorithms[name]
432
433

◆ createService()

python.ConfigAccumulator.ConfigAccumulator.createService ( self,
type,
name )
create a new service and register it as the "current algorithm"

Definition at line 386 of file ConfigAccumulator.py.

386 def createService (self, type, name) :
387 '''create a new service and register it as the "current algorithm"'''
388 if self._pass == 0 :
389 if name in self._algorithms :
390 raise Exception ('duplicate service: ' + name)
391 service = DualUseConfig.createService (type, name)
392 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
393 # as it modifies Gaudi behaviour
394 if DualUseConfig.isAthena:
395 if DualUseConfig.useComponentAccumulator:
396 self.CA.addService(service)
397 else:
398 # We're not, so let's remember this as a "normal" algorithm:
399 self._algSeq += service
400 self._algorithms[name] = service
401 self._currentAlg = service
402 return service
403 else :
404 if name not in self._algorithms :
405 raise Exception ('unknown service requested: ' + name)
406 self._currentAlg = self._algorithms[name]
407 return self._algorithms[name]
408
409

◆ dataType()

python.ConfigAccumulator.ConfigAccumulator.dataType ( self)
the data type we run on (data, fullsim, fastsim)

Definition at line 285 of file ConfigAccumulator.py.

285 def dataType (self) :
286 """the data type we run on (data, fullsim, fastsim)"""
287 return self._dataType
288

◆ dataYear()

python.ConfigAccumulator.ConfigAccumulator.dataYear ( self)
for data, the corresponding year; for MC, zero

Definition at line 309 of file ConfigAccumulator.py.

309 def dataYear(self) :
310 """for data, the corresponding year; for MC, zero"""
311 return self._flags.Input.DataYear
312

◆ dsid()

python.ConfigAccumulator.ConfigAccumulator.dsid ( self)
the mcChannelNumber or DSID of the sample we run on

Definition at line 297 of file ConfigAccumulator.py.

297 def dsid(self) :
298 """the mcChannelNumber or DSID of the sample we run on"""
299 return self._flags.Input.MCChannelNumber
300

◆ flags()

python.ConfigAccumulator.ConfigAccumulator.flags ( self)
Athena configuration flags

Definition at line 273 of file ConfigAccumulator.py.

273 def flags (self) :
274 """Athena configuration flags"""
275 return self._flags
276

◆ generatorInfo()

python.ConfigAccumulator.ConfigAccumulator.generatorInfo ( self)
the dictionary of MC generators and their versions for the sample we run on

Definition at line 313 of file ConfigAccumulator.py.

313 def generatorInfo(self) :
314 """the dictionary of MC generators and their versions for the sample we run on"""
315 return self._flags.Input.GeneratorsInfo
316

◆ geometry()

python.ConfigAccumulator.ConfigAccumulator.geometry ( self)
the LHC Run period we run on

Definition at line 293 of file ConfigAccumulator.py.

293 def geometry (self) :
294 """the LHC Run period we run on"""
295 return self._flags.GeoModel.Run
296

◆ getAlgorithm()

python.ConfigAccumulator.ConfigAccumulator.getAlgorithm ( self,
str name )
get the algorithm with the given name

Despite the name this will also return services and tools. It is
mostly meant for internal use, particularly for the property
overrides.

Definition at line 345 of file ConfigAccumulator.py.

345 def getAlgorithm (self, name : str):
346 """get the algorithm with the given name
347
348 Despite the name this will also return services and tools. It is
349 mostly meant for internal use, particularly for the property
350 overrides."""
351 name = name + self._algPostfix
352 if name not in self._algorithms:
353 return None
354 return self._algorithms[name]
355

◆ getContainerMeta()

python.ConfigAccumulator.ConfigAccumulator.getContainerMeta ( self,
containerName,
metaField,
defaultValue = None,
* ,
failOnMiss = False )
get the meta information for the given container

This is used to pass down meta-information from the
configuration to the algorithms.

Definition at line 520 of file ConfigAccumulator.py.

520 def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
521 """get the meta information for the given container
522
523 This is used to pass down meta-information from the
524 configuration to the algorithms.
525 """
526 if containerName not in self._containerConfig :
527 raise Exception ("container unknown: " + containerName)
528 if metaField in self._containerConfig[containerName].meta :
529 return self._containerConfig[containerName].meta[metaField]
530 if failOnMiss :
531 raise Exception ('unknown meta-field' + metaField + ' on container ' + containerName)
532 return defaultValue
533

◆ getEventCutFlow()

python.ConfigAccumulator.ConfigAccumulator.getEventCutFlow ( self,
selection )
get the list of decorated selections for an event cutflow,  corresponding to
key 'selection'

Definition at line 723 of file ConfigAccumulator.py.

723 def getEventCutFlow (self, selection) :
724
725 """get the list of decorated selections for an event cutflow, corresponding to
726 key 'selection'
727 """
728 return self._eventcutflow[selection]
729
730

◆ getFullSelection()

python.ConfigAccumulator.ConfigAccumulator.getFullSelection ( self,
containerName,
selectionName,
* ,
skipBase = False,
excludeFrom = None )
get the selection string for the given selection on the given
container

This can handle both individual selections or selection
expressions (e.g. `loose||tight`) with the later being
properly expanded.  Either way the base selection (i.e. the
selection without a name) will always be applied on top.

containerName --- the container the selection is defined on
selectionName --- the name of the selection, or a selection
                  expression based on multiple named selections
skipBase --- will avoid the base selection, and should normally
             not be used by the end-user.
excludeFrom --- a set of string names of selection sources to exclude
                e.g. to exclude OR selections from MET

Definition at line 613 of file ConfigAccumulator.py.

614 *, skipBase = False, excludeFrom = None) :
615
616 """get the selection string for the given selection on the given
617 container
618
619 This can handle both individual selections or selection
620 expressions (e.g. `loose||tight`) with the later being
621 properly expanded. Either way the base selection (i.e. the
622 selection without a name) will always be applied on top.
623
624 containerName --- the container the selection is defined on
625 selectionName --- the name of the selection, or a selection
626 expression based on multiple named selections
627 skipBase --- will avoid the base selection, and should normally
628 not be used by the end-user.
629 excludeFrom --- a set of string names of selection sources to exclude
630 e.g. to exclude OR selections from MET
631 """
632 if "." in containerName:
633 raise ValueError (f'invalid containerName argument: {containerName} , it contains a "." '
634 'which is used to indicate container+selection. You should only pass the container.')
635 if containerName not in self._containerConfig :
636 return ""
637
638 if excludeFrom is None :
639 excludeFrom = set()
640 elif not isinstance(excludeFrom, set) :
641 raise ValueError ('invalid excludeFrom argument (need set of strings): ' + str(excludeFrom))
642
643 # Check if this is actually a selection expression,
644 # e.g. `A||B` and if so translate it into a complex expression
645 # for the user. I'm not trying to do any complex syntax
646 # recognition, but instead just produce an expression that the
647 # C++ parser ought to be able to read.
648 if selectionName != '' and \
649 not self._selectionNameExpr.fullmatch (selectionName) :
650 result = ''
651 while selectionName != '' :
652 match = self._selectionNameExpr.match (selectionName)
653 if not match :
654 result += selectionName[0]
655 selectionName = selectionName[1:]
656 else :
657 subname = match.group(0)
658 subresult = self.getFullSelection (containerName, subname, skipBase = True, excludeFrom=excludeFrom)
659 if subresult != '' :
660 result += '(' + subresult + ')'
661 else :
662 result += 'true'
663 selectionName = selectionName[len(subname):]
664 subresult = self.getFullSelection (containerName, '', excludeFrom=excludeFrom)
665 if subresult != '' :
666 result = subresult + '&&(' + result + ')'
667 return '(' + result + ')' if result !='' else ''
668
669 config = self._containerConfig[containerName]
670 decorations = []
671 hasSelectionName = False
672 for selection in config.selections :
673 if ((selection.name == '' and not skipBase) or selection.name == selectionName) and (selection.comesFrom not in excludeFrom) :
674 decorations += [selection.decoration]
675 if selection.name == selectionName :
676 hasSelectionName = True
677 if not hasSelectionName and selectionName != '' :
678 raise KeyError ('invalid selection name: ' + containerName + '.' + selectionName)
679 return '&&'.join (decorations)
680
681
STL class.

◆ getOutputContainerOrigin()

python.ConfigAccumulator.ConfigAccumulator.getOutputContainerOrigin ( self,
outputContainerName )
Get the name of the actual container, for which an output is registered

Definition at line 758 of file ConfigAccumulator.py.

758 def getOutputContainerOrigin (self, outputContainerName) :
759 """Get the name of the actual container, for which an output is registered"""
760 try:
761 return self._outputContainers[outputContainerName]
762 except KeyError:
763 try:
764 return self._containerConfig[outputContainerName].name
765 except KeyError:
766 raise KeyError ("output container unknown: " + outputContainerName)
767
768

◆ getOutputVars()

python.ConfigAccumulator.ConfigAccumulator.getOutputVars ( self,
containerName )
get the output variables for the given container

Definition at line 783 of file ConfigAccumulator.py.

783 def getOutputVars (self, containerName) :
784 """get the output variables for the given container"""
785 if containerName in self._outputContainers :
786 containerName = self._outputContainers[containerName]
787 if containerName not in self._containerConfig :
788 raise KeyError ("unknown container for output: " + containerName)
789 return self._containerConfig[containerName].outputs
790
791

◆ getPreselection()

python.ConfigAccumulator.ConfigAccumulator.getPreselection ( self,
containerName,
selectionName,
* ,
asList = False )
get the preselection string for the given selection on the given
container

Definition at line 592 of file ConfigAccumulator.py.

592 def getPreselection (self, containerName, selectionName, *, asList = False) :
593
594 """get the preselection string for the given selection on the given
595 container
596 """
597 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
598 raise ValueError ('invalid selection name: ' + selectionName)
599 if containerName not in self._containerConfig :
600 return ""
601 config = self._containerConfig[containerName]
602 decorations = []
603 for selection in config.selections :
604 if (selection.name == '' or selection.name == selectionName) and \
605 selection.preselection :
606 decorations += [selection.decoration]
607 if asList :
608 return decorations
609 else :
610 return '&&'.join (decorations)
611
612

◆ getSelectionCutFlow()

python.ConfigAccumulator.ConfigAccumulator.getSelectionCutFlow ( self,
containerName,
selectionName )
get the individual selections as a list for producing the cutflow for
the given selection on the given container

This can only handle individual selections, not selection
expressions (e.g. `loose||tight`).

Definition at line 682 of file ConfigAccumulator.py.

682 def getSelectionCutFlow (self, containerName, selectionName) :
683
684 """get the individual selections as a list for producing the cutflow for
685 the given selection on the given container
686
687 This can only handle individual selections, not selection
688 expressions (e.g. `loose||tight`).
689
690 """
691 if containerName not in self._containerConfig :
692 return []
693
694 # Check if this is actually a selection expression,
695 # e.g. `A||B` and if so translate it into a complex expression
696 # for the user. I'm not trying to do any complex syntax
697 # recognition, but instead just produce an expression that the
698 # C++ parser ought to be able to read.
699 if selectionName != '' and \
700 not self._selectionNameExpr.fullmatch (selectionName) :
701 raise ValueError ('not allowed to do cutflow on selection expression: ' + selectionName)
702
703 config = self._containerConfig[containerName]
704 decorations = []
705 for selection in config.selections :
706 if (selection.name == '' or selection.name == selectionName) :
707 decorations += [selection.decoration]
708 return decorations
709
710

◆ getSelectionNames()

python.ConfigAccumulator.ConfigAccumulator.getSelectionNames ( self,
containerName,
excludeFrom = None )
Retrieve set of unique selections defined for a given container

Definition at line 792 of file ConfigAccumulator.py.

792 def getSelectionNames (self, containerName, excludeFrom = None) :
793 """Retrieve set of unique selections defined for a given container"""
794 if containerName not in self._containerConfig :
795 return []
796 if excludeFrom is None:
797 excludeFrom = set()
798 elif not isinstance(excludeFrom, set) :
799 raise ValueError ('invalid excludeFrom argument (need set of strings): ' + str(excludeFrom))
800
801 config = self._containerConfig[containerName]
802 # because cuts are registered individually, selection names can repeat themselves
803 # but we are interested in unique names only
804 selectionNames = set()
805 for selection in config.selections:
806 if selection.comesFrom in excludeFrom:
807 continue
808 # skip flags which should be disabled in output
809 if selection.writeToOutput:
810 selectionNames.add(selection.name)
811 return selectionNames

◆ hltSummary()

python.ConfigAccumulator.ConfigAccumulator.hltSummary ( self)
the HLTSummary configuration to be used for the trigger decision tool

Definition at line 317 of file ConfigAccumulator.py.

317 def hltSummary(self) :
318 """the HLTSummary configuration to be used for the trigger decision tool"""
319 return self._hltSummary
320

◆ isMetContainer()

python.ConfigAccumulator.ConfigAccumulator.isMetContainer ( self,
containerName )
whether the given container is registered as a MET container

This is mostly/exclusively used for determining whether to
write out the whole container or just a single MET term.

Definition at line 546 of file ConfigAccumulator.py.

546 def isMetContainer (self, containerName) :
547 """whether the given container is registered as a MET container
548
549 This is mostly/exclusively used for determining whether to
550 write out the whole container or just a single MET term.
551 """
552 if containerName not in self._containerConfig :
553 raise Exception ("container unknown: " + containerName)
554 return self._containerConfig[containerName].isMet
555
556

◆ isPhyslite()

python.ConfigAccumulator.ConfigAccumulator.isPhyslite ( self)
whether we run on PHYSLITE

Definition at line 289 of file ConfigAccumulator.py.

289 def isPhyslite (self) :
290 """whether we run on PHYSLITE"""
291 return self._isPhyslite
292

◆ nextPass()

python.ConfigAccumulator.ConfigAccumulator.nextPass ( self)
switch to the next configuration pass

Configuration happens in two steps, with all the blocks processed
twice.  This switches from the first to the second pass.

Definition at line 577 of file ConfigAccumulator.py.

577 def nextPass (self) :
578 """switch to the next configuration pass
579
580 Configuration happens in two steps, with all the blocks processed
581 twice. This switches from the first to the second pass.
582 """
583 if self._pass != 0 :
584 raise Exception ("already performed final pass")
585 for name in self._containerConfig :
586 self._containerConfig[name].nextPass ()
587 self._pass = 1
588 self._currentAlg = None
589 self._outputContainers = {}
590
591

◆ noSystematics()

python.ConfigAccumulator.ConfigAccumulator.noSystematics ( self)
noSystematics flag used by CommonServices block

Definition at line 268 of file ConfigAccumulator.py.

268 def noSystematics (self) :
269 """noSystematics flag used by CommonServices block"""
270 return self._noSystematics
271

◆ originalName()

python.ConfigAccumulator.ConfigAccumulator.originalName ( self,
containerName )
get the "original" name of the given container

This is mostly/exclusively used for jet containers, so that
subsequent configurations know which jet container they
operate on.

Definition at line 506 of file ConfigAccumulator.py.

506 def originalName (self, containerName) :
507 """get the "original" name of the given container
508
509 This is mostly/exclusively used for jet containers, so that
510 subsequent configurations know which jet container they
511 operate on.
512 """
513 if containerName not in self._containerConfig :
514 raise Exception ("container unknown: " + containerName)
515 result = self._containerConfig[containerName].originalName
516 if result is None :
517 raise Exception ("no original name for: " + containerName)
518 return result
519

◆ readName()

python.ConfigAccumulator.ConfigAccumulator.readName ( self,
containerName )
get the name of the "current copy" of the given container

As extra copies get created during processing this will track
the correct name of the current copy.  Optionally one can pass
in the name of the container before the first copy.

Definition at line 474 of file ConfigAccumulator.py.

474 def readName (self, containerName) :
475 """get the name of the "current copy" of the given container
476
477 As extra copies get created during processing this will track
478 the correct name of the current copy. Optionally one can pass
479 in the name of the container before the first copy.
480 """
481 if containerName not in self._containerConfig :
482 raise Exception ("no source container for: " + containerName)
483 return self._containerConfig[containerName].currentName()
484
485

◆ readNameAndSelection()

python.ConfigAccumulator.ConfigAccumulator.readNameAndSelection ( self,
containerName,
* ,
excludeFrom = None )
get the name of the "current copy" of the given container, and the
selection string

This is mostly meant for MET and OR for whom the actual object
selection is relevant, and which as such allow to pass in the
working point as "ObjectName.WorkingPoint".

Definition at line 557 of file ConfigAccumulator.py.

557 def readNameAndSelection (self, containerName, *, excludeFrom = None) :
558 """get the name of the "current copy" of the given container, and the
559 selection string
560
561 This is mostly meant for MET and OR for whom the actual object
562 selection is relevant, and which as such allow to pass in the
563 working point as "ObjectName.WorkingPoint".
564 """
565 split = containerName.split (".")
566 if len(split) == 1 :
567 objectName = split[0]
568 selectionName = ''
569 elif len(split) == 2 :
570 objectName = split[0]
571 selectionName = split[1]
572 else :
573 raise Exception ('invalid object selection name: ' + containerName)
574 return self.readName (objectName), self.getFullSelection (objectName, selectionName, excludeFrom=excludeFrom)
575
576

◆ runNumber()

python.ConfigAccumulator.ConfigAccumulator.runNumber ( self)
the MC runNumber

Definition at line 305 of file ConfigAccumulator.py.

305 def runNumber(self) :
306 """the MC runNumber"""
307 return int(self._flags.Input.RunNumbers[0])
308

◆ setAlgPostfix()

python.ConfigAccumulator.ConfigAccumulator.setAlgPostfix ( self,
str postfix )
set the current postfix to be appended to algorithm names

Blocks should not call this directly, but rather implement the
instanceName method, which will be used to generate the postfix
automatically.

Definition at line 329 of file ConfigAccumulator.py.

329 def setAlgPostfix (self, postfix : str) :
330 """set the current postfix to be appended to algorithm names
331
332 Blocks should not call this directly, but rather implement the
333 instanceName method, which will be used to generate the postfix
334 automatically."""
335 # make sure the postfix matches the expected format ([_a-zA-Z0-9]*)
336 if re.compile ('^[_a-zA-Z0-9]*$').match (postfix) is None :
337 raise ValueError ('invalid algorithm postfix: ' + postfix)
338 if postfix == '' :
339 self._algPostfix = ''
340 elif postfix[0] != '_' :
341 self._algPostfix = '_' + postfix
342 else :
343 self._algPostfix = postfix
344

◆ setContainerMeta()

python.ConfigAccumulator.ConfigAccumulator.setContainerMeta ( self,
containerName,
metaField,
value,
* ,
allowOverwrite = False )
set the meta information for the given container

This is used to pass down meta-information from the
configuration to the algorithms.

Definition at line 534 of file ConfigAccumulator.py.

534 def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
535 """set the meta information for the given container
536
537 This is used to pass down meta-information from the
538 configuration to the algorithms.
539 """
540 if containerName not in self._containerConfig :
541 raise Exception ("container unknown: " + containerName)
542 if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
543 raise Exception ('duplicate meta-field' + metaField + ' on container ' + containerName)
544 self._containerConfig[containerName].meta[metaField] = value
545

◆ setSourceName()

python.ConfigAccumulator.ConfigAccumulator.setSourceName ( self,
containerName,
sourceName,
* ,
originalName = None,
isMet = False )
set the (default) name of the source/original container

This is essentially meant to allow using e.g. the muon
configuration and the user not having to manually specify that
they want to use the Muons/AnalysisMuons container from the
input file.

In addition it allows to set the original name of the
container (which may be different from the source name), which
is mostly/exclusively used for jet containers, so that
subsequent configurations know which jet container they
operate on.

Definition at line 440 of file ConfigAccumulator.py.

441 *, originalName = None, isMet = False) :
442 """set the (default) name of the source/original container
443
444 This is essentially meant to allow using e.g. the muon
445 configuration and the user not having to manually specify that
446 they want to use the Muons/AnalysisMuons container from the
447 input file.
448
449 In addition it allows to set the original name of the
450 container (which may be different from the source name), which
451 is mostly/exclusively used for jet containers, so that
452 subsequent configurations know which jet container they
453 operate on.
454 """
455 if containerName not in self._containerConfig :
456 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName, noSysSuffix = self._noSysSuffix, originalName = originalName, isMet = isMet)
457
458

◆ wantCopy()

python.ConfigAccumulator.ConfigAccumulator.wantCopy ( self,
containerName )
ask whether we want/need a copy of the container

This usually only happens if no copy of the container has been
made yet and the copy is needed to allow modifications, etc.

Definition at line 495 of file ConfigAccumulator.py.

495 def wantCopy (self, containerName) :
496 """ask whether we want/need a copy of the container
497
498 This usually only happens if no copy of the container has been
499 made yet and the copy is needed to allow modifications, etc.
500 """
501 if containerName not in self._containerConfig :
502 raise Exception ("no source container for: " + containerName)
503 return self._containerConfig[containerName].index == 0
504
505

◆ writeName()

python.ConfigAccumulator.ConfigAccumulator.writeName ( self,
containerName,
* ,
isMet = None )
register that the given container will be made and return
its name

Definition at line 459 of file ConfigAccumulator.py.

459 def writeName (self, containerName, *, isMet=None) :
460 """register that the given container will be made and return
461 its name"""
462 if containerName not in self._containerConfig :
463 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName = None, noSysSuffix = self._noSysSuffix)
464 if self._containerConfig[containerName].sourceName is not None :
465 raise Exception ("trying to write container configured for input: " + containerName)
466 if self._containerConfig[containerName].index != 0 :
467 raise Exception ("trying to write container twice: " + containerName)
468 self._containerConfig[containerName].index += 1
469 if isMet is not None :
470 self._containerConfig[containerName].isMet = isMet
471 return self._containerConfig[containerName].currentName()
472
473

Member Data Documentation

◆ _algorithms

dict python.ConfigAccumulator.ConfigAccumulator._algorithms = {}
protected

Definition at line 246 of file ConfigAccumulator.py.

◆ _algPostfix

python.ConfigAccumulator.ConfigAccumulator._algPostfix = ''
protected

Definition at line 242 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq = algSeq
protected

Definition at line 239 of file ConfigAccumulator.py.

◆ _containerConfig

dict python.ConfigAccumulator.ConfigAccumulator._containerConfig = {}
protected

Definition at line 243 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg = None
protected

Definition at line 247 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType = dataType
protected

Definition at line 232 of file ConfigAccumulator.py.

◆ _eventcutflow

dict python.ConfigAccumulator.ConfigAccumulator._eventcutflow = {}
protected

Definition at line 250 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags = flags
protected

Definition at line 155 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary = hltSummary
protected

Definition at line 234 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite = isPhyslite
protected

Definition at line 233 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix = noSysSuffix
protected

Definition at line 241 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics = noSystematics
protected

Definition at line 240 of file ConfigAccumulator.py.

◆ _outputContainers

dict python.ConfigAccumulator.ConfigAccumulator._outputContainers = {}
protected

Definition at line 244 of file ConfigAccumulator.py.

◆ _pass

int python.ConfigAccumulator.ConfigAccumulator._pass = 0
protected

Definition at line 245 of file ConfigAccumulator.py.

◆ _selectionNameExpr

python.ConfigAccumulator.ConfigAccumulator._selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]+')
protected

Definition at line 248 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA = None

Definition at line 255 of file ConfigAccumulator.py.


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