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)
 checkOutputContainer (self, containerName)
 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 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 182 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 214 of file ConfigAccumulator.py.

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

Member Function Documentation

◆ addEventCutFlow()

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

Definition at line 811 of file ConfigAccumulator.py.

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

◆ addOutputContainer()

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

Definition at line 843 of file ConfigAccumulator.py.

843 def addOutputContainer (self, containerName, outputContainerName) :
844 """register a copy of a container used in outputs"""
845 if containerName not in self._containerConfig :
846 raise KeyError ("container unknown: " + containerName)
847 if outputContainerName in self._outputContainers :
848 raise KeyError ("duplicate output container name: " + outputContainerName)
849 self._outputContainers[outputContainerName] = containerName
850
851

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

869 *, noSys=False, enabled=True, auxType=None) :
870 """add an output variable for the given container to the output
871 """
872
873 if containerName not in self._containerConfig :
874 raise KeyError ("container unknown: " + containerName)
875 baseConfig = self._containerConfig[containerName].outputs
876 if outputName in baseConfig :
877 raise KeyError ("duplicate output variable name: " + outputName)
878 config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled, auxType=auxType)
879 baseConfig[outputName] = config
880
881

◆ addPrivateTool()

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

Definition at line 510 of file ConfigAccumulator.py.

510 def addPrivateTool (self, propertyName, toolType) :
511 """add a private tool to the current algorithm"""
512 DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
513

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

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

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

400 def algPostfix (self) :
401 """the current postfix to be appended to algorithm names
402
403 Blocks should not call this directly, but rather implement the
404 instanceName method, which will be used to generate the postfix
405 automatically."""
406 return self._algPostfix
407

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

346 def autoconfigFlags (self) :
347 """Athena configuration flags
348
349 This is a backward compatibility version of the flags property,
350 which is preferred."""
351 return self._flags
352

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

209 def beginJob(cls):
210 """Helper class method to fully reset the counters, call once before building a new job sequence."""
211 cls._instance_counter = 0
212 cls._singleton_registry.clear()
213
void clear()
Empty the pool.

◆ campaign()

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

Definition at line 369 of file ConfigAccumulator.py.

369 def campaign(self) :
370 """the MC campaign we run on"""
371 return self._flags.Input.MCCampaign
372

◆ checkOutputContainer()

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

Definition at line 852 of file ConfigAccumulator.py.

852 def checkOutputContainer (self, containerName) :
853 """check whether a given container has been registered in outputs"""
854 return containerName in self._outputContainers.values()
855
856

◆ copyName()

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

Definition at line 570 of file ConfigAccumulator.py.

570 def copyName (self, containerName) :
571 """register that a copy of the container will be made and return
572 its name"""
573 if containerName not in self._containerConfig :
574 raise Exception ("unknown container: " + containerName)
575 return self._containerConfig[containerName].appendStep()
576
577

◆ createAlgorithm()

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

Definition at line 435 of file ConfigAccumulator.py.

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

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

484 def createPublicTool (self, type, name, isSingleton=True) :
485 '''create a new public tool and register it as the "current algorithm"'''
486 if not isSingleton:
487 name = self._algPrefix + name + self._algPostfix
488 if isSingleton and name in ConfigAccumulator._singleton_registry:
489 tool = ConfigAccumulator._singleton_registry[name]
490 self._algorithms[name] = tool
491 self._currentAlg = tool
492 return tool
493 if name in self._algorithms :
494 raise Exception ('duplicate public tool: ' + name)
495 tool = DualUseConfig.createPublicTool (type, name)
496 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
497 # as it modifies Gaudi behaviour
498 if DualUseConfig.isAthena:
499 self.CA.addPublicTool(tool)
500 else:
501 # We're not, so let's remember this as a "normal" algorithm:
502 self._algSeq += tool
503 self._algorithms[name] = tool
504 self._currentAlg = tool
505 if isSingleton:
506 ConfigAccumulator._singleton_registry[name] = tool
507 return tool
508
509

◆ createService()

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

Definition at line 458 of file ConfigAccumulator.py.

458 def createService (self, type, name, isSingleton=True) :
459 '''create a new service and register it as the "current algorithm"'''
460 if not isSingleton:
461 name = self._algPrefix + name + self._algPostfix
462 if isSingleton and name in ConfigAccumulator._singleton_registry:
463 service = ConfigAccumulator._singleton_registry[name]
464 self._algorithms[name] = service
465 self._currentAlg = service
466 return service
467 if name in self._algorithms :
468 raise Exception ('duplicate service: ' + name)
469 service = DualUseConfig.createService (type, name)
470 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
471 # as it modifies Gaudi behaviour
472 if DualUseConfig.isAthena:
473 self.CA.addService(service)
474 else:
475 # We're not, so let's remember this as a "normal" algorithm:
476 self._algSeq += service
477 self._algorithms[name] = service
478 self._currentAlg = service
479 if isSingleton:
480 ConfigAccumulator._singleton_registry[name] = service
481 return service
482
483

◆ dataType()

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

Definition at line 353 of file ConfigAccumulator.py.

353 def dataType (self) :
354 """the data type we run on (data, fullsim, fastsim)"""
355 return self._dataType
356

◆ dataYear()

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

Definition at line 377 of file ConfigAccumulator.py.

377 def dataYear(self) :
378 """for data, the corresponding year; for MC, zero"""
379 return self._flags.Input.DataYear
380

◆ defaultHistogramStream()

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

Definition at line 389 of file ConfigAccumulator.py.

389 def defaultHistogramStream(self):
390 """the default histogram stream to be used for output histograms"""
391 return self._defaultHistogramStream
392

◆ dsid()

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

Definition at line 365 of file ConfigAccumulator.py.

365 def dsid(self) :
366 """the mcChannelNumber or DSID of the sample we run on"""
367 return self._flags.Input.MCChannelNumber
368

◆ flags()

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

Definition at line 341 of file ConfigAccumulator.py.

341 def flags (self) :
342 """Athena configuration flags"""
343 return self._flags
344

◆ generatorInfo()

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

Definition at line 381 of file ConfigAccumulator.py.

381 def generatorInfo(self) :
382 """the dictionary of MC generators and their versions for the sample we run on"""
383 return self._flags.Input.GeneratorsInfo
384

◆ geometry()

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

Definition at line 361 of file ConfigAccumulator.py.

361 def geometry (self) :
362 """the LHC Run period we run on"""
363 return self._flags.GeoModel.Run
364

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

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

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

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

◆ getEventCutFlow()

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

Definition at line 822 of file ConfigAccumulator.py.

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

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

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

857 def getOutputContainerOrigin (self, outputContainerName) :
858 """Get the name of the actual container, for which an output is registered"""
859 try:
860 return self._outputContainers[outputContainerName]
861 except KeyError:
862 try:
863 return self._containerConfig[outputContainerName].name
864 except KeyError:
865 raise KeyError ("output container unknown: " + outputContainerName)
866
867

◆ getOutputVars()

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

Definition at line 882 of file ConfigAccumulator.py.

882 def getOutputVars (self, containerName) :
883 """get the output variables for the given container"""
884 if containerName in self._outputContainers :
885 containerName = self._outputContainers[containerName]
886 if containerName not in self._containerConfig :
887 raise KeyError ("unknown container for output: " + containerName)
888 return self._containerConfig[containerName].outputs
889
890

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

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

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

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

◆ getSelectionNames()

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

Definition at line 891 of file ConfigAccumulator.py.

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

◆ hltSummary()

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

Definition at line 385 of file ConfigAccumulator.py.

385 def hltSummary(self) :
386 """the HLTSummary configuration to be used for the trigger decision tool"""
387 return self._hltSummary
388

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

661 def isMetContainer (self, containerName) :
662 """whether the given container is registered as a MET container
663
664 This is mostly/exclusively used for determining whether to
665 write out the whole container or just a single MET term.
666 """
667 if containerName not in self._containerConfig :
668 raise Exception ("container unknown: " + containerName)
669 return self._containerConfig[containerName].isMet
670
671

◆ isPhyslite()

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

Definition at line 357 of file ConfigAccumulator.py.

357 def isPhyslite (self) :
358 """whether we run on PHYSLITE"""
359 return self._isPhyslite
360

◆ noSystematics()

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

Definition at line 336 of file ConfigAccumulator.py.

336 def noSystematics (self) :
337 """noSystematics flag used by CommonServices block"""
338 return self._noSystematics
339

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

621 def originalName (self, containerName) :
622 """get the "original" name of the given container
623
624 This is mostly/exclusively used for jet containers, so that
625 subsequent configurations know which jet container they
626 operate on.
627 """
628 if containerName not in self._containerConfig :
629 raise Exception ("container unknown: " + containerName)
630 result = self._containerConfig[containerName].originalName
631 if result is None :
632 raise Exception ("no original name for: " + containerName)
633 return result
634

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

558 def readName (self, containerName, *, nominal=False) :
559 """get the name of the "current copy" of the given container
560
561 As extra copies get created during processing this will track
562 the correct name of the current copy. Optionally one can pass
563 in the name of the container before the first copy.
564 """
565 if containerName not in self._containerConfig :
566 raise Exception ("no source container for: " + containerName)
567 return self._containerConfig[containerName].currentName(nominal=nominal)
568
569

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

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

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

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

◆ runNumber()

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

Definition at line 373 of file ConfigAccumulator.py.

373 def runNumber(self) :
374 """the MC runNumber"""
375 return int(self._flags.Input.RunNumbers[0])
376

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

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

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

649 def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
650 """set the meta information for the given container
651
652 This is used to pass down meta-information from the
653 configuration to the algorithms.
654 """
655 if containerName not in self._containerConfig :
656 raise Exception ("container unknown: " + containerName)
657 if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
658 raise Exception ('duplicate meta-field' + metaField + ' on container ' + containerName)
659 self._containerConfig[containerName].meta[metaField] = value
660

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

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

◆ setExtraInputs()

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

Definition at line 514 of file ConfigAccumulator.py.

514 def setExtraInputs (self, inputs) :
515 """set extra input dependencies for the current algorithm"""
516 if DualUseConfig.isAthena:
517 self._currentAlg.ExtraInputs = inputs
518

◆ setExtraOutputs()

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

Definition at line 519 of file ConfigAccumulator.py.

519 def setExtraOutputs (self, outputs) :
520 """set extra output dependencies for the current algorithm"""
521 if DualUseConfig.isAthena:
522 self._currentAlg.ExtraOutputs = outputs
523

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

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

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

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

◆ writeName()

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

Definition at line 543 of file ConfigAccumulator.py.

543 def writeName (self, containerName, *, isMet=None) :
544 """register that the given container will be made and return
545 its name"""
546 if containerName not in self._containerConfig :
547 self._containerConfig[containerName] = ContainerConfig (containerName, sourceName = None, noSysSuffix = self._noSysSuffix)
548 config = self._containerConfig[containerName]
549 if config.sourceName is not None :
550 raise Exception ("trying to write container configured for input: " + containerName)
551 if config.names :
552 raise Exception ("trying to write container twice: " + containerName)
553 if isMet is not None :
554 config.isMet = isMet
555 return config.appendStep()
556
557

Member Data Documentation

◆ _algorithms

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

Definition at line 316 of file ConfigAccumulator.py.

◆ _algPostfix

python.ConfigAccumulator.ConfigAccumulator._algPostfix = ''
protected

Definition at line 312 of file ConfigAccumulator.py.

◆ _algPrefix

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

Definition at line 334 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq = algSeq
protected

Definition at line 309 of file ConfigAccumulator.py.

◆ _containerConfig

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

Definition at line 314 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg = None
protected

Definition at line 317 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType = dataType
protected

Definition at line 302 of file ConfigAccumulator.py.

◆ _defaultHistogramStream

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

Definition at line 313 of file ConfigAccumulator.py.

◆ _eventcutflow

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

Definition at line 321 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags = flags
protected

Definition at line 225 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary = hltSummary
protected

Definition at line 304 of file ConfigAccumulator.py.

◆ _instance_counter

int python.ConfigAccumulator.ConfigAccumulator._instance_counter = 0
staticprotected

Definition at line 204 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite = isPhyslite
protected

Definition at line 303 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix = noSysSuffix
protected

Definition at line 311 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics = noSystematics
protected

Definition at line 310 of file ConfigAccumulator.py.

◆ _outputContainers

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

Definition at line 315 of file ConfigAccumulator.py.

◆ _selectionNameExpr

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

Definition at line 318 of file ConfigAccumulator.py.

◆ _singleton_registry

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

Definition at line 206 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA = None

Definition at line 322 of file ConfigAccumulator.py.


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