ATLAS Offline Software
Public Member Functions | Public Attributes | Private Attributes | List of all members
python.ConfigAccumulator.ConfigAccumulator Class Reference
Collaboration diagram for python.ConfigAccumulator.ConfigAccumulator:

Public Member Functions

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)
 
def noSystematics (self)
 
def flags (self)
 
def autoconfigFlags (self)
 
def dataType (self)
 
def isPhyslite (self)
 
def geometry (self)
 
def dsid (self)
 
def campaign (self)
 
def runNumber (self)
 
def dataYear (self)
 
def generatorInfo (self)
 
def hltSummary (self)
 
def algPostfix (self)
 
def setAlgPostfix (self, str postfix)
 
def getAlgorithm (self, str name)
 
def createAlgorithm (self, type, name, reentrant=False)
 
def createService (self, type, name)
 
def createPublicTool (self, type, name)
 
def addPrivateTool (self, propertyName, toolType)
 
def setSourceName (self, containerName, sourceName, *originalName=None, isMet=False)
 
def writeName (self, containerName, *isMet=None)
 
def readName (self, containerName)
 
def copyName (self, containerName)
 
def wantCopy (self, containerName)
 
def originalName (self, containerName)
 
def getContainerMeta (self, containerName, metaField, defaultValue=None, *failOnMiss=False)
 
def setContainerMeta (self, containerName, metaField, value, *allowOverwrite=False)
 
def isMetContainer (self, containerName)
 
def readNameAndSelection (self, containerName, *excludeFrom=None)
 
def nextPass (self)
 
def getPreselection (self, containerName, selectionName, *asList=False)
 
def getFullSelection (self, containerName, selectionName, *skipBase=False, excludeFrom=None)
 
def getSelectionCutFlow (self, containerName, selectionName)
 
def addEventCutFlow (self, selection, decorations)
 
def getEventCutFlow (self, selection)
 
def addSelection (self, containerName, selectionName, decoration, **kwargs)
 
def addOutputContainer (self, containerName, outputContainerName)
 
def checkOutputContainer (self, containerName)
 
def getOutputContainerOrigin (self, outputContainerName)
 
def addOutputVar (self, containerName, variableName, outputName, *noSys=False, enabled=True)
 
def getOutputVars (self, containerName)
 
def getSelectionNames (self, containerName, excludeFrom=None)
 

Public Attributes

 CA
 

Private Attributes

 _flags
 
 _dataType
 
 _isPhyslite
 
 _hltSummary
 
 _algSeq
 
 _noSystematics
 
 _noSysSuffix
 
 _algPostfix
 
 _containerConfig
 
 _outputContainers
 
 _pass
 
 _algorithms
 
 _currentAlg
 
 _selectionNameExpr
 
 _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.

Definition at line 127 of file ConfigAccumulator.py.

Constructor & Destructor Documentation

◆ __init__()

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

144  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):
145 
146  # Historically we have used the identifier
147  # `autoconfigFromFlags`, but in the rest of the code base
148  # `flags` is used. So for now we allow either, and can hopefully
149  # at some point remove the former (21 Aug 25).
150  if autoconfigFromFlags is not None:
151  if flags is not None:
152  raise ValueError("Cannot pass both flags and autoconfigFromFlags arguments")
153  flags = autoconfigFromFlags
154  warnings.warn ('Using autoconfigFromFlags parameter is deprecated, use flags instead', category=deprecationWarningCategory, stacklevel=2)
155  self._flags = flags
156 
157  # Historically the user was expected to pass in meta-data
158  # manually, which was a complete underestimate of the amount of
159  # meta-data needed. The current recommendation is to pass in a
160  # configuration flags object instead. The code below will raise
161  # an error if both are done, and if no configuration flags are
162  # passed in, it will try to create a flags object from the
163  # passed in parameters.
164  if self._flags is not None:
165  if dataType is not None:
166  raise ValueError("Cannot pass both dataType and flags/autoconfigFromFlags arguments")
167  if isPhyslite is not None:
168  raise ValueError("Cannot pass both isPhyslite and flags/autoconfigFromFlags arguments")
169  if geometry is not None:
170  raise ValueError("Cannot pass both geometry and flags/autoconfigFromFlags arguments")
171  if dsid != 0:
172  raise ValueError("Cannot pass both dsid and flags/autoconfigFromFlags arguments")
173  if campaign is not None:
174  raise ValueError("Cannot pass both campaign and flags/autoconfigFromFlags arguments")
175  if runNumber is not None:
176  raise ValueError("Cannot pass both runNumber and flags/autoconfigFromFlags arguments")
177  if dataYear != 0:
178  raise ValueError("Cannot pass both dataYear and flags/autoconfigFromFlags arguments")
179 
180  if self._flags.Input.isMC:
181  if self._flags.Sim.ISF.Simulator.usesFastCaloSim():
182  dataType = DataType.FastSim
183  else:
184  dataType = DataType.FullSim
185  else:
186  dataType = DataType.Data
187  isPhyslite = 'StreamDAOD_PHYSLITE' in self._flags.Input.ProcessingTags
188  from TrigDecisionTool.TrigDecisionToolHelpers import (
189  getRun3NavigationContainerFromInput_forAnalysisBase)
191  else:
192  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)
193  from AthenaConfiguration.AllConfigFlags import initConfigFlags
194  flags = initConfigFlags()
195  if dataType is None:
196  raise ValueError ("need to specify dataType if flags are not set")
197  # legacy mappings of string arguments
198  if isinstance(dataType, str):
199  if dataType == 'mc':
200  dataType = DataType.FullSim
201  elif dataType == 'afii':
202  dataType = DataType.FastSim
203  else:
204  dataType = DataType(dataType)
205  if isPhyslite is None:
206  isPhyslite = False
207  if geometry is not None:
208  # allow possible string argument for `geometry` and convert it to enum
209  geometry = LHCPeriod(geometry)
210  if geometry is LHCPeriod.Run1:
211  raise ValueError ("invalid Run geometry: %s" % geometry.value)
212  flags.GeoModel.Run = geometry
213  if dsid != 0:
214  flags.Input.MCChannelNumber = dsid
215  if campaign is not None:
216  flags.Input.MCCampaign = campaign
217  if dataYear != 0:
218  flags.Input.DataYear = dataYear
219  if runNumber is None:
220  # not sure if we should just use a default run number
221  # here, or just report nothing
222  runNumber = 284500
223  flags.Input.RunNumbers = [runNumber]
224  hltSummary = 'HLTNav_Summary_DAODSlimmed'
225  flags.lock()
226  self._flags = flags
227 
228  # These don't seem to have a direct equivalent in the
229  # configuration flags. For now I'm keeping them (21 Aug 25), but
230  # they might be replaced with something that is more directly in
231  # the configuration flags in the future.
232  self._dataType = dataType
233  self._isPhyslite = isPhyslite
234  self._hltSummary = hltSummary
235 
236  # From here on, we are no longer dealing with flags or
237  # meta-data, but actual internal variables we need to manage the
238  # creation of components.
239  self._algSeq = algSeq
240  self._noSystematics = noSystematics
241  self._noSysSuffix = noSysSuffix
242  self._algPostfix = ''
243  self._containerConfig = {}
244  self._outputContainers = {}
245  self._pass = 0
246  self._algorithms = {}
247  self._currentAlg = None
248  self._selectionNameExpr = re.compile ('[A-Za-z_][A-Za-z_0-9]+')
249  self.setSourceName ('EventInfo', 'EventInfo')
250  self._eventcutflow = {}
251 
252  # If we are in an Athena environment with ComponentAccumulator configuration
253  # then the AlgSequence, which is Gaudi.AthSequencer, does not support '+=',
254  # and we in any case want to produce an output ComponentAccumulator
255  self.CA = None
256  if DualUseConfig.useComponentAccumulator:
257  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
258  self.CA = ComponentAccumulator()
259  # if we have a component accumulator the user is not required to pass
260  # in a sequence, but if they do let's add it
261  if algSeq :
262  self.CA.addSequence(algSeq)
263  else :
264  if algSeq is None :
265  raise ValueError ("need to pass algSeq if not using ComponentAccumulator")
266 
267 

Member Function Documentation

◆ addEventCutFlow()

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

713  def addEventCutFlow (self, selection, decorations) :
714 
715  """register a new event cutflow, adding it to the dictionary with key 'selection'
716  and value 'decorations', a list of decorated selections
717  """
718  if self._pass == 0:
719  if selection in self._eventcutflow.keys():
720  raise ValueError ('the event cutflow dictionary already contains an entry ' + selection)
721  else:
722  self._eventcutflow[selection] = decorations
723 
724 

◆ addOutputContainer()

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

Definition at line 746 of file ConfigAccumulator.py.

746  def addOutputContainer (self, containerName, outputContainerName) :
747  """register a copy of a container used in outputs"""
748  if containerName not in self._containerConfig :
749  raise KeyError ("container unknown: " + containerName)
750  if outputContainerName in self._outputContainers :
751  raise KeyError ("duplicate output container name: " + outputContainerName)
752  self._outputContainers[outputContainerName] = containerName
753 
754 

◆ addOutputVar()

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

Definition at line 771 of file ConfigAccumulator.py.

771  def addOutputVar (self, containerName, variableName, outputName,
772  *, noSys=False, enabled=True) :
773  """add an output variable for the given container to the output
774  """
775 
776  if containerName not in self._containerConfig :
777  raise KeyError ("container unknown: " + containerName)
778  baseConfig = self._containerConfig[containerName].outputs
779  if outputName in baseConfig :
780  raise KeyError ("duplicate output variable name: " + outputName)
781  config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled)
782  baseConfig[outputName] = config
783 
784 

◆ addPrivateTool()

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

Definition at line 436 of file ConfigAccumulator.py.

436  def addPrivateTool (self, propertyName, toolType) :
437  """add a private tool to the current algorithm"""
438  if self._pass == 0 :
439  DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
440 
441 

◆ addSelection()

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

733  def addSelection (self, containerName, selectionName, decoration,
734  **kwargs) :
735  """add another selection decoration to the selection of the given
736  name for the given container"""
737  if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
738  raise ValueError ('invalid selection name: ' + selectionName)
739  if containerName not in self._containerConfig :
740  self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
741  config = self._containerConfig[containerName]
742  selection = SelectionConfig (selectionName, decoration, **kwargs)
743  config.selections.append (selection)
744 
745 

◆ algPostfix()

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

321  def algPostfix (self) :
322  """the current postfix to be appended to algorithm names
323 
324  Blocks should not call this directly, but rather implement the
325  instanceName method, which will be used to generate the postfix
326  automatically."""
327  return self._algPostfix
328 

◆ autoconfigFlags()

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

This is a backward compatibility version of the flags property,
which is preferred.

Definition at line 278 of file ConfigAccumulator.py.

278  def autoconfigFlags (self) :
279  """Athena configuration flags
280 
281  This is a backward compatibility version of the flags property,
282  which is preferred."""
283  return self._flags
284 

◆ campaign()

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

Definition at line 301 of file ConfigAccumulator.py.

301  def campaign(self) :
302  """the MC campaign we run on"""
303  return self._flags.Input.MCCampaign
304 

◆ checkOutputContainer()

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

Definition at line 755 of file ConfigAccumulator.py.

755  def checkOutputContainer (self, containerName) :
756  """check whether a given container has been registered in outputs"""
757  return containerName in self._outputContainers.values()
758 
759 

◆ copyName()

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

Definition at line 488 of file ConfigAccumulator.py.

488  def copyName (self, containerName) :
489  """register that a copy of the container will be made and return
490  its name"""
491  if containerName not in self._containerConfig :
492  raise Exception ("unknown container: " + containerName)
493  self._containerConfig[containerName].index += 1
494  return self._containerConfig[containerName].currentName()
495 
496 

◆ createAlgorithm()

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

Definition at line 356 of file ConfigAccumulator.py.

356  def createAlgorithm (self, type, name, reentrant=False) :
357  """create a new algorithm and register it as the current algorithm"""
358  name = name + self._algPostfix
359  if self._pass == 0 :
360  if name in self._algorithms :
361  raise Exception ('duplicate algorithms: ' + name + ' with algPostfix=' + self._algPostfix)
362  if reentrant:
363  alg = DualUseConfig.createReentrantAlgorithm (type, name)
364  else:
365  alg = DualUseConfig.createAlgorithm (type, name)
366 
367  if DualUseConfig.useComponentAccumulator:
368  if self._algSeq :
369  self.CA.addEventAlgo(alg,self._algSeq.name)
370  else :
371  self.CA.addEventAlgo(alg)
372  else:
373  self._algSeq += alg
374  self._algorithms[name] = alg
375  self._currentAlg = alg
376  return alg
377  else :
378  if name not in self._algorithms :
379  raise Exception ('unknown algorithm requested: ' + name)
380  self._currentAlg = self._algorithms[name]
381  if self.CA and self._currentAlg != self.CA.getEventAlgo(name) :
382  raise Exception ('change to algorithm object: ' + name)
383  return self._algorithms[name]
384 
385 

◆ createPublicTool()

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

Definition at line 411 of file ConfigAccumulator.py.

411  def createPublicTool (self, type, name) :
412  '''create a new public tool and register it as the "current algorithm"'''
413  name = name + self._algPostfix
414  if self._pass == 0 :
415  if name in self._algorithms :
416  raise Exception ('duplicate public tool: ' + name)
417  tool = DualUseConfig.createPublicTool (type, name)
418  # Avoid importing AthenaCommon.AppMgr in a CA Athena job
419  # as it modifies Gaudi behaviour
420  if DualUseConfig.isAthena:
421  if DualUseConfig.useComponentAccumulator:
422  self.CA.addPublicTool(tool)
423  else:
424  # We're not, so let's remember this as a "normal" algorithm:
425  self._algSeq += tool
426  self._algorithms[name] = tool
427  self._currentAlg = tool
428  return tool
429  else :
430  if name not in self._algorithms :
431  raise Exception ('unknown public tool requested: ' + name)
432  self._currentAlg = self._algorithms[name]
433  return self._algorithms[name]
434 
435 

◆ createService()

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

Definition at line 386 of file ConfigAccumulator.py.

386  def createService (self, type, name) :
387  '''create a new service and register it as the "current algorithm"'''
388  name = name + self._algPostfix
389  if self._pass == 0 :
390  if name in self._algorithms :
391  raise Exception ('duplicate service: ' + name)
392  service = DualUseConfig.createService (type, name)
393  # Avoid importing AthenaCommon.AppMgr in a CA Athena job
394  # as it modifies Gaudi behaviour
395  if DualUseConfig.isAthena:
396  if DualUseConfig.useComponentAccumulator:
397  self.CA.addService(service)
398  else:
399  # We're not, so let's remember this as a "normal" algorithm:
400  self._algSeq += service
401  self._algorithms[name] = service
402  self._currentAlg = service
403  return service
404  else :
405  if name not in self._algorithms :
406  raise Exception ('unknown service requested: ' + name)
407  self._currentAlg = self._algorithms[name]
408  return self._algorithms[name]
409 
410 

◆ dataType()

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

Definition at line 285 of file ConfigAccumulator.py.

285  def dataType (self) :
286  """the data type we run on (data, fullsim, fastsim)"""
287  return self._dataType
288 

◆ dataYear()

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

Definition at line 309 of file ConfigAccumulator.py.

309  def dataYear(self) :
310  """for data, the corresponding year; for MC, zero"""
311  return self._flags.Input.DataYear
312 

◆ dsid()

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

Definition at line 297 of file ConfigAccumulator.py.

297  def dsid(self) :
298  """the mcChannelNumber or DSID of the sample we run on"""
299  return self._flags.Input.MCChannelNumber
300 

◆ flags()

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

Definition at line 273 of file ConfigAccumulator.py.

273  def flags (self) :
274  """Athena configuration flags"""
275  return self._flags
276 

◆ generatorInfo()

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

Definition at line 313 of file ConfigAccumulator.py.

313  def generatorInfo(self) :
314  """the dictionary of MC generators and their versions for the sample we run on"""
315  return self._flags.Input.GeneratorsInfo
316 

◆ geometry()

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

Definition at line 293 of file ConfigAccumulator.py.

293  def geometry (self) :
294  """the LHC Run period we run on"""
295  return self._flags.GeoModel.Run
296 

◆ getAlgorithm()

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

345  def getAlgorithm (self, name : str):
346  """get the algorithm with the given name
347 
348  Despite the name this will also return services and tools. It is
349  mostly meant for internal use, particularly for the property
350  overrides."""
351  name = name + self._algPostfix
352  if name not in self._algorithms:
353  return None
354  return self._algorithms[name]
355 

◆ getContainerMeta()

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

522  def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
523  """get the meta information for the given container
524 
525  This is used to pass down meta-information from the
526  configuration to the algorithms.
527  """
528  if containerName not in self._containerConfig :
529  raise Exception ("container unknown: " + containerName)
530  if metaField in self._containerConfig[containerName].meta :
531  return self._containerConfig[containerName].meta[metaField]
532  if failOnMiss :
533  raise Exception ('unknown meta-field' + metaField + ' on container ' + containerName)
534  return defaultValue
535 

◆ getEventCutFlow()

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

Definition at line 725 of file ConfigAccumulator.py.

725  def getEventCutFlow (self, selection) :
726 
727  """get the list of decorated selections for an event cutflow, corresponding to
728  key 'selection'
729  """
730  return self._eventcutflow[selection]
731 
732 

◆ getFullSelection()

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

615  def getFullSelection (self, containerName, selectionName,
616  *, skipBase = False, excludeFrom = None) :
617 
618  """get the selection string for the given selection on the given
619  container
620 
621  This can handle both individual selections or selection
622  expressions (e.g. `loose||tight`) with the later being
623  properly expanded. Either way the base selection (i.e. the
624  selection without a name) will always be applied on top.
625 
626  containerName --- the container the selection is defined on
627  selectionName --- the name of the selection, or a selection
628  expression based on multiple named selections
629  skipBase --- will avoid the base selection, and should normally
630  not be used by the end-user.
631  excludeFrom --- a set of string names of selection sources to exclude
632  e.g. to exclude OR selections from MET
633  """
634  if "." in containerName:
635  raise ValueError (f'invalid containerName argument: {containerName} , it contains a "." '
636  'which is used to indicate container+selection. You should only pass the container.')
637  if containerName not in self._containerConfig :
638  return ""
639 
640  if excludeFrom is None :
641  excludeFrom = set()
642  elif not isinstance(excludeFrom, set) :
643  raise ValueError ('invalid excludeFrom argument (need set of strings): ' + str(excludeFrom))
644 
645  # Check if this is actually a selection expression,
646  # e.g. `A||B` and if so translate it into a complex expression
647  # for the user. I'm not trying to do any complex syntax
648  # recognition, but instead just produce an expression that the
649  # C++ parser ought to be able to read.
650  if selectionName != '' and \
651  not self._selectionNameExpr.fullmatch (selectionName) :
652  result = ''
653  while selectionName != '' :
654  match = self._selectionNameExpr.match (selectionName)
655  if not match :
656  result += selectionName[0]
657  selectionName = selectionName[1:]
658  else :
659  subname = match.group(0)
660  subresult = self.getFullSelection (containerName, subname, skipBase = True, excludeFrom=excludeFrom)
661  if subresult != '' :
662  result += '(' + subresult + ')'
663  else :
664  result += 'true'
665  selectionName = selectionName[len(subname):]
666  subresult = self.getFullSelection (containerName, '', excludeFrom=excludeFrom)
667  if subresult != '' :
668  result = subresult + '&&(' + result + ')'
669  return '(' + result + ')' if result !='' else ''
670 
671  config = self._containerConfig[containerName]
672  decorations = []
673  hasSelectionName = False
674  for selection in config.selections :
675  if ((selection.name == '' and not skipBase) or selection.name == selectionName) and (selection.comesFrom not in excludeFrom) :
676  decorations += [selection.decoration]
677  if selection.name == selectionName :
678  hasSelectionName = True
679  if not hasSelectionName and selectionName != '' :
680  raise KeyError ('invalid selection name: ' + containerName + '.' + selectionName)
681  return '&&'.join (decorations)
682 
683 

◆ getOutputContainerOrigin()

def python.ConfigAccumulator.ConfigAccumulator.getOutputContainerOrigin (   self,
  outputContainerName 
)
Get the name of the actual container, for which an output is registered

Definition at line 760 of file ConfigAccumulator.py.

760  def getOutputContainerOrigin (self, outputContainerName) :
761  """Get the name of the actual container, for which an output is registered"""
762  try:
763  return self._outputContainers[outputContainerName]
764  except KeyError:
765  try:
766  return self._containerConfig[outputContainerName].name
767  except KeyError:
768  raise KeyError ("output container unknown: " + outputContainerName)
769 
770 

◆ getOutputVars()

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

Definition at line 785 of file ConfigAccumulator.py.

785  def getOutputVars (self, containerName) :
786  """get the output variables for the given container"""
787  if containerName in self._outputContainers :
788  containerName = self._outputContainers[containerName]
789  if containerName not in self._containerConfig :
790  raise KeyError ("unknown container for output: " + containerName)
791  return self._containerConfig[containerName].outputs
792 
793 

◆ getPreselection()

def python.ConfigAccumulator.ConfigAccumulator.getPreselection (   self,
  containerName,
  selectionName,
asList = False 
)
get the preselection string for the given selection on the given
container

Definition at line 594 of file ConfigAccumulator.py.

594  def getPreselection (self, containerName, selectionName, *, asList = False) :
595 
596  """get the preselection string for the given selection on the given
597  container
598  """
599  if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
600  raise ValueError ('invalid selection name: ' + selectionName)
601  if containerName not in self._containerConfig :
602  return ""
603  config = self._containerConfig[containerName]
604  decorations = []
605  for selection in config.selections :
606  if (selection.name == '' or selection.name == selectionName) and \
607  selection.preselection :
608  decorations += [selection.decoration]
609  if asList :
610  return decorations
611  else :
612  return '&&'.join (decorations)
613 
614 

◆ getSelectionCutFlow()

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

684  def getSelectionCutFlow (self, containerName, selectionName) :
685 
686  """get the individual selections as a list for producing the cutflow for
687  the given selection on the given container
688 
689  This can only handle individual selections, not selection
690  expressions (e.g. `loose||tight`).
691 
692  """
693  if containerName not in self._containerConfig :
694  return []
695 
696  # Check if this is actually a selection expression,
697  # e.g. `A||B` and if so translate it into a complex expression
698  # for the user. I'm not trying to do any complex syntax
699  # recognition, but instead just produce an expression that the
700  # C++ parser ought to be able to read.
701  if selectionName != '' and \
702  not self._selectionNameExpr.fullmatch (selectionName) :
703  raise ValueError ('not allowed to do cutflow on selection expression: ' + selectionName)
704 
705  config = self._containerConfig[containerName]
706  decorations = []
707  for selection in config.selections :
708  if (selection.name == '' or selection.name == selectionName) :
709  decorations += [selection.decoration]
710  return decorations
711 
712 

◆ getSelectionNames()

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

Definition at line 794 of file ConfigAccumulator.py.

794  def getSelectionNames (self, containerName, excludeFrom = None) :
795  """Retrieve set of unique selections defined for a given container"""
796  if containerName not in self._containerConfig :
797  return []
798  if excludeFrom is None:
799  excludeFrom = set()
800  elif not isinstance(excludeFrom, set) :
801  raise ValueError ('invalid excludeFrom argument (need set of strings): ' + str(excludeFrom))
802 
803  config = self._containerConfig[containerName]
804  # because cuts are registered individually, selection names can repeat themselves
805  # but we are interested in unique names only
806  selectionNames = set()
807  for selection in config.selections:
808  if selection.comesFrom in excludeFrom:
809  continue
810  # skip flags which should be disabled in output
811  if selection.writeToOutput:
812  selectionNames.add(selection.name)
813  return selectionNames

◆ hltSummary()

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

Definition at line 317 of file ConfigAccumulator.py.

317  def hltSummary(self) :
318  """the HLTSummary configuration to be used for the trigger decision tool"""
319  return self._hltSummary
320 

◆ isMetContainer()

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

548  def isMetContainer (self, containerName) :
549  """whether the given container is registered as a MET container
550 
551  This is mostly/exclusively used for determining whether to
552  write out the whole container or just a single MET term.
553  """
554  if containerName not in self._containerConfig :
555  raise Exception ("container unknown: " + containerName)
556  return self._containerConfig[containerName].isMet
557 
558 

◆ isPhyslite()

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

Definition at line 289 of file ConfigAccumulator.py.

289  def isPhyslite (self) :
290  """whether we run on PHYSLITE"""
291  return self._isPhyslite
292 

◆ nextPass()

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

579  def nextPass (self) :
580  """switch to the next configuration pass
581 
582  Configuration happens in two steps, with all the blocks processed
583  twice. This switches from the first to the second pass.
584  """
585  if self._pass != 0 :
586  raise Exception ("already performed final pass")
587  for name in self._containerConfig :
588  self._containerConfig[name].nextPass ()
589  self._pass = 1
590  self._currentAlg = None
591  self._outputContainers = {}
592 
593 

◆ noSystematics()

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

Definition at line 268 of file ConfigAccumulator.py.

268  def noSystematics (self) :
269  """noSystematics flag used by CommonServices block"""
270  return self._noSystematics
271 

◆ originalName()

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

508  def originalName (self, containerName) :
509  """get the "original" name of the given container
510 
511  This is mostly/exclusively used for jet containers, so that
512  subsequent configurations know which jet container they
513  operate on.
514  """
515  if containerName not in self._containerConfig :
516  raise Exception ("container unknown: " + containerName)
517  result = self._containerConfig[containerName].originalName
518  if result is None :
519  raise Exception ("no original name for: " + containerName)
520  return result
521 

◆ readName()

def python.ConfigAccumulator.ConfigAccumulator.readName (   self,
  containerName 
)
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 476 of file ConfigAccumulator.py.

476  def readName (self, containerName) :
477  """get the name of the "current copy" of the given container
478 
479  As extra copies get created during processing this will track
480  the correct name of the current copy. Optionally one can pass
481  in the name of the container before the first copy.
482  """
483  if containerName not in self._containerConfig :
484  raise Exception ("no source container for: " + containerName)
485  return self._containerConfig[containerName].currentName()
486 
487 

◆ readNameAndSelection()

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

559  def readNameAndSelection (self, containerName, *, excludeFrom = None) :
560  """get the name of the "current copy" of the given container, and the
561  selection string
562 
563  This is mostly meant for MET and OR for whom the actual object
564  selection is relevant, and which as such allow to pass in the
565  working point as "ObjectName.WorkingPoint".
566  """
567  split = containerName.split (".")
568  if len(split) == 1 :
569  objectName = split[0]
570  selectionName = ''
571  elif len(split) == 2 :
572  objectName = split[0]
573  selectionName = split[1]
574  else :
575  raise Exception ('invalid object selection name: ' + containerName)
576  return self.readName (objectName), self.getFullSelection (objectName, selectionName, excludeFrom=excludeFrom)
577 
578 

◆ runNumber()

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

Definition at line 305 of file ConfigAccumulator.py.

305  def runNumber(self) :
306  """the MC runNumber"""
307  return int(self._flags.Input.RunNumbers[0])
308 

◆ setAlgPostfix()

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

329  def setAlgPostfix (self, postfix : str) :
330  """set the current postfix to be appended to algorithm names
331 
332  Blocks should not call this directly, but rather implement the
333  instanceName method, which will be used to generate the postfix
334  automatically."""
335  # make sure the postfix matches the expected format ([_a-zA-Z0-9]*)
336  if re.compile ('^[_a-zA-Z0-9]*$').match (postfix) is None :
337  raise ValueError ('invalid algorithm postfix: ' + postfix)
338  if postfix == '' :
339  self._algPostfix = ''
340  elif postfix[0] != '_' :
341  self._algPostfix = '_' + postfix
342  else :
343  self._algPostfix = postfix
344 

◆ setContainerMeta()

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

536  def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
537  """set the meta information for the given container
538 
539  This is used to pass down meta-information from the
540  configuration to the algorithms.
541  """
542  if containerName not in self._containerConfig :
543  raise Exception ("container unknown: " + containerName)
544  if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
545  raise Exception ('duplicate meta-field' + metaField + ' on container ' + containerName)
546  self._containerConfig[containerName].meta[metaField] = value
547 

◆ setSourceName()

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

442  def setSourceName (self, containerName, sourceName,
443  *, originalName = None, isMet = False) :
444  """set the (default) name of the source/original container
445 
446  This is essentially meant to allow using e.g. the muon
447  configuration and the user not having to manually specify that
448  they want to use the Muons/AnalysisMuons container from the
449  input file.
450 
451  In addition it allows to set the original name of the
452  container (which may be different from the source name), which
453  is mostly/exclusively used for jet containers, so that
454  subsequent configurations know which jet container they
455  operate on.
456  """
457  if containerName not in self._containerConfig :
458  self._containerConfig[containerName] = ContainerConfig (containerName, sourceName, noSysSuffix = self._noSysSuffix, originalName = originalName, isMet = isMet)
459 
460 

◆ wantCopy()

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

497  def wantCopy (self, containerName) :
498  """ask whether we want/need a copy of the container
499 
500  This usually only happens if no copy of the container has been
501  made yet and the copy is needed to allow modifications, etc.
502  """
503  if containerName not in self._containerConfig :
504  raise Exception ("no source container for: " + containerName)
505  return self._containerConfig[containerName].index == 0
506 
507 

◆ writeName()

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

Definition at line 461 of file ConfigAccumulator.py.

461  def writeName (self, containerName, *, isMet=None) :
462  """register that the given container will be made and return
463  its name"""
464  if containerName not in self._containerConfig :
465  self._containerConfig[containerName] = ContainerConfig (containerName, sourceName = None, noSysSuffix = self._noSysSuffix)
466  if self._containerConfig[containerName].sourceName is not None :
467  raise Exception ("trying to write container configured for input: " + containerName)
468  if self._containerConfig[containerName].index != 0 :
469  raise Exception ("trying to write container twice: " + containerName)
470  self._containerConfig[containerName].index += 1
471  if isMet is not None :
472  self._containerConfig[containerName].isMet = isMet
473  return self._containerConfig[containerName].currentName()
474 
475 

Member Data Documentation

◆ _algorithms

python.ConfigAccumulator.ConfigAccumulator._algorithms
private

Definition at line 246 of file ConfigAccumulator.py.

◆ _algPostfix

python.ConfigAccumulator.ConfigAccumulator._algPostfix
private

Definition at line 242 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq
private

Definition at line 239 of file ConfigAccumulator.py.

◆ _containerConfig

python.ConfigAccumulator.ConfigAccumulator._containerConfig
private

Definition at line 243 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg
private

Definition at line 247 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType
private

Definition at line 232 of file ConfigAccumulator.py.

◆ _eventcutflow

python.ConfigAccumulator.ConfigAccumulator._eventcutflow
private

Definition at line 250 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags
private

Definition at line 155 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary
private

Definition at line 234 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite
private

Definition at line 233 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix
private

Definition at line 241 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics
private

Definition at line 240 of file ConfigAccumulator.py.

◆ _outputContainers

python.ConfigAccumulator.ConfigAccumulator._outputContainers
private

Definition at line 244 of file ConfigAccumulator.py.

◆ _pass

python.ConfigAccumulator.ConfigAccumulator._pass
private

Definition at line 245 of file ConfigAccumulator.py.

◆ _selectionNameExpr

python.ConfigAccumulator.ConfigAccumulator._selectionNameExpr
private

Definition at line 248 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA

Definition at line 255 of file ConfigAccumulator.py.


The documentation for this class was generated from the following file:
python.TrigDecisionToolHelpers.getRun3NavigationContainerFromInput_forAnalysisBase
def getRun3NavigationContainerFromInput_forAnalysisBase(flags)
Definition: TrigDecisionToolHelpers.py:22
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
python.DualUseConfig.createPublicTool
def createPublicTool(typeName, toolName)
Definition: DualUseConfig.py:84
python.DualUseConfig.addPrivateTool
def addPrivateTool(alg, toolName, typeName)
Definition: DualUseConfig.py:180
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
python.processes.powheg.ZZj_MiNNLO.ZZj_MiNNLO.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZj_MiNNLO.py:18
python.DualUseConfig.createService
def createService(typeName, serviceName, sequence=None)
Definition: DualUseConfig.py:127
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:808
python.DualUseConfig.createAlgorithm
def createAlgorithm(typeName, instanceName)
Definition: DualUseConfig.py:56
Generate_dsid_ranseed.dsid
dsid
Definition: Generate_dsid_ranseed.py:6
LArG4GenerateShowerLib.geometry
geometry
Definition: LArG4GenerateShowerLib.py:19
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
dqt_zlumi_pandas.campaign
campaign
Definition: dqt_zlumi_pandas.py:40
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801