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

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

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

706  def addEventCutFlow (self, selection, decorations) :
707 
708  """register a new event cutflow, adding it to the dictionary with key 'selection'
709  and value 'decorations', a list of decorated selections
710  """
711  if self._pass == 0:
712  if selection in self._eventcutflow.keys():
713  raise ValueError ('the event cutflow dictionary already contains an entry ' + selection)
714  else:
715  self._eventcutflow[selection] = decorations
716 
717 

◆ addOutputContainer()

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

Definition at line 739 of file ConfigAccumulator.py.

739  def addOutputContainer (self, containerName, outputContainerName) :
740  """register a copy of a container used in outputs"""
741  if containerName not in self._containerConfig :
742  raise KeyError ("container unknown: " + containerName)
743  if outputContainerName in self._outputContainers :
744  raise KeyError ("duplicate output container name: " + outputContainerName)
745  self._outputContainers[outputContainerName] = containerName
746 
747 

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

764  def addOutputVar (self, containerName, variableName, outputName,
765  *, noSys=False, enabled=True) :
766  """add an output variable for the given container to the output
767  """
768 
769  if containerName not in self._containerConfig :
770  raise KeyError ("container unknown: " + containerName)
771  baseConfig = self._containerConfig[containerName].outputs
772  if outputName in baseConfig :
773  raise KeyError ("duplicate output variable name: " + outputName)
774  config = OutputConfig (containerName, variableName, noSys=noSys, enabled=enabled)
775  baseConfig[outputName] = config
776 
777 

◆ addPrivateTool()

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

Definition at line 429 of file ConfigAccumulator.py.

429  def addPrivateTool (self, propertyName, toolType) :
430  """add a private tool to the current algorithm"""
431  if self._pass == 0 :
432  DualUseConfig.addPrivateTool (self._currentAlg, propertyName, toolType)
433 
434 

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

726  def addSelection (self, containerName, selectionName, decoration,
727  **kwargs) :
728  """add another selection decoration to the selection of the given
729  name for the given container"""
730  if selectionName != '' and not self._selectionNameExpr.fullmatch (selectionName) :
731  raise ValueError ('invalid selection name: ' + selectionName)
732  if containerName not in self._containerConfig :
733  self._containerConfig[containerName] = ContainerConfig (containerName, containerName, noSysSuffix=self._noSysSuffix)
734  config = self._containerConfig[containerName]
735  selection = SelectionConfig (selectionName, decoration, **kwargs)
736  config.selections.append (selection)
737 
738 

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

314  def algPostfix (self) :
315  """the current postfix to be appended to algorithm names
316 
317  Blocks should not call this directly, but rather implement the
318  instanceName method, which will be used to generate the postfix
319  automatically."""
320  return self._algPostfix
321 

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

271  def autoconfigFlags (self) :
272  """Athena configuration flags
273 
274  This is a backward compatibility version of the flags property,
275  which is preferred."""
276  return self._flags
277 

◆ campaign()

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

Definition at line 294 of file ConfigAccumulator.py.

294  def campaign(self) :
295  """the MC campaign we run on"""
296  return self._flags.Input.MCCampaign
297 

◆ checkOutputContainer()

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

Definition at line 748 of file ConfigAccumulator.py.

748  def checkOutputContainer (self, containerName) :
749  """check whether a given container has been registered in outputs"""
750  return containerName in self._outputContainers.values()
751 
752 

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

481  def copyName (self, containerName) :
482  """register that a copy of the container will be made and return
483  its name"""
484  if containerName not in self._containerConfig :
485  raise Exception ("unknown container: " + containerName)
486  self._containerConfig[containerName].index += 1
487  return self._containerConfig[containerName].currentName()
488 
489 

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

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

◆ createPublicTool()

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

Definition at line 404 of file ConfigAccumulator.py.

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

◆ createService()

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

Definition at line 379 of file ConfigAccumulator.py.

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

◆ dataType()

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

Definition at line 278 of file ConfigAccumulator.py.

278  def dataType (self) :
279  """the data type we run on (data, fullsim, fastsim)"""
280  return self._dataType
281 

◆ dataYear()

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

Definition at line 302 of file ConfigAccumulator.py.

302  def dataYear(self) :
303  """for data, the corresponding year; for MC, zero"""
304  return self._flags.Input.DataYear
305 

◆ dsid()

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

Definition at line 290 of file ConfigAccumulator.py.

290  def dsid(self) :
291  """the mcChannelNumber or DSID of the sample we run on"""
292  return self._flags.Input.MCChannelNumber
293 

◆ flags()

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

Definition at line 266 of file ConfigAccumulator.py.

266  def flags (self) :
267  """Athena configuration flags"""
268  return self._flags
269 

◆ generatorInfo()

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

Definition at line 306 of file ConfigAccumulator.py.

306  def generatorInfo(self) :
307  """the dictionary of MC generators and their versions for the sample we run on"""
308  return self._flags.Input.GeneratorsInfo
309 

◆ geometry()

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

Definition at line 286 of file ConfigAccumulator.py.

286  def geometry (self) :
287  """the LHC Run period we run on"""
288  return self._flags.GeoModel.Run
289 

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

338  def getAlgorithm (self, name : str):
339  """get the algorithm with the given name
340 
341  Despite the name this will also return services and tools. It is
342  mostly meant for internal use, particularly for the property
343  overrides."""
344  name = name + self._algPostfix
345  if name not in self._algorithms:
346  return None
347  return self._algorithms[name]
348 

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

515  def getContainerMeta (self, containerName, metaField, defaultValue=None, *, failOnMiss=False) :
516  """get the meta information for the given container
517 
518  This is used to pass down meta-information from the
519  configuration to the algorithms.
520  """
521  if containerName not in self._containerConfig :
522  raise Exception ("container unknown: " + containerName)
523  if metaField in self._containerConfig[containerName].meta :
524  return self._containerConfig[containerName].meta[metaField]
525  if failOnMiss :
526  raise Exception ('unknown meta-field' + metaField + ' on container ' + containerName)
527  return defaultValue
528 

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

718  def getEventCutFlow (self, selection) :
719 
720  """get the list of decorated selections for an event cutflow, corresponding to
721  key 'selection'
722  """
723  return self._eventcutflow[selection]
724 
725 

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

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

◆ getOutputContainerOrigin()

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

Definition at line 753 of file ConfigAccumulator.py.

753  def getOutputContainerOrigin (self, outputContainerName) :
754  """Get the name of the actual container, for which an output is registered"""
755  try:
756  return self._outputContainers[outputContainerName]
757  except KeyError:
758  try:
759  return self._containerConfig[outputContainerName].name
760  except KeyError:
761  raise KeyError ("output container unknown: " + outputContainerName)
762 
763 

◆ getOutputVars()

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

Definition at line 778 of file ConfigAccumulator.py.

778  def getOutputVars (self, containerName) :
779  """get the output variables for the given container"""
780  if containerName in self._outputContainers :
781  containerName = self._outputContainers[containerName]
782  if containerName not in self._containerConfig :
783  raise KeyError ("unknown container for output: " + containerName)
784  return self._containerConfig[containerName].outputs
785 
786 

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

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

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

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

◆ getSelectionNames()

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

Definition at line 787 of file ConfigAccumulator.py.

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

◆ hltSummary()

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

Definition at line 310 of file ConfigAccumulator.py.

310  def hltSummary(self) :
311  """the HLTSummary configuration to be used for the trigger decision tool"""
312  return self._hltSummary
313 

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

541  def isMetContainer (self, containerName) :
542  """whether the given container is registered as a MET container
543 
544  This is mostly/exclusively used for determining whether to
545  write out the whole container or just a single MET term.
546  """
547  if containerName not in self._containerConfig :
548  raise Exception ("container unknown: " + containerName)
549  return self._containerConfig[containerName].isMet
550 
551 

◆ isPhyslite()

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

Definition at line 282 of file ConfigAccumulator.py.

282  def isPhyslite (self) :
283  """whether we run on PHYSLITE"""
284  return self._isPhyslite
285 

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

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

◆ noSystematics()

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

Definition at line 261 of file ConfigAccumulator.py.

261  def noSystematics (self) :
262  """noSystematics flag used by CommonServices block"""
263  return self._noSystematics
264 

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

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

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

469  def readName (self, containerName) :
470  """get the name of the "current copy" of the given container
471 
472  As extra copies get created during processing this will track
473  the correct name of the current copy. Optionally one can pass
474  in the name of the container before the first copy.
475  """
476  if containerName not in self._containerConfig :
477  raise Exception ("no source container for: " + containerName)
478  return self._containerConfig[containerName].currentName()
479 
480 

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

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

◆ runNumber()

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

Definition at line 298 of file ConfigAccumulator.py.

298  def runNumber(self) :
299  """the MC runNumber"""
300  return int(self._flags.Input.RunNumbers[0])
301 

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

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

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

529  def setContainerMeta (self, containerName, metaField, value, *, allowOverwrite=False) :
530  """set the meta information for the given container
531 
532  This is used to pass down meta-information from the
533  configuration to the algorithms.
534  """
535  if containerName not in self._containerConfig :
536  raise Exception ("container unknown: " + containerName)
537  if not allowOverwrite and metaField in self._containerConfig[containerName].meta :
538  raise Exception ('duplicate meta-field' + metaField + ' on container ' + containerName)
539  self._containerConfig[containerName].meta[metaField] = value
540 

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

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

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

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

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

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

Member Data Documentation

◆ _algorithms

python.ConfigAccumulator.ConfigAccumulator._algorithms
private

Definition at line 239 of file ConfigAccumulator.py.

◆ _algPostfix

python.ConfigAccumulator.ConfigAccumulator._algPostfix
private

Definition at line 235 of file ConfigAccumulator.py.

◆ _algSeq

python.ConfigAccumulator.ConfigAccumulator._algSeq
private

Definition at line 232 of file ConfigAccumulator.py.

◆ _containerConfig

python.ConfigAccumulator.ConfigAccumulator._containerConfig
private

Definition at line 236 of file ConfigAccumulator.py.

◆ _currentAlg

python.ConfigAccumulator.ConfigAccumulator._currentAlg
private

Definition at line 240 of file ConfigAccumulator.py.

◆ _dataType

python.ConfigAccumulator.ConfigAccumulator._dataType
private

Definition at line 225 of file ConfigAccumulator.py.

◆ _eventcutflow

python.ConfigAccumulator.ConfigAccumulator._eventcutflow
private

Definition at line 243 of file ConfigAccumulator.py.

◆ _flags

python.ConfigAccumulator.ConfigAccumulator._flags
private

Definition at line 148 of file ConfigAccumulator.py.

◆ _hltSummary

python.ConfigAccumulator.ConfigAccumulator._hltSummary
private

Definition at line 227 of file ConfigAccumulator.py.

◆ _isPhyslite

python.ConfigAccumulator.ConfigAccumulator._isPhyslite
private

Definition at line 226 of file ConfigAccumulator.py.

◆ _noSysSuffix

python.ConfigAccumulator.ConfigAccumulator._noSysSuffix
private

Definition at line 234 of file ConfigAccumulator.py.

◆ _noSystematics

python.ConfigAccumulator.ConfigAccumulator._noSystematics
private

Definition at line 233 of file ConfigAccumulator.py.

◆ _outputContainers

python.ConfigAccumulator.ConfigAccumulator._outputContainers
private

Definition at line 237 of file ConfigAccumulator.py.

◆ _pass

python.ConfigAccumulator.ConfigAccumulator._pass
private

Definition at line 238 of file ConfigAccumulator.py.

◆ _selectionNameExpr

python.ConfigAccumulator.ConfigAccumulator._selectionNameExpr
private

Definition at line 241 of file ConfigAccumulator.py.

◆ CA

python.ConfigAccumulator.ConfigAccumulator.CA

Definition at line 248 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.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
python.processes.powheg.ZZ.ZZ.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZ.py:18
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