ATLAS Offline Software
GenerateMenuMT.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 import importlib
4 import string
5 
6 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig import HLTMenuConfig
7 
8 from AthenaCommon.Logging import logging
9 log = logging.getLogger(__name__)
10 
11 
13  return ['Streaming','Monitor','Beamspot','Cosmic', 'Calib', 'EnhancedBias']
14 
16  return ['MinBias','Electron','Photon','Muon','Tau','Jet', 'Bjet','MET','UnconventionalTracking','HeavyIon']
17 
19  return ['Bjet', 'Egamma', 'Combined']
20 
22  return ['Streaming']
23 
25  return ['Test']
26 
28  return ['Bphysics']
29 
32 
33 
35  """
36  class to use filters for chains
37  """
38  def __init__(self,flags):
39  self.enabledSignatures = flags.Trigger.enabledSignatures if flags.hasFlag("Trigger.enabledSignatures") else []
40  self.disabledSignatures = flags.Trigger.disabledSignatures if flags.hasFlag("Trigger.disabledSignatures") else []
41  self.selectChains = flags.Trigger.selectChains if flags.hasFlag("Trigger.selectChains") else []
42  self.disableChains = flags.Trigger.disableChains if flags.hasFlag("Trigger.disableChains") else []
43  def __call__(self, signame, chain):
44  return ((signame in self.enabledSignatures and signame not in self.disabledSignatures) and \
45  (not self.selectChains or chain in self.selectChains) and chain not in self.disableChains)
46 
47 
48 class Singleton(type):
49  _instances = {}
50  def __call__(cls, *args, **kwargs):
51  if cls not in cls._instances:
52  cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
53  return cls._instances[cls]
54 
55  def clear(cls):
56  cls._instances.clear()
57 
58 
59 class GenerateMenuMT(metaclass=Singleton):
60  """Singleton class for trigger menu"""
61 
62  # Define which signatures (folders) are required for each slice
63  def getRequiredSignatures(theslice):
64  allSigs = allSignatures()
65  signatureDeps = {sig:[sig] for sig in allSigs}
66  # Special cases
67  signatureDeps.update({
68  # Bjet always requires jet
69  'Bjet': ['Bjet','Jet'],
70  # Egamma contains two signatures
71  'Egamma': ['Electron','Photon'],
72  'Combined': combinedSignatures(),
73  })
74  return set(signatureDeps[theslice]+defaultSignatures()) # always allow streamers
75 
76  def __init__(self):
77  self.chainsInMenu = {} # signature : [chains]
78 
80  self.chainDicts = []
83  self.configLengthDict = {}
84 
85  self.signaturesOverwritten = False
86  self.L1Prescales = None
87  self.HLTPrescales = None
88 
89  self.chainFilter = None
91 
92  self.sigDicts = {}
93 
94  self.chainDefModule = {} # Generate[SIG]ChainDefs module for each SIGnature
95 
96  def setChainFilter(self, f):
97  """Set chain filter for menu generation.
98 
99  This can be any callable object taking two
100  arguments for signature and chain name and returning a boolean.
101  E.g. to only generate Egamma chains:
102  menu.setChainFilter(lambda slice,chain : slice=='Egamma').
103 
104  In the special case that f is a functor with the list attributes
105  selectChains and/or disableChains, the contents will be explicitly
106  checked to be in the menu.
107  """
108  fname = f.__class__.__name__ if isinstance(f,object) else f.__name__
109  import inspect
110  if len(inspect.signature(f).parameters)!=2:
111  log.error('%s is not a valid chain filter. Function/callable needs take two arguments '
112  'for signature and chain name and return a boolean', fname)
113  else:
114  log.warning('Setting chain filter to %s', fname)
115  self.chainFilter = f
116 
117 
118  def getChainDicts(self, flags):
119 
120  def validSignature(currentSig, chainSig):
121  """Check if chain is assigned to the correct signature"""
122  reqd = GenerateMenuMT.getRequiredSignatures(currentSig)
123  isValid = chainSig.issubset( reqd )
124  log.debug("Chain signatures: %s, required signatures: %s",chainSig,reqd)
125  if not isValid:
126  log.error("Chain signatures %s not a subset of required signatures %s",set(chainSig),reqd)
127  return isValid
128 
129  from TriggerMenuMT.HLT.Config.Utility.DictFromChainName import dictFromChainName
130 
131  chainCounter = 0
132  invalid = False
133  for sig, chains in self.chainsInMenu.items():
134  for chain in chains:
135  log.debug("Now processing chain: %s from signature %s", chain, sig)
136  chainCounter += 1
137  chainDict = dictFromChainName(flags, chain)
138  chainDict['chainCounter'] = chainCounter
139  chainDict['prescale'] = 1 # set default chain prescale
140 
141  # Pick out the folder and subsignature directories to import
142  for sigfo, subsig in chainDict['sigDicts'].items():
143  if sigfo not in self.sigDicts:
144  self.sigDicts[sigfo] = subsig
145  else:
146  for ss in subsig:
147  if ss not in self.sigDicts[sigfo]:
148  self.sigDicts[sigfo].append(ss)
149 
150  self.chainDicts.append(chainDict)
151 
152  if not validSignature(sig, set(chainDict['signatures'])):
153  invalid=True
154  log.error('Chain %s assigned to signature %s but creates %s',
155  chainDict['chainName'], sig, set(chainDict['signatures']))
156  if invalid:
157  raise RuntimeError('Incorrect assignment of chains to slices -- see preceding messages.')
158 
160  """check if all the signature files can be imported and then import them"""
161 
162  for sig, subSigs in self.sigDicts.items():
163  try:
164  for ss in subSigs:
165  import_module = 'TriggerMenuMT.HLT.' + sig +'.Generate' + ss + 'ChainDefs'
166  self.chainDefModule[ss] = importlib.import_module(import_module)
167 
168  if ss not in self.availableSignatures:
169  self.availableSignatures.append(ss)
170 
171  except ImportError:
172  log.exception('Problems when importing ChainDef generating code for %s', sig)
173  import traceback
174  traceback.print_exc()
175 
176  log.info('Available signature(s) for chain generation: %s', self.availableSignatures)
177 
178  return
179 
180  def generateChains(self, flags):
181  all_chains = []
182  combinations_in_menu = []
183  alignmentGroups_to_align = set()
184  length_of_configs = {}
185 
186  nchainDicts = len(self.chainDicts)
187  notify_increment = max(int(nchainDicts / 10),1)
188  for ichainDict, chainDict in enumerate(self.chainDicts):
189  log.debug("Next: getting chain configuration for chain %s ", chainDict['chainName'])
190  if ichainDict % notify_increment==0:
191  log.info("Generating HLT chain %d / %d", ichainDict+1, nchainDicts)
192  chainConfig,lengthOfChainConfigs = self.__generateChainConfig(flags, chainDict)
193  all_chains += [(chainDict,chainConfig,lengthOfChainConfigs)]
194 
195  #update the alignment group length dictionary if we have a longer number of steps
196  #or the signature isn't registered in the dictionary yet
197  for config_length, config_grp in lengthOfChainConfigs:
198  if config_grp in length_of_configs:
199  if config_length > length_of_configs[config_grp]:
200  length_of_configs[config_grp] = config_length
201  else:
202  length_of_configs[config_grp] = config_length
203 
204  # find the chains that contain more than one alignment group, to keep track
205  # of what combinations do we need to deal with.
206  # we're using sets here so we don't end up with duplicates
207  if len(set(chainDict['alignmentGroups'])) > 1:
208  combinations_in_menu += [list(set(chainDict['alignmentGroups']))]
209  for align_group in list(set(chainDict['alignmentGroups'])):
210  alignmentGroups_to_align.update([align_group])
211 
212  self.allChainsForAlignment = all_chains
213  self.combinationsInMenu = combinations_in_menu
214  self.alignmentGroupsToAlign = alignmentGroups_to_align
215  self.configLengthDict = length_of_configs
216 
217  return
218 
219 
220  def generateAllChainConfigs(self, flags):
221  """
222  == Obtains chain configs for all chains in menu
223  """
224 
225  from TriggerMenuMT.HLT.Config.Utility.MenuAlignmentTools import MenuAlignment
226  from TriggerMenuMT.HLT.CommonSequences import EventBuildingSequences, TLABuildingSequences
227 
228  # get all chain names from menu
229  log.info("Will now get chains from the menu")
230  self.getChainsFromMenu(flags)
231 
232  # decoding of the chain name
233  log.info("Will now get chain dictionaries for each chain")
234  self.getChainDicts(flags)
235 
236  if flags.Trigger.disableCPS:
237  log.warning('Removing all CPS group because the flag Trigger.disableCPS is set')
238  for chainDict in self.chainDicts:
239  chainDict['groups'] = [g for g in chainDict['groups'] if not g.startswith('RATE:CPS_')]
240 
241  #import the necessary signatures
242  log.debug("Importing the necessary signatures")
244 
245  log.info("Will now generate the chain configuration for each chain")
246  self.generateChains(flags)
247 
248  log.info("Will now calculate the alignment parameters")
249  #dict of signature: set it belongs to
250  #e.g. {'Electron': ['Electron','Muon','Photon']}
251  menuAlignment = MenuAlignment(self.combinationsInMenu,
253  self.configLengthDict)
254  menuAlignment.analyse_combinations()
255 
256  # alignmentGroups_to_align = menuAlignment.groupsToAlign
257  # lengthOfChainConfigs = self.configLengthDict
258  # combinationsInMenu = menuAlignment.combinationsInMenu
259  # alignmentGroup_sets_to_align = menuAlignment.setsToAlign
260 
261  log.info('Aligning the following signatures: %s',sorted(menuAlignment.sets_to_align))
262  log.debug('Length of each of the alignment groups: %s',self.configLengthDict)
263 
264  chainConfigs = []
265 
266  for chainDict,chainConfig,lengthOfChainConfigs in self.allChainsForAlignment:
267 
268  # start by ordering electron, photon, muon by having e+mu, g+mu, e+g chains
269  # desired ordering: electron, photon, muon, tau, jet, met, b-jet
270 
271  # lengthOfChainConfigs is something like this: [(4, 'Photon'), (5, 'Muon')]
272  # needs to match up with the maximum number of steps in a signature in the menu (length_of_configs)
273  # start with electron! Only need to add post-steps for combined electron chains if the max length in a combined chain
274  # is greater than the number of electron steps combined chain. Assume that the max length of an electron chain occurs
275  # in a combined chain.
276 
277  log.debug("[generateAllChainConfigs] chain %s has config lengths %s and alignment groups %s", chainDict['chainName'], lengthOfChainConfigs, chainDict['alignmentGroups'])
278 
279  alignmentGroups = chainDict['alignmentGroups']
280 
281  #parallel-merged single-signature chains or single signature chains. Anything that needs no splitting!
282  if len(set(alignmentGroups)) == 1:
283  alignedChainConfig = menuAlignment.single_align(chainDict, chainConfig)
284  HLTMenuConfig.registerChain( chainDict )
285  chainConfigs.append( alignedChainConfig )
286 
287  elif len(alignmentGroups) >= 2:
288  alignedChainConfig = menuAlignment.multi_align(chainDict, chainConfig, lengthOfChainConfigs)
289  HLTMenuConfig.registerChain( chainDict )
290  chainConfigs.append( alignedChainConfig )
291 
292  else:
293  log.error("Menu can't deal with combined chains with more than two alignmentGroups at the moment. oops...")
294  raise NotImplementedError("more than three alignment groups still needs implementing in ChainMerging.py, ATR-22206")
295 
296  if not HLTMenuConfig.isChainRegistered(chainDict['chainName']):
297  log.error("Chain %s has not been registered in the menu!", chainDict['chainName'])
298  import pprint
299  pp = pprint.PrettyPrinter(indent=4, depth=8)
300  log.error('The chain dictionary is: %s', pp.pformat(chainDict))
301  raise Exception("Please fix the menu or the chain.")
302 
303  # align event building sequences
304  log.info("[generateAllChainConfigs] general alignment complete, will now align TLA chains")
305  TLABuildingSequences.alignTLASteps(chainConfigs, HLTMenuConfig.dicts())
306  log.info("[generateAllChainConfigs] general and TLA alignment complete, will now align PEB chains")
307  EventBuildingSequences.alignEventBuildingSteps(chainConfigs, HLTMenuConfig.dicts())
308 
309  log.info("[generateAllChainConfigs] all chain configurations have been generated.")
310  return chainConfigs
311 
312 
313  def getChainsFromMenu(self, flags):
314  """
315  == Returns the list of chain names that are in the menu
316  """
317  from TriggerMenuMT.HLT.Menu.MenuPrescaleConfig import MenuPrescaleConfig
318 
319  # go over the slices and put together big list of signatures requested
320  (self.L1Prescales, self.HLTPrescales, self.chainsInMenu) = MenuPrescaleConfig(HLTMenuConfig, flags)
321 
322  log.debug("Setup HLT menu with prescales: %s", self.HLTPrescales)
323 
324  # Filter chains if requested
325  if self.chainFilter is not None:
326  self.signaturesOverwritten = True
327 
328  # Verify that if the chain filter has lists of chains
329  # they are all in the menu
330  chainsToCheck = []
331  if hasattr(self.chainFilter,'selectChains'):
332  chainsToCheck += self.chainFilter.selectChains
333  if hasattr(self.chainFilter,'disableChains'):
334  chainsToCheck += self.chainFilter.disableChains
335  for chain in chainsToCheck:
336  inMenu = False
337  for signame in self.chainsInMenu:
338  if chain in [c.name for c in self.chainsInMenu[signame]]:
339  inMenu = True
340  break
341  if not inMenu:
342  raise RuntimeError(f'Request to enable/disable chain {chain} that is not in menu')
343 
344  for signame in self.chainsInMenu:
345  self.chainsInMenu[signame] = [c for c in self.chainsInMenu[signame]
346  if self.chainFilter(signame, c.name)]
347 
348  if not self.chainsInMenu:
349  log.warning("There seem to be no chains in the menu - please check")
350  elif log.isEnabledFor(logging.DEBUG):
351  import pprint
352  log.debug("The following chains were found in the menu:")
353  pprint.pprint(self.chainsInMenu)
354 
355 
356  def __generateChainConfig(self, flags, mainChainDict):
357  """
358  # Assembles the chain configuration and returns a chain object with (name, L1see and list of ChainSteps)
359  """
360 
361  from TriggerMenuMT.HLT.Config.Utility.ChainDictTools import splitInterSignatureChainDict
362  from TriggerMenuMT.HLT.Config.Utility.ComboHypoHandling import addTopoInfo, comboConfigurator, topoLegIndices
363  from TriggerMenuMT.HLT.Config.Utility.ChainMerging import mergeChainDefs
364  from TriggerMenuMT.HLT.CommonSequences import EventBuildingSequences, TLABuildingSequences
365 
366  # split the the chainDictionaries for each chain and print them in a pretty way
367  chainDicts = splitInterSignatureChainDict(mainChainDict)
368 
369  if log.isEnabledFor(logging.DEBUG):
370  import pprint
371  pp = pprint.PrettyPrinter(indent=4, depth=8)
372  log.debug('dictionary is: %s', pp.pformat(chainDicts))
373 
374  # Loop over all chainDicts and send them off to their respective assembly code
375  listOfChainConfigs = []
376  perSig_lengthOfChainConfigs = []
377 
378  for chainPartDict in chainDicts:
379  chainPartConfig = None
380  currentSig = chainPartDict['signature']
381  currentAlignGroup = None
382  if len(chainPartDict['chainParts']) == 1:
383  currentAlignGroup = chainPartDict['chainParts'][0]['alignmentGroup']
384 
385  chainName = chainPartDict['chainName']
386  log.debug('Checking chainDict for chain %s in signature %s, alignment group %s' , chainName, currentSig, currentAlignGroup)
387 
388  if currentSig in self.availableSignatures:
389  try:
390  log.debug("[__generateChainConfigs] Trying to get chain config for %s", currentSig)
391  if currentSig in ['Electron', 'Photon', 'Muon', 'Tau', 'Bphysics'] :
392  chainPartConfig, perSig_lengthOfChainConfigs = self.chainDefModule[currentSig].generateChainConfigs(flags, chainPartDict, perSig_lengthOfChainConfigs)
393  else:
394  chainPartConfig = self.chainDefModule[currentSig].generateChainConfigs(flags, chainPartDict)
395  if currentSig == 'Test' and isinstance(chainPartConfig, tuple):
396  chainPartConfig = chainPartConfig[0]
397  except Exception:
398  log.error('[__generateChainConfigs] Problems creating ChainDef for chain %s ', chainName)
399  log.error('[__generateChainConfigs] I am in chain part\n %s ', chainPartDict)
400  log.exception('[__generateChainConfigs] Full chain dictionary is\n %s ', mainChainDict)
401  raise Exception('[__generateChainConfigs] Stopping menu generation. Please investigate the exception shown above.')
402  else:
403  log.error('Chain %s cannot be generated - Signature "%s" not available', chainPartDict['chainName'], currentSig)
404  log.error('Available signature(s): %s', self.availableSignatures)
405  raise Exception('Stopping the execution. Please correct the configuration.')
406 
407  log.debug("Chain %s \n chain config: %s",chainPartDict['chainName'],chainPartConfig)
408 
409  listOfChainConfigs.append(chainPartConfig)
410  log.debug("[__generateChainConfigs] adding to the perSig_lengthOfChainConfigs list (%s, %s)",chainPartConfig.nSteps,chainPartConfig.alignmentGroups)
411  perSig_lengthOfChainConfigs.append((chainPartConfig.nSteps,chainPartConfig.alignmentGroups))
412 
413  # this will be a list of lists for inter-sig combined chains and a list with one
414  # multi-element list for intra-sig combined chains
415  # here, we flatten it accordingly (works for both cases!)
416  lengthOfChainConfigs = []
417  for nSteps, aGrps in perSig_lengthOfChainConfigs:
418  if len(nSteps) != len(aGrps):
419  log.error("Chain part has %s steps and %s alignment groups - these don't match!",nSteps,aGrps)
420  else:
421  for a,b in zip(nSteps,aGrps):
422  lengthOfChainConfigs.append((a,b))
423 
424 
425  # This part is to deal with combined chains between different signatures
426  try:
427  if len(listOfChainConfigs) == 0:
428  raise Exception('[__generateChainConfigs] No Chain Configuration found for {0}'.format(mainChainDict['chainName']))
429  else:
430  if len(listOfChainConfigs)>1:
431  log.debug("Merging strategy from dictionary: %s", mainChainDict["mergingStrategy"])
432  theChainConfig, perSig_lengthOfChainConfigs = mergeChainDefs(listOfChainConfigs, mainChainDict, perSig_lengthOfChainConfigs)
433  lengthOfChainConfigs = []
434  for nSteps, aGrps in perSig_lengthOfChainConfigs:
435  if len(nSteps) != len(aGrps):
436  log.error("Post-merged chain part has %s steps and %s alignment groups - these don't match!",nSteps,aGrps)
437  else:
438  for a,b in zip(nSteps,aGrps):
439  lengthOfChainConfigs.append((a,b))
440  else:
441  theChainConfig = listOfChainConfigs[0]
442 
443  for topoID in range(len(mainChainDict['extraComboHypos'])):
444  thetopo = mainChainDict['extraComboHypos'][topoID].strip(string.digits).rstrip(topoLegIndices)
445  theChainConfig.addTopo((comboConfigurator[thetopo],thetopo))
446 
447  # Now we know where the topos should go, we can insert them in the right steps
448  if len(theChainConfig.topoMap) > 0:
449  log.debug("Trying to add extra ComboHypoTool for %s",mainChainDict['extraComboHypos'])
450  addTopoInfo(theChainConfig,mainChainDict,listOfChainConfigs,lengthOfChainConfigs)
451  except RuntimeError:
452  log.error('[__generateChainConfigs] Problems creating ChainDef for chain %s ', chainName)
453  log.error('[__generateChainConfigs] I am in the extraComboHypos section, for %s ', mainChainDict['extraComboHypos'])
454  log.exception('[__generateChainConfigs] Full chain dictionary is\n %s ', mainChainDict)
455  raise Exception('[__generateChainConfigs] Stopping menu generation. Please investigate the exception shown above.')
456  except AttributeError:
457  raise Exception('[__generateChainConfigs] Stopping menu generation. Please investigate the exception shown above.')
458 
459  # Configure event building strategy
460  eventBuildType = mainChainDict['eventBuildType']
461  if eventBuildType:
462  try:
463  if 'PhysicsTLA' in eventBuildType:
464  log.debug("Adding TLA Step for chain %s", mainChainDict['chainName'])
465  TLABuildingSequences.addTLAStep(flags, theChainConfig, mainChainDict)
466  log.debug('Configuring event building sequence %s for chain %s', eventBuildType, mainChainDict['chainName'])
467  EventBuildingSequences.addEventBuildingSequence(flags, theChainConfig, eventBuildType, mainChainDict)
468  except TypeError as ex:
469  log.error(ex)
470  raise Exception('[__generateChainConfigs] Stopping menu generation for EventBuilding/TLA sequences. Please investigate the exception shown above.')
471 
472  log.debug('[__generateChainConfigs] lengthOfChainConfigs %s, ChainConfigs %s ', lengthOfChainConfigs, theChainConfig)
473  return theChainConfig,lengthOfChainConfigs
474 
475 
476  def resolveEmptySteps(self,chainConfigs):
477  max_steps = max([len(cc.steps) for cc in chainConfigs], default=0)
478  steps_are_empty = [True for i in range(0,max_steps)]
479  emptySteps = []
480  for cc in chainConfigs:
481  for istep, the_step in enumerate(cc.steps):
482  if not the_step.isEmpty:
483  steps_are_empty[istep] = False
484  else:
485  emptySteps.append(the_step)
486 
487  log.debug("Are there any fully empty steps? %s", steps_are_empty)
488  log.debug("The empty step(s) and associated chain(s) are: %s", emptySteps)
489  empty_step_indices = [i for i,is_empty in enumerate(steps_are_empty) if is_empty]
490 
491  if len(empty_step_indices) == 0:
492  return chainConfigs
493 
494  special_test_menu = self.chainFilter and ( getattr(self.chainFilter, "selectChains", False) or \
495  getattr(self.chainFilter, "disableChains", False) or \
496  getattr(self.chainFilter, "disabledSignatures", False) or \
497  getattr(self.chainFilter, "enabledSignatures", False) )
498 
499 
500  if len(self.availableSignatures) != 1 and not special_test_menu:
501  raise Exception("[resolveEmptySteps] Please find the reason for this empty step and resolve it / remove it from the menu: %s", emptySteps)
502 
503  log.info("Will now delete steps %s (indexed from zero)",empty_step_indices)
504 
505  for cc in chainConfigs:
506  new_steps = []
507  #only add non-empty steps to the new steps list!
508  for istep,step in enumerate(cc.steps):
509  if istep not in empty_step_indices:
510  new_steps += [step]
511  cc.steps = new_steps
512 
513  return chainConfigs
514 
515 
516 def generateMenuMT(flags):
517  """
518  == Main function to generates L1, L1Topo and HLT menu CA, using class GenerateMenuMT
519  """
520  # generate L1 menu
521  # This probably will go to TriggerConfig.triggerRunCfg
522  from TrigConfigSvc.TrigConfigSvcCfg import generateL1Menu, createL1PrescalesFileFromMenu
523  from TriggerMenuMT.HLT.Menu.MenuPrescaleConfig import MenuPrescaleConfig
524  generateL1Menu(flags)
526 
527  # generate HLT menu
528  menu = GenerateMenuMT()
529 
530  chainsToGenerate = FilterChainsToGenerate(flags)
531  menu.setChainFilter(chainsToGenerate)
532  log.debug("Filtering chains = %d", (menu.chainFilter is not None))
533  finalListOfChainConfigs = menu.generateAllChainConfigs(flags)
534  log.info("Length of FinalListOfChainConfigs %s", len(finalListOfChainConfigs))
535 
536  # Add prescales for disabling items (e.g. MC production)
537  log.info("Applying HLT prescales")
538 
539  (menu.L1Prescales, menu.HLTPrescales, menu.chainsInMenu) = MenuPrescaleConfig(HLTMenuConfig, flags)
540  from TriggerMenuMT.HLT.Menu.MenuPrescaleConfig import applyHLTPrescale
541  applyHLTPrescale(HLTMenuConfig, menu.HLTPrescales, menu.signaturesOverwritten)
542 
543  # make sure that we didn't generate any steps that are fully empty in all chains
544  # if there are empty steps, remove them
545  finalListOfChainConfigs = menu.resolveEmptySteps(finalListOfChainConfigs)
546 
547  log.debug("finalListOfChainConfig %s", finalListOfChainConfigs)
548  log.info("Making the HLT configuration tree")
549  menuAcc, CFseq_list = makeHLTTree(flags, finalListOfChainConfigs)
550  # Configure ChainFilters for ROBPrefetching
551  from TriggerJobOpts.TriggerConfigFlags import ROBPrefetching
552  if ROBPrefetching.InitialRoI in flags.Trigger.ROBPrefetchingOptions:
553  from TrigGenericAlgs.TrigGenericAlgsConfig import prefetchingInitialRoIConfig
554  menuAcc.merge( prefetchingInitialRoIConfig(flags, CFseq_list), 'HLTBeginSeq')
555 
556  log.info("Checking the L1HLTConsistency...")
557  from TriggerMenuMT.HLT.Config.Validation.CheckL1HLTConsistency import checkL1HLTConsistency
558  checkL1HLTConsistency(flags)
559 
560  log.info("Checking the Coherent Prescale assignments...")
561  from TriggerMenuMT.HLT.Config.Validation.CheckCPSGroups import checkCPSGroups
562  checkCPSGroups(HLTMenuConfig.dictsList())
563 
564  # Cleanup menu singletons to allow garbage collection (ATR-28855)
565  GenerateMenuMT.clear()
566  from TriggerMenuMT.HLT.Config import MenuComponents
567  MenuComponents._ComboHypoPool.clear()
568 
569  return menuAcc
570 
571 
572 def makeHLTTree(flags, chainConfigs):
573  """
574  Generate appropriate Control Flow Graph wiht all HLT algorithms
575  """
576  from TriggerMenuMT.HLT.Config.ControlFlow.HLTCFConfig import decisionTreeFromChains, sequenceScanner
577  from TriggerJobOpts.TriggerConfig import collectViewMakers
578  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
579  from AthenaCommon.CFElements import seqAND
580 
581  acc = ComponentAccumulator()
582  steps = seqAND('HLTAllSteps')
583  finalDecisions, CFseq_list, menuAcc = decisionTreeFromChains(flags, steps, chainConfigs, HLTMenuConfig.dictsList())
584  if log.getEffectiveLevel() <= logging.DEBUG:
585  menuAcc.printConfig()
586 
587  acc.merge(menuAcc)
588  successful_scan = sequenceScanner( steps )
589  if not successful_scan:
590  raise Exception("[makeHLTTree] At least one sequence is expected in more than one step. Check error messages and fix!")
591 
592  flatDecisions=[]
593  for step in finalDecisions:
594  flatDecisions.extend (step)
595 
596  viewMakers = collectViewMakers(steps)
597  viewMakerMap = {vm.name:vm for vm in viewMakers}
598  for vmname, vm in viewMakerMap.items():
599  log.debug(f"[makeHLTTree] {vmname} InputMakerOutputDecisions: {vm.InputMakerOutputDecisions}")
600  if vmname.endswith("_probe"):
601  try:
602  log.debug(f"Setting InputCachedViews on {vmname} to read decisions from tag leg {vmname[:-6]}: {vm.InputMakerOutputDecisions}")
603  vm.InputCachedViews = viewMakerMap[vmname[:-6]].InputMakerOutputDecisions
604  except KeyError: # We may be using a probe leg that has different reco from the tag
605  log.debug(f"Tag leg does not match probe: '{vmname[:-6]}', will not use cached views")
606 
607 
608  # generate JSON representation of the config
609  from TriggerMenuMT.HLT.Config.JSON.HLTMenuJSON import generateJSON
610  generateJSON(flags, HLTMenuConfig.dictsList(), menuAcc.getSequence("HLTAllSteps"))
611 
612  from TriggerMenuMT.HLT.Config.JSON.HLTPrescaleJSON import generatePrescaleJSON
613  generatePrescaleJSON(flags, HLTMenuConfig.dictsList())
614 
615  from TriggerMenuMT.HLT.Config.JSON.HLTMonitoringJSON import generateDefaultMonitoringJSON
616  generateDefaultMonitoringJSON(flags, HLTMenuConfig.dictsList())
617 
618  from AthenaCommon.CFElements import checkSequenceConsistency
620  return acc, CFseq_list
GenerateMenuMT.calibCosmicMonSignatures
def calibCosmicMonSignatures()
Definition: GenerateMenuMT.py:12
GenerateMenuMT.FilterChainsToGenerate.enabledSignatures
enabledSignatures
Definition: GenerateMenuMT.py:39
GenerateMenuMT.allSignatures
def allSignatures()
Definition: GenerateMenuMT.py:30
max
#define max(a, b)
Definition: cfImp.cxx:41
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
vtune_athena.format
format
Definition: vtune_athena.py:14
GenerateMenuMT.GenerateMenuMT.chainDefModule
chainDefModule
Definition: GenerateMenuMT.py:94
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
GenerateMenuMT.FilterChainsToGenerate.disabledSignatures
disabledSignatures
Definition: GenerateMenuMT.py:40
GenerateMenuMT.defaultSignatures
def defaultSignatures()
Definition: GenerateMenuMT.py:21
GenerateMenuMT.Singleton.clear
def clear(cls)
Definition: GenerateMenuMT.py:55
GenerateMenuMT.FilterChainsToGenerate
Definition: GenerateMenuMT.py:34
GenerateMenuMT.Singleton
Definition: GenerateMenuMT.py:48
GenerateMenuMT.GenerateMenuMT.__generateChainConfig
def __generateChainConfig(self, flags, mainChainDict)
Definition: GenerateMenuMT.py:356
GenerateMenuMT.FilterChainsToGenerate.__init__
def __init__(self, flags)
Definition: GenerateMenuMT.py:38
python.TrigConfigSvcCfg.createL1PrescalesFileFromMenu
def createL1PrescalesFileFromMenu(flags)
Definition: TrigConfigSvcCfg.py:165
GenerateMenuMT.GenerateMenuMT.chainFilter
chainFilter
Definition: GenerateMenuMT.py:89
GenerateMenuMT.GenerateMenuMT.configLengthDict
configLengthDict
Definition: GenerateMenuMT.py:83
python.TrigConfigSvcCfg.generateL1Menu
def generateL1Menu(flags)
Definition: TrigConfigSvcCfg.py:184
GenerateMenuMT.makeHLTTree
def makeHLTTree(flags, chainConfigs)
Definition: GenerateMenuMT.py:572
CheckL1HLTConsistency.checkL1HLTConsistency
def checkL1HLTConsistency(flags)
Definition: CheckL1HLTConsistency.py:48
GenerateMenuMT.GenerateMenuMT.setChainFilter
def setChainFilter(self, f)
Definition: GenerateMenuMT.py:96
DictFromChainName.dictFromChainName
def dictFromChainName(flags, chainInfo)
Definition: DictFromChainName.py:626
HLTCFConfig.decisionTreeFromChains
def decisionTreeFromChains(flags, HLTNode, chains, allDicts)
Definition: HLTCFConfig.py:166
ComboHypoHandling.addTopoInfo
def addTopoInfo(theChainConfig, mainChainDict, listOfChainDefs, lengthOfChainConfigs)
Definition: ComboHypoHandling.py:213
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
GenerateMenuMT.bphysicsSignatures
def bphysicsSignatures()
Definition: GenerateMenuMT.py:27
GenerateMenuMT.GenerateMenuMT.getChainDicts
def getChainDicts(self, flags)
Definition: GenerateMenuMT.py:118
GenerateMenuMT.GenerateMenuMT.allChainsForAlignment
allChainsForAlignment
Definition: GenerateMenuMT.py:79
GenerateMenuMT.GenerateMenuMT.availableSignatures
availableSignatures
Definition: GenerateMenuMT.py:90
python.CFElements.seqAND
def seqAND(name, subs=[])
Definition: CFElements.py:25
HLTCFConfig.sequenceScanner
def sequenceScanner(HLTNode)
Definition: HLTCFConfig.py:110
GenerateMenuMT.Singleton.__call__
def __call__(cls, *args, **kwargs)
Definition: GenerateMenuMT.py:50
GenerateMenuMT.GenerateMenuMT.HLTPrescales
HLTPrescales
Definition: GenerateMenuMT.py:87
GenerateMenuMT.combinedSignatures
def combinedSignatures()
Definition: GenerateMenuMT.py:15
python.CFElements.checkSequenceConsistency
def checkSequenceConsistency(seq)
Definition: CFElements.py:69
GenerateMenuMT.GenerateMenuMT.chainDicts
chainDicts
Definition: GenerateMenuMT.py:80
GenerateMenuMT.GenerateMenuMT.chainsInMenu
chainsInMenu
Definition: GenerateMenuMT.py:77
GenerateMenuMT.FilterChainsToGenerate.selectChains
selectChains
Definition: GenerateMenuMT.py:41
GenerateMenuMT.GenerateMenuMT.resolveEmptySteps
def resolveEmptySteps(self, chainConfigs)
Definition: GenerateMenuMT.py:476
GenerateMenuMT.GenerateMenuMT
Definition: GenerateMenuMT.py:59
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
GenerateMenuMT.GenerateMenuMT.__init__
def __init__(self)
Definition: GenerateMenuMT.py:76
GenerateMenuMT.generateMenuMT
def generateMenuMT(flags)
Definition: GenerateMenuMT.py:516
GenerateMenuMT.GenerateMenuMT.combinationsInMenu
combinationsInMenu
Definition: GenerateMenuMT.py:81
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.HLT.Menu.MenuPrescaleConfig.applyHLTPrescale
def applyHLTPrescale(triggerPythonConfig, HLTPrescale, ignoreUnknownChains=False)
Definition: MenuPrescaleConfig.py:82
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
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:224
GenerateMenuMT.GenerateMenuMT.sigDicts
sigDicts
Definition: GenerateMenuMT.py:92
GenerateMenuMT.GenerateMenuMT.getRequiredSignatures
def getRequiredSignatures(theslice)
Definition: GenerateMenuMT.py:63
python.HLT.Menu.MenuPrescaleConfig.MenuPrescaleConfig
def MenuPrescaleConfig(hltMenuConfig, flags)
Definition: MenuPrescaleConfig.py:9
GenerateMenuMT.Singleton._instances
_instances
Definition: GenerateMenuMT.py:49
GenerateMenuMT.GenerateMenuMT.generateChains
def generateChains(self, flags)
Definition: GenerateMenuMT.py:180
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
GenerateMenuMT.jointSignatures
def jointSignatures()
Definition: GenerateMenuMT.py:18
python.TriggerConfig.collectViewMakers
def collectViewMakers(steps)
Definition: TriggerConfig.py:66
GenerateMenuMT.GenerateMenuMT.signaturesOverwritten
signaturesOverwritten
Definition: GenerateMenuMT.py:85
GenerateMenuMT.GenerateMenuMT.importSignaturesToGenerate
def importSignaturesToGenerate(self)
Definition: GenerateMenuMT.py:159
HLTMonitoringJSON.generateDefaultMonitoringJSON
def generateDefaultMonitoringJSON(flags, chainDicts)
Definition: HLTMonitoringJSON.py:21
ChainMerging.mergeChainDefs
def mergeChainDefs(listOfChainDefs, chainDict, perSig_lengthOfChainConfigs=None)
Definition: ChainMerging.py:15
python.TrigGenericAlgsConfig.prefetchingInitialRoIConfig
def prefetchingInitialRoIConfig(flags, CFseq_list)
Definition: TrigGenericAlgsConfig.py:159
GenerateMenuMT.GenerateMenuMT.L1Prescales
L1Prescales
Definition: GenerateMenuMT.py:86
GenerateMenuMT.GenerateMenuMT.getChainsFromMenu
def getChainsFromMenu(self, flags)
Definition: GenerateMenuMT.py:313
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
HLTMenuJSON.generateJSON
def generateJSON(flags, chainDicts, HLTAllSteps)
Definition: HLTMenuJSON.py:83
GenerateMenuMT.FilterChainsToGenerate.__call__
def __call__(self, signame, chain)
Definition: GenerateMenuMT.py:43
GenerateMenuMT.FilterChainsToGenerate.disableChains
disableChains
Definition: GenerateMenuMT.py:42
pickleTool.object
object
Definition: pickleTool.py:30
ChainDictTools.splitInterSignatureChainDict
def splitInterSignatureChainDict(chainDict)
Definition: ChainDictTools.py:9
CheckCPSGroups.checkCPSGroups
def checkCPSGroups(chainDicts)
Definition: CheckCPSGroups.py:19
GenerateMenuMT.GenerateMenuMT.alignmentGroupsToAlign
alignmentGroupsToAlign
Definition: GenerateMenuMT.py:82
GenerateMenuMT.GenerateMenuMT.generateAllChainConfigs
def generateAllChainConfigs(self, flags)
Definition: GenerateMenuMT.py:220
python.HLT.Bjet.GenerateBjetChainDefs.generateChainConfigs
def generateChainConfigs(flags, chainDict)
Definition: GenerateBjetChainDefs.py:13
GenerateMenuMT.testSignatures
def testSignatures()
Definition: GenerateMenuMT.py:24
HLTPrescaleJSON.generatePrescaleJSON
def generatePrescaleJSON(flags, chainDicts)
Definition: HLTPrescaleJSON.py:8