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

Public Member Functions

 __init__ (self, *, flags=None, algSeq=None, noSysSuffix=False, noSystematics=None, dataType=None, isPhyslite=None, geometry=None, dsid=0, campaign=None, runNumber=None, autoconfigFromFlags=None, dataYear=0)
 noSystematics (self)
 flags (self)
 autoconfigFlags (self)
 dataType (self)
 isPhyslite (self)
 geometry (self)
 dsid (self)
 campaign (self)
 runNumber (self)
 dataYear (self)
 generatorInfo (self)
 hltSummary (self)
 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)
 createPublicTool (self, type, name)
 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)
 originalName (self, containerName)
 getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False)
 setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False)
 isMetContainer (self, containerName)
 readNameAndSelection (self, containerName, *, excludeFrom=None)
 nextPass (self)
 getPreselection (self, containerName, selectionName, *, asList=False)
 getFullSelection (self, containerName, selectionName, *, skipBase=False, excludeFrom=None)
 getSelectionCutFlow (self, containerName, selectionName)
 addEventCutFlow (self, selection, decorations)
 getEventCutFlow (self, selection)
 addSelection (self, containerName, selectionName, decoration, **kwargs)
 addOutputContainer (self, containerName, outputContainerName)
 checkOutputContainer (self, containerName)
 getOutputContainerOrigin (self, outputContainerName)
 addOutputVar (self, containerName, variableName, outputName, *, noSys=False, enabled=True, 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 = {}
int _pass = 0
dict _algorithms = {}
dict _currentAlg = None
 _selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]+')
dict _eventcutflow = {}

Detailed Description

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

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

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

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

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

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

792 def addEventCutFlow (self, selection, decorations) :
793
794 """register a new event cutflow, adding it to the dictionary with key 'selection'
795 and value 'decorations', a list of decorated selections
796 """
797 if self._pass == 0:
798 if selection in self._eventcutflow.keys():
799 raise ValueError ('the event cutflow dictionary already contains an entry ' + selection)
800 else:
801 self._eventcutflow[selection] = decorations
802
803

◆ addOutputContainer()

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

Definition at line 825 of file ConfigAccumulator.py.

825 def addOutputContainer (self, containerName, outputContainerName) :
826 """register a copy of a container used in outputs"""
827 if containerName not in self._containerConfig :
828 raise KeyError ("container unknown: " + containerName)
829 if outputContainerName in self._outputContainers :
830 raise KeyError ("duplicate output container name: " + outputContainerName)
831 self._outputContainers[outputContainerName] = containerName
832
833

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

851 *, noSys=False, enabled=True, auxType=None) :
852 """add an output variable for the given container to the output
853 """
854
855 if containerName not in self._containerConfig :
856 raise KeyError ("container unknown: " + containerName)
857 baseConfig = self._containerConfig[containerName].outputs
858 if outputName in baseConfig :
859 raise KeyError ("duplicate output variable name: " + outputName)
860 config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled, auxType=auxType)
861 baseConfig[outputName] = config
862
863

◆ addPrivateTool()

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

Definition at line 502 of file ConfigAccumulator.py.

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

◆ addSelection()

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

Definition at line 812 of file ConfigAccumulator.py.

813 **kwargs) :
814 """add another selection decoration to the selection of the given
815 name for the given container"""
816 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
817 raise ValueError ('invalid selection name: ' + selectionName)
818 if containerName not in self._containerConfig :
819 self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
820 config = self._containerConfig[containerName]
821 selection = SelectionConfig (selectionName, decoration, **kwargs)
822 config.selections.append (selection)
823
824

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

390 def algPostfix (self) :
391 """the current postfix to be appended to algorithm names
392
393 Blocks should not call this directly, but rather implement the
394 instanceName method, which will be used to generate the postfix
395 automatically."""
396 return self._algPostfix
397

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

336 def autoconfigFlags (self) :
337 """Athena configuration flags
338
339 This is a backward compatibility version of the flags property,
340 which is preferred."""
341 return self._flags
342

◆ campaign()

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

Definition at line 359 of file ConfigAccumulator.py.

359 def campaign(self) :
360 """the MC campaign we run on"""
361 return self._flags.Input.MCCampaign
362

◆ checkOutputContainer()

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

Definition at line 834 of file ConfigAccumulator.py.

834 def checkOutputContainer (self, containerName) :
835 """check whether a given container has been registered in outputs"""
836 return containerName in self._outputContainers.values()
837
838

◆ copyName()

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

Definition at line 563 of file ConfigAccumulator.py.

563 def copyName (self, containerName) :
564 """register that a copy of the container will be made and return
565 its name"""
566 if containerName not in self._containerConfig :
567 raise Exception ("unknown container: " + containerName)
568 self._containerConfig[containerName].index += 1
569 return self._containerConfig[containerName].currentName()
570
571

◆ createAlgorithm()

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

Definition at line 425 of file ConfigAccumulator.py.

425 def createAlgorithm (self, type, name, reentrant=False) :
426 """create a new algorithm and register it as the current algorithm"""
427 name = name + self._algPostfix
428 if self._pass == 0 :
429 if name in self._algorithms :
430 raise Exception ('duplicate algorithms: ' + name + ' with algPostfix=' + self._algPostfix)
431 if reentrant:
432 alg = DualUseConfig.createReentrantAlgorithm (type, name)
433 else:
434 alg = DualUseConfig.createAlgorithm (type, name)
435
436 if DualUseConfig.isAthena:
437 if self._algSeq is not None:
438 self.CA.addEventAlgo(alg,self._algSeq.name)
439 else :
440 self.CA.addEventAlgo(alg)
441 else:
442 self._algSeq += alg
443
444 self._algorithms[name] = alg
445 self._currentAlg = alg
446 return alg
447 else :
448 if name not in self._algorithms :
449 raise Exception ('unknown algorithm requested: ' + name)
450 self._currentAlg = self._algorithms[name]
451 if self.CA and self._currentAlg != self.CA.getEventAlgo(name) :
452 raise Exception ('change to algorithm object: ' + name)
453 return self._algorithms[name]
454
455

◆ createPublicTool()

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

Definition at line 479 of file ConfigAccumulator.py.

479 def createPublicTool (self, type, name) :
480 '''create a new public tool and register it as the "current algorithm"'''
481 if self._pass == 0 :
482 if name in self._algorithms :
483 raise Exception ('duplicate public tool: ' + name)
484 tool = DualUseConfig.createPublicTool (type, name)
485 # Avoid importing AthenaCommon.AppMgr in a CA Athena job
486 # as it modifies Gaudi behaviour
487 if DualUseConfig.isAthena:
488 self.CA.addPublicTool(tool)
489 else:
490 # We're not, so let's remember this as a "normal" algorithm:
491 self._algSeq += tool
492 self._algorithms[name] = tool
493 self._currentAlg = tool
494 return tool
495 else :
496 if name not in self._algorithms :
497 raise Exception ('unknown public tool requested: ' + name)
498 self._currentAlg = self._algorithms[name]
499 return self._algorithms[name]
500
501

◆ createService()

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

Definition at line 456 of file ConfigAccumulator.py.

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

◆ dataType()

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

Definition at line 343 of file ConfigAccumulator.py.

343 def dataType (self) :
344 """the data type we run on (data, fullsim, fastsim)"""
345 return self._dataType
346

◆ dataYear()

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

Definition at line 367 of file ConfigAccumulator.py.

367 def dataYear(self) :
368 """for data, the corresponding year; for MC, zero"""
369 return self._flags.Input.DataYear
370

◆ defaultHistogramStream()

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

Definition at line 379 of file ConfigAccumulator.py.

379 def defaultHistogramStream(self):
380 """the default histogram stream to be used for output histograms"""
381 return self._defaultHistogramStream
382

◆ dsid()

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

Definition at line 355 of file ConfigAccumulator.py.

355 def dsid(self) :
356 """the mcChannelNumber or DSID of the sample we run on"""
357 return self._flags.Input.MCChannelNumber
358

◆ flags()

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

Definition at line 331 of file ConfigAccumulator.py.

331 def flags (self) :
332 """Athena configuration flags"""
333 return self._flags
334

◆ generatorInfo()

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

Definition at line 371 of file ConfigAccumulator.py.

371 def generatorInfo(self) :
372 """the dictionary of MC generators and their versions for the sample we run on"""
373 return self._flags.Input.GeneratorsInfo
374

◆ geometry()

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

Definition at line 351 of file ConfigAccumulator.py.

351 def geometry (self) :
352 """the LHC Run period we run on"""
353 return self._flags.GeoModel.Run
354

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

414 def getAlgorithm (self, name : str):
415 """get the algorithm with the given name
416
417 Despite the name this will also return services and tools. It is
418 mostly meant for internal use, particularly for the property
419 overrides."""
420 name = name + self._algPostfix
421 if name not in self._algorithms:
422 return None
423 return self._algorithms[name]
424

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

597 def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
598 """get the meta information for the given container
599
600 This is used to pass down meta-information from the
601 configuration to the algorithms.
602 """
603 if containerName not in self._containerConfig :
604 raise Exception ("container unknown: " + containerName)
605 if metaField in self._containerConfig[containerName].meta :
606 return self._containerConfig[containerName].meta[metaField]
607 if failOnMiss :
608 raise Exception ('unknown meta-field' + metaField + ' on container ' + containerName)
609 return defaultValue
610

◆ getEventCutFlow()

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

Definition at line 804 of file ConfigAccumulator.py.

804 def getEventCutFlow (self, selection) :
805
806 """get the list of decorated selections for an event cutflow, corresponding to
807 key 'selection'
808 """
809 return self._eventcutflow[selection]
810
811

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

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

839 def getOutputContainerOrigin (self, outputContainerName) :
840 """Get the name of the actual container, for which an output is registered"""
841 try:
842 return self._outputContainers[outputContainerName]
843 except KeyError:
844 try:
845 return self._containerConfig[outputContainerName].name
846 except KeyError:
847 raise KeyError ("output container unknown: " + outputContainerName)
848
849

◆ getOutputVars()

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

Definition at line 864 of file ConfigAccumulator.py.

864 def getOutputVars (self, containerName) :
865 """get the output variables for the given container"""
866 if containerName in self._outputContainers :
867 containerName = self._outputContainers[containerName]
868 if containerName not in self._containerConfig :
869 raise KeyError ("unknown container for output: " + containerName)
870 return self._containerConfig[containerName].outputs
871
872

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

673 def getPreselection (self, containerName, selectionName, *, asList = False) :
674
675 """get the preselection string for the given selection on the given
676 container
677 """
678 if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
679 raise ValueError ('invalid selection name: ' + selectionName)
680 if containerName not in self._containerConfig :
681 return ""
682 config = self._containerConfig[containerName]
683 decorations = []
684 for selection in config.selections :
685 if (selection.name == '' or selection.name == selectionName) and \
686 selection.preselection :
687 decorations += [selection.decoration]
688 if asList :
689 return decorations
690 else :
691 return '&&'.join (decorations)
692
693

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

763 def getSelectionCutFlow (self, containerName, selectionName) :
764
765 """get the individual selections as a list for producing the cutflow for
766 the given selection on the given container
767
768 This can only handle individual selections, not selection
769 expressions (e.g. `loose||tight`).
770
771 """
772 if containerName not in self._containerConfig :
773 return []
774
775 # Check if this is actually a selection expression,
776 # e.g. `A||B` and if so translate it into a complex expression
777 # for the user. I'm not trying to do any complex syntax
778 # recognition, but instead just produce an expression that the
779 # C++ parser ought to be able to read.
780 if selectionName != '' and \
781 not self._selectionNameExpr.fullmatch (selectionName) :
782 raise ValueError ('not allowed to do cutflow on selection expression: ' + selectionName)
783
784 config = self._containerConfig[containerName]
785 decorations = []
786 for selection in config.selections :
787 if (selection.name == '' or selection.name == selectionName) :
788 decorations += [selection.decoration]
789 return decorations
790
791

◆ getSelectionNames()

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

Definition at line 873 of file ConfigAccumulator.py.

873 def getSelectionNames (self, containerName, excludeFrom = None) :
874 """Retrieve set of unique selections defined for a given container"""
875 if containerName not in self._containerConfig :
876 return []
877 if excludeFrom is None:
878 excludeFrom = set()
879 elif not isinstance(excludeFrom, set) :
880 raise ValueError ('invalid excludeFrom argument (need set of strings): ' + str(excludeFrom))
881
882 config = self._containerConfig[containerName]
883 # because cuts are registered individually, selection names can repeat themselves
884 # but we are interested in unique names only
885 selectionNames = set()
886 for selection in config.selections:
887 if selection.comesFrom in excludeFrom:
888 continue
889 # skip flags which should be disabled in output
890 if selection.writeToOutput:
891 selectionNames.add(selection.name)
892 return selectionNames

◆ hltSummary()

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

Definition at line 375 of file ConfigAccumulator.py.

375 def hltSummary(self) :
376 """the HLTSummary configuration to be used for the trigger decision tool"""
377 return self._hltSummary
378

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

623 def isMetContainer (self, containerName) :
624 """whether the given container is registered as a MET container
625
626 This is mostly/exclusively used for determining whether to
627 write out the whole container or just a single MET term.
628 """
629 if containerName not in self._containerConfig :
630 raise Exception ("container unknown: " + containerName)
631 return self._containerConfig[containerName].isMet
632
633

◆ isPhyslite()

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

Definition at line 347 of file ConfigAccumulator.py.

347 def isPhyslite (self) :
348 """whether we run on PHYSLITE"""
349 return self._isPhyslite
350

◆ nextPass()

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

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

Definition at line 654 of file ConfigAccumulator.py.

654 def nextPass (self) :
655 """switch to the next configuration pass
656
657 Configuration happens in two steps, with all the blocks processed
658 twice. This switches from the first to the second pass.
659 """
660 if self._pass != 0 :
661 raise Exception ("already performed final pass")
662 for name in self._containerConfig :
663 self._containerConfig[name].nextPass ()
664 self._pass = 1
665 self._currentAlg = None
666 self._outputContainers = {}
667
668 # the above wiped out the meta-information, so we need to
669 # re-register the non-container status of EventInfo
670 self.setContainerMeta ('EventInfo', 'nonContainer', True)
671
672

◆ noSystematics()

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

Definition at line 326 of file ConfigAccumulator.py.

326 def noSystematics (self) :
327 """noSystematics flag used by CommonServices block"""
328 return self._noSystematics
329

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

583 def originalName (self, containerName) :
584 """get the "original" name of the given container
585
586 This is mostly/exclusively used for jet containers, so that
587 subsequent configurations know which jet container they
588 operate on.
589 """
590 if containerName not in self._containerConfig :
591 raise Exception ("container unknown: " + containerName)
592 result = self._containerConfig[containerName].originalName
593 if result is None :
594 raise Exception ("no original name for: " + containerName)
595 return result
596

◆ readName()

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

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

Definition at line 551 of file ConfigAccumulator.py.

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

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

634 def readNameAndSelection (self, containerName, *, excludeFrom = None) :
635 """get the name of the "current copy" of the given container, and the
636 selection string
637
638 This is mostly meant for MET and OR for whom the actual object
639 selection is relevant, and which as such allow to pass in the
640 working point as "ObjectName.WorkingPoint".
641 """
642 split = containerName.split (".")
643 if len(split) == 1 :
644 objectName = split[0]
645 selectionName = ''
646 elif len(split) == 2 :
647 objectName = split[0]
648 selectionName = split[1]
649 else :
650 raise Exception ('invalid object selection name: ' + containerName)
651 return self.readName (objectName), self.getFullSelection (objectName, selectionName, excludeFrom=excludeFrom)
652
653

◆ runNumber()

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

Definition at line 363 of file ConfigAccumulator.py.

363 def runNumber(self) :
364 """the MC runNumber"""
365 return int(self._flags.Input.RunNumbers[0])
366

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

398 def setAlgPostfix (self, postfix : str) :
399 """set the current postfix to be appended to algorithm names
400
401 Blocks should not call this directly, but rather implement the
402 instanceName method, which will be used to generate the postfix
403 automatically."""
404 # make sure the postfix matches the expected format ([_a-zA-Z0-9]*)
405 if re.compile ('^[_a-zA-Z0-9]*$').match (postfix) is None :
406 raise ValueError ('invalid algorithm postfix: ' + postfix)
407 if postfix == '' :
408 self._algPostfix = ''
409 elif postfix[0] != '_' :
410 self._algPostfix = '_' + postfix
411 else :
412 self._algPostfix = postfix
413

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

611 def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
612 """set the meta information for the given container
613
614 This is used to pass down meta-information from the
615 configuration to the algorithms.
616 """
617 if containerName not in self._containerConfig :
618 raise Exception ("container unknown: " + containerName)
619 if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
620 raise Exception ('duplicate meta-field' + metaField + ' on container ' + containerName)
621 self._containerConfig[containerName].meta[metaField] = value
622

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

383 def setDefaultHistogramStream(self, streamName: str):
384 """set the default histogram stream to be used for output histograms
385
386 As an advanced option this is not directly exposed by the constructor,
387 but can be set by the user if needed before configuring the job."""
388 self._defaultHistogramStream = streamName
389

◆ setExtraInputs()

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

Definition at line 507 of file ConfigAccumulator.py.

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

◆ setExtraOutputs()

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

Definition at line 512 of file ConfigAccumulator.py.

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

◆ setSourceName()

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

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

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

Definition at line 517 of file ConfigAccumulator.py.

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

◆ wantCopy()

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

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

Definition at line 572 of file ConfigAccumulator.py.

572 def wantCopy (self, containerName) :
573 """ask whether we want/need a copy of the container
574
575 This usually only happens if no copy of the container has been
576 made yet and the copy is needed to allow modifications, etc.
577 """
578 if containerName not in self._containerConfig :
579 raise Exception ("no source container for: " + containerName)
580 return self._containerConfig[containerName].index == 0
581
582

◆ writeName()

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

Definition at line 536 of file ConfigAccumulator.py.

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

Member Data Documentation

◆ _algorithms

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

Definition at line 309 of file ConfigAccumulator.py.

◆ _algPostfix

python.ConfigAccumulator.ConfigAccumulator._algPostfix = ''
protected

Definition at line 304 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq = algSeq
protected

Definition at line 301 of file ConfigAccumulator.py.

◆ _containerConfig

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

Definition at line 306 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg = None
protected

Definition at line 310 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType = dataType
protected

Definition at line 294 of file ConfigAccumulator.py.

◆ _defaultHistogramStream

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

Definition at line 305 of file ConfigAccumulator.py.

◆ _eventcutflow

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

Definition at line 314 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags = flags
protected

Definition at line 217 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary = hltSummary
protected

Definition at line 296 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite = isPhyslite
protected

Definition at line 295 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix = noSysSuffix
protected

Definition at line 303 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics = noSystematics
protected

Definition at line 302 of file ConfigAccumulator.py.

◆ _outputContainers

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

Definition at line 307 of file ConfigAccumulator.py.

◆ _pass

int python.ConfigAccumulator.ConfigAccumulator._pass = 0
protected

Definition at line 308 of file ConfigAccumulator.py.

◆ _selectionNameExpr

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

Definition at line 311 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA = None

Definition at line 315 of file ConfigAccumulator.py.


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