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

Public Member Functions

 beginJob (cls)
 __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)
 defaultHistogramStream (self)
 setDefaultHistogramStream (self, str streamName)
 algPostfix (self)
 setAlgPostfix (self, str postfix)
 getAlgorithm (self, str name)
 createAlgorithm (self, type, name, reentrant=False)
 createService (self, type, name, isSingleton=True)
 createPublicTool (self, type, name, isSingleton=True)
 addPrivateTool (self, propertyName, toolType)
 setExtraInputs (self, inputs)
 setExtraOutputs (self, outputs)
 setSourceName (self, containerName, sourceName, *, originalName=None, isMet=False)
 writeName (self, containerName, *, isMet=None)
 readName (self, containerName, *, nominal=False)
 copyName (self, containerName)
 wantCopy (self, containerName)
 renameFinalContainers (self)
 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)
 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)
 getOutputContainerOrigin (self, outputContainerName)
 addOutputVar (self, containerName, variableName, outputName, *, noSys=False, enabled=True, auxType=None)
 getOutputVars (self, containerName)
 getSelectionNames (self, containerName, excludeFrom=None)

Public Attributes

 CA = None

Protected Member Functions

 _createServiceOrTool (self, type, name, isSingleton, kind, create, add)

Protected Attributes

 _flags = flags
 _dataType = dataType
 _isPhyslite = isPhyslite
 _hltSummary = hltSummary
 _algSeq = algSeq
 _noSystematics = noSystematics
 _noSysSuffix = noSysSuffix
str _algPostfix = ''
str _defaultHistogramStream = 'ANALYSIS'
dict _containerConfig = {}
dict _outputContainers = {}
dict _algorithms = {}
 _currentAlg = None
 _selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]*')
dict _eventcutflow = {}
str _algPrefix = f'seq{self._instance_counter}_'

Static Protected Attributes

int _instance_counter = 0
dict _singleton_registry = {}

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.

All arguments passed to the ConfigAccumulator constructor are used
as they are. The only exception is the systematics flag:
If not explicitly set the decision to run systematics or not
will be taken depending on the CommonServicesConfig setup.

Definition at line 187 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 219 of file ConfigAccumulator.py.

219 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):
220
221 # Historically we have used the identifier
222 # `autoconfigFromFlags`, but in the rest of the code base
223 # `flags` is used. So for now we allow either, and can hopefully
224 # at some point remove the former (21 Aug 25).
225 if autoconfigFromFlags is not None:
226 if flags is not None:
227 raise ValueError("Cannot pass both flags and autoconfigFromFlags arguments")
228 flags = autoconfigFromFlags
229 warnings.warn ('Using autoconfigFromFlags parameter is deprecated, use flags instead', category=deprecationWarningCategory, stacklevel=2)
230 self._flags = flags
231
232 # Historically the user was expected to pass in meta-data
233 # manually, which was a complete underestimate of the amount of
234 # meta-data needed. The current recommendation is to pass in a
235 # configuration flags object instead. The code below will raise
236 # an error if both are done, and if no configuration flags are
237 # passed in, it will try to create a flags object from the
238 # passed in parameters.
239 if self._flags is not None:
240 if dataType is not None:
241 raise ValueError("Cannot pass both dataType and flags/autoconfigFromFlags arguments")
242 if isPhyslite is not None:
243 raise ValueError("Cannot pass both isPhyslite and flags/autoconfigFromFlags arguments")
244 if geometry is not None:
245 raise ValueError("Cannot pass both geometry and flags/autoconfigFromFlags arguments")
246 if dsid != 0:
247 raise ValueError("Cannot pass both dsid and flags/autoconfigFromFlags arguments")
248 if campaign is not None:
249 raise ValueError("Cannot pass both campaign and flags/autoconfigFromFlags arguments")
250 if runNumber is not None:
251 raise ValueError("Cannot pass both runNumber and flags/autoconfigFromFlags arguments")
252 if dataYear != 0:
253 raise ValueError("Cannot pass both dataYear and flags/autoconfigFromFlags arguments")
254
255 if self._flags.Input.isMC:
256 if self._flags.Sim.ISF.Simulator.usesFastCaloSim():
257 dataType = DataType.FastSim
258 else:
259 dataType = DataType.FullSim
260 else:
261 dataType = DataType.Data
262 isPhyslite = 'StreamDAOD_PHYSLITE' in self._flags.Input.ProcessingTags
263 from TrigDecisionTool.TrigDecisionToolHelpers import (
264 getRun3NavigationContainerFromInput_forAnalysisBase)
265 hltSummary = getRun3NavigationContainerFromInput_forAnalysisBase(self._flags)
266 else:
267 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)
268 from AthenaConfiguration.AllConfigFlags import initConfigFlags
269 flags = initConfigFlags()
270 if dataType is None:
271 raise ValueError ("need to specify dataType if flags are not set")
272 # legacy mappings of string arguments
273 if isinstance(dataType, str):
274 if dataType == 'mc':
275 dataType = DataType.FullSim
276 elif dataType == 'afii':
277 dataType = DataType.FastSim
278 else:
279 dataType = DataType(dataType)
280 if isPhyslite is None:
281 isPhyslite = False
282 if geometry is not None:
283 # allow possible string argument for `geometry` and convert it to enum
284 geometry = LHCPeriod(geometry)
285 if geometry is LHCPeriod.Run1:
286 raise ValueError (f"invalid Run geometry: {geometry.value}")
287 flags.GeoModel.Run = geometry
288 if dsid != 0:
289 flags.Input.MCChannelNumber = dsid
290 if campaign is not None:
291 flags.Input.MCCampaign = campaign
292 if dataYear != 0:
293 flags.Input.DataYear = dataYear
294 if runNumber is None:
295 # not sure if we should just use a default run number
296 # here, or just report nothing
297 runNumber = 284500
298 flags.Input.RunNumbers = [runNumber]
299 hltSummary = 'HLTNav_Summary_DAODSlimmed'
300 flags.lock()
301 self._flags = flags
302
303 # These don't seem to have a direct equivalent in the
304 # configuration flags. For now I'm keeping them (21 Aug 25), but
305 # they might be replaced with something that is more directly in
306 # the configuration flags in the future.
307 self._dataType = dataType
308 self._isPhyslite = isPhyslite
309 self._hltSummary = hltSummary
310
311 # From here on, we are no longer dealing with flags or
312 # meta-data, but actual internal variables we need to manage the
313 # creation of components.
314 self._algSeq = algSeq
315 self._noSystematics = noSystematics
316 self._noSysSuffix = noSysSuffix
317 self._algPostfix = ''
318 self._defaultHistogramStream = 'ANALYSIS'
319 self._containerConfig = {}
320 self._outputContainers = {}
321 self._algorithms = {}
322 self._currentAlg = None
323 self._selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]*')
324 self.setSourceName ('EventInfo', 'EventInfo')
325 self.setContainerMeta ('EventInfo', "nonContainer", True)
326 self._eventcutflow = {}
327 self.CA = None
328
329 if DualUseConfig.isAthena:
330 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
331 self.CA = ComponentAccumulator()
332 if algSeq is not None:
333 self.CA.addSequence(algSeq)
334 else:
335 if algSeq is None :
336 raise ValueError ("need to pass algSeq if not using ComponentAccumulator")
337
338 ConfigAccumulator._instance_counter += 1
339 self._algPrefix = f'seq{self._instance_counter}_'
340

Member Function Documentation

◆ _createServiceOrTool()

python.ConfigAccumulator.ConfigAccumulator._createServiceOrTool ( self,
type,
name,
isSingleton,
kind,
create,
add )
protected
shared implementation of createService and createPublicTool

Definition at line 463 of file ConfigAccumulator.py.

463 def _createServiceOrTool (self, type, name, isSingleton, kind, create, add) :
464 """shared implementation of createService and createPublicTool"""
465 if not isSingleton:
466 name = self._algPrefix + name + self._algPostfix
467 if isSingleton and name in ConfigAccumulator._singleton_registry:
468 component = ConfigAccumulator._singleton_registry[name]
469 self._algorithms[name] = component
470 self._currentAlg = component
471 return component
472 if name in self._algorithms :
473 raise ValueError (f'duplicate {kind}: {name}')
474 component = create (type, name)
475 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
476 # as it modifies Gaudi behaviour
477 if DualUseConfig.isAthena:
478 add (component)
479 else:
480 # We're not, so let's remember this as a "normal" algorithm:
481 self._algSeq += component
482 self._algorithms[name] = component
483 self._currentAlg = component
484 if isSingleton:
485 ConfigAccumulator._singleton_registry[name] = component
486 return component
487
488

◆ 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 807 of file ConfigAccumulator.py.

807 def addEventCutFlow (self, selection, decorations) :
808
809 """register a new event cutflow, adding it to the dictionary with key 'selection'
810 and value 'decorations', a list of decorated selections
811 """
812 if selection in self._eventcutflow.keys():
813 raise ValueError (f'the event cutflow dictionary already contains an entry {selection}')
814 else:
815 self._eventcutflow[selection] = decorations
816
817

◆ addOutputContainer()

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

Definition at line 839 of file ConfigAccumulator.py.

839 def addOutputContainer (self, containerName, outputContainerName) :
840 """register a copy of a container used in outputs"""
841 if containerName not in self._containerConfig :
842 raise KeyError (f"container unknown: {containerName}")
843 if outputContainerName in self._outputContainers :
844 raise KeyError (f"duplicate output container name: {outputContainerName}")
845 self._outputContainers[outputContainerName] = containerName
846
847

◆ addOutputVar()

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

Definition at line 859 of file ConfigAccumulator.py.

860 *, noSys=False, enabled=True, auxType=None) :
861 """add an output variable for the given container to the output
862 """
863 if containerName in self._outputContainers:
864 self.addOutputVar(self.getOutputContainerOrigin(containerName), variableName, outputName, noSys=noSys, enabled=enabled, auxType=auxType)
865 return
866
867 if containerName not in self._containerConfig :
868 raise KeyError (f"container unknown: {containerName}")
869 baseConfig = self._containerConfig[containerName].outputs
870 if outputName in baseConfig :
871 raise KeyError (f"duplicate output variable name: {outputName}")
872 config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled, auxType=auxType)
873 baseConfig[outputName] = config
874
875

◆ addPrivateTool()

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

Definition at line 503 of file ConfigAccumulator.py.

503 def addPrivateTool (self, propertyName, toolType) :
504 """add a private tool to the current algorithm"""
505 DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
506

◆ 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 826 of file ConfigAccumulator.py.

827 **kwargs) :
828 """add another selection decoration to the selection of the given
829 name for the given container"""
830 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
831 raise ValueError (f'invalid selection name: {selectionName}')
832 if containerName not in self._containerConfig :
833 self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
834 config = self._containerConfig[containerName]
835 selection = SelectionConfig (selectionName, decoration, **kwargs)
836 config.selections.append (selection)
837
838

◆ 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 405 of file ConfigAccumulator.py.

405 def algPostfix (self) :
406 """the current postfix to be appended to algorithm names
407
408 Blocks should not call this directly, but rather implement the
409 instanceName method, which will be used to generate the postfix
410 automatically."""
411 return self._algPostfix
412

◆ 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 351 of file ConfigAccumulator.py.

351 def autoconfigFlags (self) :
352 """Athena configuration flags
353
354 This is a backward compatibility version of the flags property,
355 which is preferred."""
356 return self._flags
357

◆ beginJob()

python.ConfigAccumulator.ConfigAccumulator.beginJob ( cls)
Helper class method to fully reset the counters, call once before building a new job sequence.

Definition at line 214 of file ConfigAccumulator.py.

214 def beginJob(cls):
215 """Helper class method to fully reset the counters, call once before building a new job sequence."""
216 cls._instance_counter = 0
217 cls._singleton_registry.clear()
218
void clear()
Empty the pool.

◆ campaign()

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

Definition at line 374 of file ConfigAccumulator.py.

374 def campaign(self) :
375 """the MC campaign we run on"""
376 return self._flags.Input.MCCampaign
377

◆ copyName()

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

Definition at line 566 of file ConfigAccumulator.py.

566 def copyName (self, containerName) :
567 """register that a copy of the container will be made and return
568 its name"""
569 if containerName not in self._containerConfig :
570 raise KeyError (f"unknown container: {containerName}")
571 return self._containerConfig[containerName].appendStep()
572
573

◆ createAlgorithm()

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

Definition at line 440 of file ConfigAccumulator.py.

440 def createAlgorithm (self, type, name, reentrant=False) :
441 """create a new algorithm and register it as the current algorithm"""
442 name = self._algPrefix + name + self._algPostfix
443 if name in self._algorithms :
444 raise ValueError (f'duplicate algorithms: {name} with algPostfix={self._algPostfix}')
445 if reentrant:
446 alg = DualUseConfig.createReentrantAlgorithm (type, name)
447 else:
448 alg = DualUseConfig.createAlgorithm (type, name)
449
450 if DualUseConfig.isAthena:
451 if self._algSeq is not None:
452 self.CA.addEventAlgo(alg,self._algSeq.name)
453 else :
454 self.CA.addEventAlgo(alg)
455 else:
456 self._algSeq += alg
457
458 self._algorithms[name] = alg
459 self._currentAlg = alg
460 return alg
461
462

◆ createPublicTool()

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

Definition at line 496 of file ConfigAccumulator.py.

496 def createPublicTool (self, type, name, isSingleton=True) :
497 '''create a new public tool and register it as the "current algorithm"'''
498 return self._createServiceOrTool (
499 type, name, isSingleton, 'public tool', DualUseConfig.createPublicTool,
500 lambda tool: self.CA.addPublicTool(tool))
501
502

◆ createService()

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

Definition at line 489 of file ConfigAccumulator.py.

489 def createService (self, type, name, isSingleton=True) :
490 '''create a new service and register it as the "current algorithm"'''
491 return self._createServiceOrTool (
492 type, name, isSingleton, 'service', DualUseConfig.createService,
493 lambda service: self.CA.addService(service))
494
495

◆ dataType()

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

Definition at line 358 of file ConfigAccumulator.py.

358 def dataType (self) :
359 """the data type we run on (data, fullsim, fastsim)"""
360 return self._dataType
361

◆ dataYear()

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

Definition at line 382 of file ConfigAccumulator.py.

382 def dataYear(self) :
383 """for data, the corresponding year; for MC, zero"""
384 return self._flags.Input.DataYear
385

◆ defaultHistogramStream()

python.ConfigAccumulator.ConfigAccumulator.defaultHistogramStream ( self)
the default histogram stream to be used for output histograms

Definition at line 394 of file ConfigAccumulator.py.

394 def defaultHistogramStream(self):
395 """the default histogram stream to be used for output histograms"""
396 return self._defaultHistogramStream
397

◆ dsid()

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

Definition at line 370 of file ConfigAccumulator.py.

370 def dsid(self) :
371 """the mcChannelNumber or DSID of the sample we run on"""
372 return self._flags.Input.MCChannelNumber
373

◆ flags()

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

Definition at line 346 of file ConfigAccumulator.py.

346 def flags (self) :
347 """Athena configuration flags"""
348 return self._flags
349

◆ generatorInfo()

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

Definition at line 386 of file ConfigAccumulator.py.

386 def generatorInfo(self) :
387 """the dictionary of MC generators and their versions for the sample we run on"""
388 return self._flags.Input.GeneratorsInfo
389

◆ geometry()

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

Definition at line 366 of file ConfigAccumulator.py.

366 def geometry (self) :
367 """the LHC Run period we run on"""
368 return self._flags.GeoModel.Run
369

◆ 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 429 of file ConfigAccumulator.py.

429 def getAlgorithm (self, name : str):
430 """get the algorithm with the given name
431
432 Despite the name this will also return services and tools. It is
433 mostly meant for internal use, particularly for the property
434 overrides."""
435 name = self._algPrefix + name + self._algPostfix
436 if name not in self._algorithms:
437 return None
438 return self._algorithms[name]
439

◆ 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 631 of file ConfigAccumulator.py.

631 def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
632 """get the meta information for the given container
633
634 This is used to pass down meta-information from the
635 configuration to the algorithms.
636 """
637 if containerName not in self._containerConfig :
638 raise KeyError (f"container unknown: {containerName}")
639 if metaField in self._containerConfig[containerName].meta :
640 return self._containerConfig[containerName].meta[metaField]
641 if failOnMiss :
642 raise KeyError (f'unknown meta-field {metaField} on container {containerName}')
643 return defaultValue
644

◆ getEventCutFlow()

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

Definition at line 818 of file ConfigAccumulator.py.

818 def getEventCutFlow (self, selection) :
819
820 """get the list of decorated selections for an event cutflow, corresponding to
821 key 'selection'
822 """
823 return self._eventcutflow[selection]
824
825

◆ 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 709 of file ConfigAccumulator.py.

710 *, skipBase = False, excludeFrom = None) :
711
712 """get the selection string for the given selection on the given
713 container
714
715 This can handle both individual selections or selection
716 expressions (e.g. `loose||tight`) with the later being
717 properly expanded. Either way the base selection (i.e. the
718 selection without a name) will always be applied on top.
719
720 containerName --- the container the selection is defined on
721 selectionName --- the name of the selection, or a selection
722 expression based on multiple named selections
723 skipBase --- will avoid the base selection, and should normally
724 not be used by the end-user.
725 excludeFrom --- a set of string names of selection sources to exclude
726 e.g. to exclude OR selections from MET
727 """
728 if "." in containerName:
729 raise ValueError (f'invalid containerName argument: {containerName} , it contains a "." '
730 'which is used to indicate container+selection. You should only pass the container.')
731 if containerName not in self._containerConfig :
732 return ""
733
734 if excludeFrom is None :
735 excludeFrom = set()
736 elif not isinstance(excludeFrom, set) :
737 raise ValueError (f'invalid excludeFrom argument (need set of strings): {excludeFrom}')
738
739 # Check if this is actually a selection expression,
740 # e.g. `A||B` and if so translate it into a complex expression
741 # for the user. I'm not trying to do any complex syntax
742 # recognition, but instead just produce an expression that the
743 # C++ parser ought to be able to read.
744 if selectionName != '' and \
745 not self._selectionNameExpr.fullmatch (selectionName) :
746 result = ''
747 while selectionName != '' :
748 match = self._selectionNameExpr.match (selectionName)
749 if not match :
750 result += selectionName[0]
751 selectionName = selectionName[1:]
752 else :
753 subname = match.group(0)
754 subresult = self.getFullSelection (containerName, subname, skipBase = True, excludeFrom=excludeFrom)
755 if subresult != '' :
756 result += '(' + subresult + ')'
757 else :
758 result += 'true'
759 selectionName = selectionName[len(subname):]
760 subresult = self.getFullSelection (containerName, '', excludeFrom=excludeFrom)
761 if subresult != '' :
762 result = subresult + '&&(' + result + ')'
763 return '(' + result + ')' if result !='' else ''
764
765 config = self._containerConfig[containerName]
766 decorations = []
767 hasSelectionName = False
768 for selection in config.selections :
769 if ((selection.name == '' and not skipBase) or selection.name == selectionName) and (selection.comesFrom not in excludeFrom) :
770 decorations += [selection.decoration]
771 if selection.name == selectionName :
772 hasSelectionName = True
773 if not hasSelectionName and selectionName != '' :
774 raise KeyError (f'invalid selection name: {containerName}.{selectionName}')
775 return '&&'.join (decorations)
776
777
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 848 of file ConfigAccumulator.py.

848 def getOutputContainerOrigin (self, outputContainerName) :
849 """Get the name of the actual container, for which an output is registered"""
850 try:
851 return self._outputContainers[outputContainerName]
852 except KeyError:
853 try:
854 return self._containerConfig[outputContainerName].name
855 except KeyError:
856 raise KeyError (f"output container unknown: {outputContainerName}") from None
857
858

◆ getOutputVars()

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

Definition at line 876 of file ConfigAccumulator.py.

876 def getOutputVars (self, containerName) :
877 """get the output variables for the given container"""
878 if containerName in self._outputContainers :
879 containerName = self._outputContainers[containerName]
880 if containerName not in self._containerConfig :
881 raise KeyError (f"unknown container for output: {containerName}")
882 return self._containerConfig[containerName].outputs
883
884

◆ 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 688 of file ConfigAccumulator.py.

688 def getPreselection (self, containerName, selectionName, *, asList = False) :
689
690 """get the preselection string for the given selection on the given
691 container
692 """
693 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
694 raise ValueError (f'invalid selection name: {selectionName}')
695 if containerName not in self._containerConfig :
696 return ""
697 config = self._containerConfig[containerName]
698 decorations = []
699 for selection in config.selections :
700 if (selection.name == '' or selection.name == selectionName) and \
701 selection.preselection :
702 decorations += [selection.decoration]
703 if asList :
704 return decorations
705 else :
706 return '&&'.join (decorations)
707
708

◆ 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 778 of file ConfigAccumulator.py.

778 def getSelectionCutFlow (self, containerName, selectionName) :
779
780 """get the individual selections as a list for producing the cutflow for
781 the given selection on the given container
782
783 This can only handle individual selections, not selection
784 expressions (e.g. `loose||tight`).
785
786 """
787 if containerName not in self._containerConfig :
788 return []
789
790 # Check if this is actually a selection expression,
791 # e.g. `A||B` and if so translate it into a complex expression
792 # for the user. I'm not trying to do any complex syntax
793 # recognition, but instead just produce an expression that the
794 # C++ parser ought to be able to read.
795 if selectionName != '' and \
796 not self._selectionNameExpr.fullmatch (selectionName) :
797 raise ValueError (f'not allowed to do cutflow on selection expression: {selectionName}')
798
799 config = self._containerConfig[containerName]
800 decorations = []
801 for selection in config.selections :
802 if (selection.name == '' or selection.name == selectionName) :
803 decorations += [selection.decoration]
804 return decorations
805
806

◆ getSelectionNames()

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

Definition at line 885 of file ConfigAccumulator.py.

885 def getSelectionNames (self, containerName, excludeFrom = None) :
886 """Retrieve set of unique selections defined for a given container"""
887 if containerName not in self._containerConfig :
888 return set()
889 if excludeFrom is None:
890 excludeFrom = set()
891 elif not isinstance(excludeFrom, set) :
892 raise ValueError (f'invalid excludeFrom argument (need set of strings): {excludeFrom}')
893
894 config = self._containerConfig[containerName]
895 # because cuts are registered individually, selection names can repeat themselves
896 # but we are interested in unique names only
897 selectionNames = set()
898 for selection in config.selections:
899 if selection.comesFrom in excludeFrom:
900 continue
901 # skip flags which should be disabled in output
902 if selection.writeToOutput:
903 selectionNames.add(selection.name)
904 return selectionNames

◆ hltSummary()

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

Definition at line 390 of file ConfigAccumulator.py.

390 def hltSummary(self) :
391 """the HLTSummary configuration to be used for the trigger decision tool"""
392 return self._hltSummary
393

◆ 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 657 of file ConfigAccumulator.py.

657 def isMetContainer (self, containerName) :
658 """whether the given container is registered as a MET container
659
660 This is mostly/exclusively used for determining whether to
661 write out the whole container or just a single MET term.
662 """
663 if containerName not in self._containerConfig :
664 raise KeyError (f"container unknown: {containerName}")
665 return self._containerConfig[containerName].isMet
666
667

◆ isPhyslite()

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

Definition at line 362 of file ConfigAccumulator.py.

362 def isPhyslite (self) :
363 """whether we run on PHYSLITE"""
364 return self._isPhyslite
365

◆ noSystematics()

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

Definition at line 341 of file ConfigAccumulator.py.

341 def noSystematics (self) :
342 """noSystematics flag used by CommonServices block"""
343 return self._noSystematics
344

◆ 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 617 of file ConfigAccumulator.py.

617 def originalName (self, containerName) :
618 """get the "original" name of the given container
619
620 This is mostly/exclusively used for jet containers, so that
621 subsequent configurations know which jet container they
622 operate on.
623 """
624 if containerName not in self._containerConfig :
625 raise KeyError (f"container unknown: {containerName}")
626 result = self._containerConfig[containerName].originalName
627 if result is None :
628 raise ValueError (f"no original name for: {containerName}")
629 return result
630

◆ readName()

python.ConfigAccumulator.ConfigAccumulator.readName ( self,
containerName,
* ,
nominal = False )
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 551 of file ConfigAccumulator.py.

551 def readName (self, containerName, *, nominal=False) :
552 """get the name of the "current copy" of the given container
553
554 As extra copies get created during processing this will track
555 the correct name of the current copy. Optionally one can pass
556 in the name of the container before the first copy.
557 """
558 if containerName in self._outputContainers:
559 return f"{containerName}_%SYS%"
560
561 if containerName not in self._containerConfig :
562 raise KeyError (f"no source container for: {containerName}")
563 return self._containerConfig[containerName].currentName(nominal=nominal)
564
565

◆ 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 668 of file ConfigAccumulator.py.

668 def readNameAndSelection (self, containerName, *, excludeFrom = None) :
669 """get the name of the "current copy" of the given container, and the
670 selection string
671
672 This is mostly meant for MET and OR for whom the actual object
673 selection is relevant, and which as such allow to pass in the
674 working point as "ObjectName.WorkingPoint".
675 """
676 split = containerName.split (".")
677 if len(split) == 1 :
678 objectName = split[0]
679 selectionName = ''
680 elif len(split) == 2 :
681 objectName = split[0]
682 selectionName = split[1]
683 else :
684 raise ValueError (f'invalid object selection name: {containerName}')
685 return self.readName (objectName), self.getFullSelection (objectName, selectionName, excludeFrom=excludeFrom)
686
687

◆ renameFinalContainers()

python.ConfigAccumulator.ConfigAccumulator.renameFinalContainers ( self)
post-process the configured algorithms, tools and services to
strip the auto-generated `_STEP<n>` suffix from each container's
*final* name in every property value.

This is mostly needed in case the user has further downstream
algorithms that rely on the exact name of containers in the
event store. For anything configured through the
`ConfigAccumulator` this doesn't matter, as the names are
configured consistently.

Definition at line 588 of file ConfigAccumulator.py.

588 def renameFinalContainers (self) :
589 """post-process the configured algorithms, tools and services to
590 strip the auto-generated `_STEP<n>` suffix from each container's
591 *final* name in every property value.
592
593 This is mostly needed in case the user has further downstream
594 algorithms that rely on the exact name of containers in the
595 event store. For anything configured through the
596 `ConfigAccumulator` this doesn't matter, as the names are
597 configured consistently."""
598
599 substitutions = []
600 for containerConfig in self._containerConfig.values() :
601 if not containerConfig.names :
602 continue
603 base = containerConfig.name
604 lastName = containerConfig.names[-1]
605 match = re.match (re.escape (base) + r'_STEP\d+', lastName)
606 if match :
607 substitutions.append ((match.group(0), base))
608 # keep ContainerConfig in sync, in case anything reads
609 # currentName() after this pass
610 containerConfig.names[-1] = substituteValue (lastName, [(match.group(0), base)])
611 if not substitutions :
612 return
613 for component in self._algorithms.values() :
614 substituteComponentProperties (component, substitutions)
615
616

◆ runNumber()

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

Definition at line 378 of file ConfigAccumulator.py.

378 def runNumber(self) :
379 """the MC runNumber"""
380 return int(self._flags.Input.RunNumbers[0])
381

◆ 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 413 of file ConfigAccumulator.py.

413 def setAlgPostfix (self, postfix : str) :
414 """set the current postfix to be appended to algorithm names
415
416 Blocks should not call this directly, but rather implement the
417 instanceName method, which will be used to generate the postfix
418 automatically."""
419 # make sure the postfix matches the expected format ([_a-zA-Z0-9]*)
420 if _algPostfixExpr.match (postfix) is None :
421 raise ValueError (f'invalid algorithm postfix: {postfix}')
422 if postfix == '' :
423 self._algPostfix = ''
424 elif postfix[0] != '_' :
425 self._algPostfix = '_' + postfix
426 else :
427 self._algPostfix = postfix
428

◆ 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 645 of file ConfigAccumulator.py.

645 def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
646 """set the meta information for the given container
647
648 This is used to pass down meta-information from the
649 configuration to the algorithms.
650 """
651 if containerName not in self._containerConfig :
652 raise KeyError (f"container unknown: {containerName}")
653 if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
654 raise KeyError (f'duplicate meta-field {metaField} on container {containerName}')
655 self._containerConfig[containerName].meta[metaField] = value
656

◆ setDefaultHistogramStream()

python.ConfigAccumulator.ConfigAccumulator.setDefaultHistogramStream ( self,
str streamName )
set the default histogram stream to be used for output histograms

As an advanced option this is not directly exposed by the constructor,
but can be set by the user if needed before configuring the job.

Definition at line 398 of file ConfigAccumulator.py.

398 def setDefaultHistogramStream(self, streamName: str):
399 """set the default histogram stream to be used for output histograms
400
401 As an advanced option this is not directly exposed by the constructor,
402 but can be set by the user if needed before configuring the job."""
403 self._defaultHistogramStream = streamName
404

◆ setExtraInputs()

python.ConfigAccumulator.ConfigAccumulator.setExtraInputs ( self,
inputs )
set extra input dependencies for the current algorithm

Definition at line 507 of file ConfigAccumulator.py.

507 def setExtraInputs (self, inputs) :
508 """set extra input dependencies for the current algorithm"""
509 if DualUseConfig.isAthena:
510 self._currentAlg.ExtraInputs = inputs
511

◆ setExtraOutputs()

python.ConfigAccumulator.ConfigAccumulator.setExtraOutputs ( self,
outputs )
set extra output dependencies for the current algorithm

Definition at line 512 of file ConfigAccumulator.py.

512 def setExtraOutputs (self, outputs) :
513 """set extra output dependencies for the current algorithm"""
514 if DualUseConfig.isAthena:
515 self._currentAlg.ExtraOutputs = outputs
516

◆ 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 517 of file ConfigAccumulator.py.

518 *, originalName = None, isMet = False) :
519 """set the (default) name of the source/original container
520
521 This is essentially meant to allow using e.g. the muon
522 configuration and the user not having to manually specify that
523 they want to use the Muons/AnalysisMuons container from the
524 input file.
525
526 In addition it allows to set the original name of the
527 container (which may be different from the source name), which
528 is mostly/exclusively used for jet containers, so that
529 subsequent configurations know which jet container they
530 operate on.
531 """
532 if containerName not in self._containerConfig :
533 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName, noSysSuffix = self._noSysSuffix, originalName = originalName, isMet = isMet)
534
535

◆ 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 574 of file ConfigAccumulator.py.

574 def wantCopy (self, containerName) :
575 """ask whether we want/need a copy of the container
576
577 This usually only happens if no copy of the container has been
578 made yet and the copy is needed to allow modifications, etc.
579 """
580 if containerName not in self._containerConfig :
581 raise KeyError (f"no source container for: {containerName}")
582 config = self._containerConfig[containerName]
583 if len (config.names) == 0 :
584 raise ValueError (f"checking wantCopy on container with no name in event store: {containerName}")
585 return config.names[-1] == config.sourceName
586
587

◆ writeName()

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

Definition at line 536 of file ConfigAccumulator.py.

536 def writeName (self, containerName, *, isMet=None) :
537 """register that the given container will be made and return
538 its name"""
539 if containerName not in self._containerConfig :
540 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName = None, noSysSuffix = self._noSysSuffix)
541 config = self._containerConfig[containerName]
542 if config.sourceName is not None :
543 raise ValueError (f"trying to write container configured for input: {containerName}")
544 if config.names :
545 raise ValueError (f"trying to write container twice: {containerName}")
546 if isMet is not None :
547 config.isMet = isMet
548 return config.appendStep()
549
550

Member Data Documentation

◆ _algorithms

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

Definition at line 321 of file ConfigAccumulator.py.

◆ _algPostfix

str python.ConfigAccumulator.ConfigAccumulator._algPostfix = ''
protected

Definition at line 317 of file ConfigAccumulator.py.

◆ _algPrefix

str python.ConfigAccumulator.ConfigAccumulator._algPrefix = f'seq{self._instance_counter}_'
protected

Definition at line 339 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq = algSeq
protected

Definition at line 314 of file ConfigAccumulator.py.

◆ _containerConfig

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

Definition at line 319 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg = None
protected

Definition at line 322 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType = dataType
protected

Definition at line 307 of file ConfigAccumulator.py.

◆ _defaultHistogramStream

str python.ConfigAccumulator.ConfigAccumulator._defaultHistogramStream = 'ANALYSIS'
protected

Definition at line 318 of file ConfigAccumulator.py.

◆ _eventcutflow

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

Definition at line 326 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags = flags
protected

Definition at line 230 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary = hltSummary
protected

Definition at line 309 of file ConfigAccumulator.py.

◆ _instance_counter

int python.ConfigAccumulator.ConfigAccumulator._instance_counter = 0
staticprotected

Definition at line 209 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite = isPhyslite
protected

Definition at line 308 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix = noSysSuffix
protected

Definition at line 316 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics = noSystematics
protected

Definition at line 315 of file ConfigAccumulator.py.

◆ _outputContainers

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

Definition at line 320 of file ConfigAccumulator.py.

◆ _selectionNameExpr

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

Definition at line 323 of file ConfigAccumulator.py.

◆ _singleton_registry

dict python.ConfigAccumulator.ConfigAccumulator._singleton_registry = {}
staticprotected

Definition at line 211 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA = None

Definition at line 327 of file ConfigAccumulator.py.


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