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)
 requestOutputStream (self, streamName=None)
 outputStreams (self)
 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'
list _outputStreams = []
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._outputStreams = []
320 self._containerConfig = {}
321 self._outputContainers = {}
322 self._algorithms = {}
323 self._currentAlg = None
324 self._selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]*')
325 self.setSourceName ('EventInfo', 'EventInfo')
326 self.setContainerMeta ('EventInfo', "nonContainer", True)
327 self._eventcutflow = {}
328 self.CA = None
329
330 if DualUseConfig.isAthena:
331 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
332 self.CA = ComponentAccumulator()
333 if algSeq is not None:
334 self.CA.addSequence(algSeq)
335 else:
336 if algSeq is None :
337 raise ValueError ("need to pass algSeq if not using ComponentAccumulator")
338
339 ConfigAccumulator._instance_counter += 1
340 self._algPrefix = f'seq{self._instance_counter}_'
341

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

479 def _createServiceOrTool (self, type, name, isSingleton, kind, create, add) :
480 """shared implementation of createService and createPublicTool"""
481 if not isSingleton:
482 name = self._algPrefix + name + self._algPostfix
483 if isSingleton and name in ConfigAccumulator._singleton_registry:
484 component = ConfigAccumulator._singleton_registry[name]
485 self._algorithms[name] = component
486 self._currentAlg = component
487 return component
488 if name in self._algorithms :
489 raise ValueError (f'duplicate {kind}: {name}')
490 component = create (type, name)
491 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
492 # as it modifies Gaudi behaviour
493 if DualUseConfig.isAthena:
494 add (component)
495 else:
496 # We're not, so let's remember this as a "normal" algorithm:
497 self._algSeq += component
498 self._algorithms[name] = component
499 self._currentAlg = component
500 if isSingleton:
501 ConfigAccumulator._singleton_registry[name] = component
502 return component
503
504

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

823 def addEventCutFlow (self, selection, decorations) :
824
825 """register a new event cutflow, adding it to the dictionary with key 'selection'
826 and value 'decorations', a list of decorated selections
827 """
828 if selection in self._eventcutflow.keys():
829 raise ValueError (f'the event cutflow dictionary already contains an entry {selection}')
830 else:
831 self._eventcutflow[selection] = decorations
832
833

◆ addOutputContainer()

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

Definition at line 855 of file ConfigAccumulator.py.

855 def addOutputContainer (self, containerName, outputContainerName) :
856 """register a copy of a container used in outputs"""
857 if containerName not in self._containerConfig :
858 raise KeyError (f"container unknown: {containerName}")
859 if outputContainerName in self._outputContainers :
860 raise KeyError (f"duplicate output container name: {outputContainerName}")
861 self._outputContainers[outputContainerName] = containerName
862
863

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

876 *, noSys=False, enabled=True, auxType=None) :
877 """add an output variable for the given container to the output
878 """
879 if containerName in self._outputContainers:
880 self.addOutputVar(self.getOutputContainerOrigin(containerName), variableName, outputName, noSys=noSys, enabled=enabled, auxType=auxType)
881 return
882
883 if containerName not in self._containerConfig :
884 raise KeyError (f"container unknown: {containerName}")
885 baseConfig = self._containerConfig[containerName].outputs
886 if outputName in baseConfig :
887 raise KeyError (f"duplicate output variable name: {outputName}")
888 config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled, auxType=auxType)
889 baseConfig[outputName] = config
890
891

◆ addPrivateTool()

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

Definition at line 519 of file ConfigAccumulator.py.

519 def addPrivateTool (self, propertyName, toolType) :
520 """add a private tool to the current algorithm"""
521 DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
522

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

843 **kwargs) :
844 """add another selection decoration to the selection of the given
845 name for the given container"""
846 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
847 raise ValueError (f'invalid selection name: {selectionName}')
848 if containerName not in self._containerConfig :
849 self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
850 config = self._containerConfig[containerName]
851 selection = SelectionConfig (selectionName, decoration, **kwargs)
852 config.selections.append (selection)
853
854

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

421 def algPostfix (self) :
422 """the current postfix to be appended to algorithm names
423
424 Blocks should not call this directly, but rather implement the
425 instanceName method, which will be used to generate the postfix
426 automatically."""
427 return self._algPostfix
428

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

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

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

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

◆ copyName()

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

Definition at line 582 of file ConfigAccumulator.py.

582 def copyName (self, containerName) :
583 """register that a copy of the container will be made and return
584 its name"""
585 if containerName not in self._containerConfig :
586 raise KeyError (f"unknown container: {containerName}")
587 return self._containerConfig[containerName].appendStep()
588
589

◆ createAlgorithm()

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

Definition at line 456 of file ConfigAccumulator.py.

456 def createAlgorithm (self, type, name, reentrant=False) :
457 """create a new algorithm and register it as the current algorithm"""
458 name = self._algPrefix + name + self._algPostfix
459 if name in self._algorithms :
460 raise ValueError (f'duplicate algorithms: {name} with algPostfix={self._algPostfix}')
461 if reentrant:
462 alg = DualUseConfig.createReentrantAlgorithm (type, name)
463 else:
464 alg = DualUseConfig.createAlgorithm (type, name)
465
466 if DualUseConfig.isAthena:
467 if self._algSeq is not None:
468 self.CA.addEventAlgo(alg,self._algSeq.name)
469 else :
470 self.CA.addEventAlgo(alg)
471 else:
472 self._algSeq += alg
473
474 self._algorithms[name] = alg
475 self._currentAlg = alg
476 return alg
477
478

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

512 def createPublicTool (self, type, name, isSingleton=True) :
513 '''create a new public tool and register it as the "current algorithm"'''
514 return self._createServiceOrTool (
515 type, name, isSingleton, 'public tool', DualUseConfig.createPublicTool,
516 lambda tool: self.CA.addPublicTool(tool))
517
518

◆ createService()

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

Definition at line 505 of file ConfigAccumulator.py.

505 def createService (self, type, name, isSingleton=True) :
506 '''create a new service and register it as the "current algorithm"'''
507 return self._createServiceOrTool (
508 type, name, isSingleton, 'service', DualUseConfig.createService,
509 lambda service: self.CA.addService(service))
510
511

◆ dataType()

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

Definition at line 359 of file ConfigAccumulator.py.

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

◆ dataYear()

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

Definition at line 383 of file ConfigAccumulator.py.

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

◆ defaultHistogramStream()

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

Definition at line 395 of file ConfigAccumulator.py.

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

◆ dsid()

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

Definition at line 371 of file ConfigAccumulator.py.

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

◆ flags()

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

Definition at line 347 of file ConfigAccumulator.py.

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

◆ generatorInfo()

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

Definition at line 387 of file ConfigAccumulator.py.

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

◆ geometry()

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

Definition at line 367 of file ConfigAccumulator.py.

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

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

445 def getAlgorithm (self, name : str):
446 """get the algorithm with the given name
447
448 Despite the name this will also return services and tools. It is
449 mostly meant for internal use, particularly for the property
450 overrides."""
451 name = self._algPrefix + name + self._algPostfix
452 if name not in self._algorithms:
453 return None
454 return self._algorithms[name]
455

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

647 def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
648 """get the meta information for the given container
649
650 This is used to pass down meta-information from the
651 configuration to the algorithms.
652 """
653 if containerName not in self._containerConfig :
654 raise KeyError (f"container unknown: {containerName}")
655 if metaField in self._containerConfig[containerName].meta :
656 return self._containerConfig[containerName].meta[metaField]
657 if failOnMiss :
658 raise KeyError (f'unknown meta-field {metaField} on container {containerName}')
659 return defaultValue
660

◆ getEventCutFlow()

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

Definition at line 834 of file ConfigAccumulator.py.

834 def getEventCutFlow (self, selection) :
835
836 """get the list of decorated selections for an event cutflow, corresponding to
837 key 'selection'
838 """
839 return self._eventcutflow[selection]
840
841

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

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

864 def getOutputContainerOrigin (self, outputContainerName) :
865 """Get the name of the actual container, for which an output is registered"""
866 try:
867 return self._outputContainers[outputContainerName]
868 except KeyError:
869 try:
870 return self._containerConfig[outputContainerName].name
871 except KeyError:
872 raise KeyError (f"output container unknown: {outputContainerName}") from None
873
874

◆ getOutputVars()

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

Definition at line 892 of file ConfigAccumulator.py.

892 def getOutputVars (self, containerName) :
893 """get the output variables for the given container"""
894 if containerName in self._outputContainers :
895 containerName = self._outputContainers[containerName]
896 if containerName not in self._containerConfig :
897 raise KeyError (f"unknown container for output: {containerName}")
898 return self._containerConfig[containerName].outputs
899
900

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

704 def getPreselection (self, containerName, selectionName, *, asList = False) :
705
706 """get the preselection string for the given selection on the given
707 container
708 """
709 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
710 raise ValueError (f'invalid selection name: {selectionName}')
711 if containerName not in self._containerConfig :
712 return ""
713 config = self._containerConfig[containerName]
714 decorations = []
715 for selection in config.selections :
716 if (selection.name == '' or selection.name == selectionName) and \
717 selection.preselection :
718 decorations += [selection.decoration]
719 if asList :
720 return decorations
721 else :
722 return '&&'.join (decorations)
723
724

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

794 def getSelectionCutFlow (self, containerName, selectionName) :
795
796 """get the individual selections as a list for producing the cutflow for
797 the given selection on the given container
798
799 This can only handle individual selections, not selection
800 expressions (e.g. `loose||tight`).
801
802 """
803 if containerName not in self._containerConfig :
804 return []
805
806 # Check if this is actually a selection expression,
807 # e.g. `A||B` and if so translate it into a complex expression
808 # for the user. I'm not trying to do any complex syntax
809 # recognition, but instead just produce an expression that the
810 # C++ parser ought to be able to read.
811 if selectionName != '' and \
812 not self._selectionNameExpr.fullmatch (selectionName) :
813 raise ValueError (f'not allowed to do cutflow on selection expression: {selectionName}')
814
815 config = self._containerConfig[containerName]
816 decorations = []
817 for selection in config.selections :
818 if (selection.name == '' or selection.name == selectionName) :
819 decorations += [selection.decoration]
820 return decorations
821
822

◆ getSelectionNames()

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

Definition at line 901 of file ConfigAccumulator.py.

901 def getSelectionNames (self, containerName, excludeFrom = None) :
902 """Retrieve set of unique selections defined for a given container"""
903 if containerName not in self._containerConfig :
904 return set()
905 if excludeFrom is None:
906 excludeFrom = set()
907 elif not isinstance(excludeFrom, set) :
908 raise ValueError (f'invalid excludeFrom argument (need set of strings): {excludeFrom}')
909
910 config = self._containerConfig[containerName]
911 # because cuts are registered individually, selection names can repeat themselves
912 # but we are interested in unique names only
913 selectionNames = set()
914 for selection in config.selections:
915 if selection.comesFrom in excludeFrom:
916 continue
917 # skip flags which should be disabled in output
918 if selection.writeToOutput:
919 selectionNames.add(selection.name)
920 return selectionNames

◆ hltSummary()

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

Definition at line 391 of file ConfigAccumulator.py.

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

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

673 def isMetContainer (self, containerName) :
674 """whether the given container is registered as a MET container
675
676 This is mostly/exclusively used for determining whether to
677 write out the whole container or just a single MET term.
678 """
679 if containerName not in self._containerConfig :
680 raise KeyError (f"container unknown: {containerName}")
681 return self._containerConfig[containerName].isMet
682
683

◆ isPhyslite()

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

Definition at line 363 of file ConfigAccumulator.py.

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

◆ noSystematics()

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

Definition at line 342 of file ConfigAccumulator.py.

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

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

633 def originalName (self, containerName) :
634 """get the "original" name of the given container
635
636 This is mostly/exclusively used for jet containers, so that
637 subsequent configurations know which jet container they
638 operate on.
639 """
640 if containerName not in self._containerConfig :
641 raise KeyError (f"container unknown: {containerName}")
642 result = self._containerConfig[containerName].originalName
643 if result is None :
644 raise ValueError (f"no original name for: {containerName}")
645 return result
646

◆ outputStreams()

python.ConfigAccumulator.ConfigAccumulator.outputStreams ( self)
the output streams requested during the configuration, in request order

Definition at line 417 of file ConfigAccumulator.py.

417 def outputStreams(self):
418 """the output streams requested during the configuration, in request order"""
419 return list(self._outputStreams)
420

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

567 def readName (self, containerName, *, nominal=False) :
568 """get the name of the "current copy" of the given container
569
570 As extra copies get created during processing this will track
571 the correct name of the current copy. Optionally one can pass
572 in the name of the container before the first copy.
573 """
574 if containerName in self._outputContainers:
575 return f"{containerName}_%SYS%"
576
577 if containerName not in self._containerConfig :
578 raise KeyError (f"no source container for: {containerName}")
579 return self._containerConfig[containerName].currentName(nominal=nominal)
580
581

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

684 def readNameAndSelection (self, containerName, *, excludeFrom = None) :
685 """get the name of the "current copy" of the given container, and the
686 selection string
687
688 This is mostly meant for MET and OR for whom the actual object
689 selection is relevant, and which as such allow to pass in the
690 working point as "ObjectName.WorkingPoint".
691 """
692 split = containerName.split (".")
693 if len(split) == 1 :
694 objectName = split[0]
695 selectionName = ''
696 elif len(split) == 2 :
697 objectName = split[0]
698 selectionName = split[1]
699 else :
700 raise ValueError (f'invalid object selection name: {containerName}')
701 return self.readName (objectName), self.getFullSelection (objectName, selectionName, excludeFrom=excludeFrom)
702
703

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

604 def renameFinalContainers (self) :
605 """post-process the configured algorithms, tools and services to
606 strip the auto-generated `_STEP<n>` suffix from each container's
607 *final* name in every property value.
608
609 This is mostly needed in case the user has further downstream
610 algorithms that rely on the exact name of containers in the
611 event store. For anything configured through the
612 `ConfigAccumulator` this doesn't matter, as the names are
613 configured consistently."""
614
615 substitutions = []
616 for containerConfig in self._containerConfig.values() :
617 if not containerConfig.names :
618 continue
619 base = containerConfig.name
620 lastName = containerConfig.names[-1]
621 match = re.match (re.escape (base) + r'_STEP\d+', lastName)
622 if match :
623 substitutions.append ((match.group(0), base))
624 # keep ContainerConfig in sync, in case anything reads
625 # currentName() after this pass
626 containerConfig.names[-1] = substituteValue (lastName, [(match.group(0), base)])
627 if not substitutions :
628 return
629 for component in self._algorithms.values() :
630 substituteComponentProperties (component, substitutions)
631
632

◆ requestOutputStream()

python.ConfigAccumulator.ConfigAccumulator.requestOutputStream ( self,
streamName = None )
request an output stream for the algorithms of a block to write to

Falls back to the default histogram stream if no stream is given, and
records the stream so the job runner can declare an output file for it.
Returns the name of the stream to set as the algorithms' RootStreamName.

Definition at line 406 of file ConfigAccumulator.py.

406 def requestOutputStream(self, streamName=None):
407 """request an output stream for the algorithms of a block to write to
408
409 Falls back to the default histogram stream if no stream is given, and
410 records the stream so the job runner can declare an output file for it.
411 Returns the name of the stream to set as the algorithms' RootStreamName."""
412 streamName = streamName or self._defaultHistogramStream
413 if streamName not in self._outputStreams:
414 self._outputStreams.append(streamName)
415 return streamName
416

◆ runNumber()

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

Definition at line 379 of file ConfigAccumulator.py.

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

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

429 def setAlgPostfix (self, postfix : str) :
430 """set the current postfix to be appended to algorithm names
431
432 Blocks should not call this directly, but rather implement the
433 instanceName method, which will be used to generate the postfix
434 automatically."""
435 # make sure the postfix matches the expected format ([_a-zA-Z0-9]*)
436 if _algPostfixExpr.match (postfix) is None :
437 raise ValueError (f'invalid algorithm postfix: {postfix}')
438 if postfix == '' :
439 self._algPostfix = ''
440 elif postfix[0] != '_' :
441 self._algPostfix = '_' + postfix
442 else :
443 self._algPostfix = postfix
444

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

661 def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
662 """set the meta information for the given container
663
664 This is used to pass down meta-information from the
665 configuration to the algorithms.
666 """
667 if containerName not in self._containerConfig :
668 raise KeyError (f"container unknown: {containerName}")
669 if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
670 raise KeyError (f'duplicate meta-field {metaField} on container {containerName}')
671 self._containerConfig[containerName].meta[metaField] = value
672

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

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

◆ setExtraInputs()

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

Definition at line 523 of file ConfigAccumulator.py.

523 def setExtraInputs (self, inputs) :
524 """set extra input dependencies for the current algorithm"""
525 if DualUseConfig.isAthena:
526 self._currentAlg.ExtraInputs = inputs
527

◆ setExtraOutputs()

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

Definition at line 528 of file ConfigAccumulator.py.

528 def setExtraOutputs (self, outputs) :
529 """set extra output dependencies for the current algorithm"""
530 if DualUseConfig.isAthena:
531 self._currentAlg.ExtraOutputs = outputs
532

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

534 *, originalName = None, isMet = False) :
535 """set the (default) name of the source/original container
536
537 This is essentially meant to allow using e.g. the muon
538 configuration and the user not having to manually specify that
539 they want to use the Muons/AnalysisMuons container from the
540 input file.
541
542 In addition it allows to set the original name of the
543 container (which may be different from the source name), which
544 is mostly/exclusively used for jet containers, so that
545 subsequent configurations know which jet container they
546 operate on.
547 """
548 if containerName not in self._containerConfig :
549 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName, noSysSuffix = self._noSysSuffix, originalName = originalName, isMet = isMet)
550
551

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

590 def wantCopy (self, containerName) :
591 """ask whether we want/need a copy of the container
592
593 This usually only happens if no copy of the container has been
594 made yet and the copy is needed to allow modifications, etc.
595 """
596 if containerName not in self._containerConfig :
597 raise KeyError (f"no source container for: {containerName}")
598 config = self._containerConfig[containerName]
599 if len (config.names) == 0 :
600 raise ValueError (f"checking wantCopy on container with no name in event store: {containerName}")
601 return config.names[-1] == config.sourceName
602
603

◆ writeName()

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

Definition at line 552 of file ConfigAccumulator.py.

552 def writeName (self, containerName, *, isMet=None) :
553 """register that the given container will be made and return
554 its name"""
555 if containerName not in self._containerConfig :
556 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName = None, noSysSuffix = self._noSysSuffix)
557 config = self._containerConfig[containerName]
558 if config.sourceName is not None :
559 raise ValueError (f"trying to write container configured for input: {containerName}")
560 if config.names :
561 raise ValueError (f"trying to write container twice: {containerName}")
562 if isMet is not None :
563 config.isMet = isMet
564 return config.appendStep()
565
566

Member Data Documentation

◆ _algorithms

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

Definition at line 322 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 340 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 320 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg = None
protected

Definition at line 323 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 327 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 321 of file ConfigAccumulator.py.

◆ _outputStreams

python.ConfigAccumulator.ConfigAccumulator._outputStreams = []
protected

Definition at line 319 of file ConfigAccumulator.py.

◆ _selectionNameExpr

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

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


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