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

Public Member Functions

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

Public Attributes

 CA = None

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

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

◆ addOutputContainer()

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

Definition at line 846 of file ConfigAccumulator.py.

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

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

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

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

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

◆ 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

◆ copyName()

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

Definition at line 573 of file ConfigAccumulator.py.

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

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

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

◆ getEventCutFlow()

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

Definition at line 825 of file ConfigAccumulator.py.

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

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

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

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

◆ getOutputVars()

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

Definition at line 883 of file ConfigAccumulator.py.

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

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

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

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

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

◆ getSelectionNames()

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

Definition at line 892 of file ConfigAccumulator.py.

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

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

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

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

◆ 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 in self._outputContainers:
566 return f"{containerName}_%SYS%"
567
568 if containerName not in self._containerConfig :
569 raise Exception ("no source container for: " + containerName)
570 return self._containerConfig[containerName].currentName(nominal=nominal)
571
572

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

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

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

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

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

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

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

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

◆ 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: