ATLAS Offline Software
Functions | Variables
DictFromChainName Namespace Reference

Functions

def getOverallL1item (flags, chainName)
 
def getL1item (flags, chainName)
 
def getAllThresholdsFromItem (item)
 
def getUniqueThresholdsFromItem (item)
 
def getEBPartFromParts (chainName, chainParts)
 
def getChainThresholdFromName (chainParts, signature)
 
def getChainMultFromDict (chainDict)
 
def verifyExplicitL1Thresholds (chainname, chainparts, L1thresholds)
 
def unifyJetRecoParts (chainParts)
 
def analyseChainName (chainName, L1thresholds, L1item)
 
def flattenChainGroups (A)
 
def checkChainStream (myStream)
 
def dictFromChainName (flags, chainInfo)
 
def main ()
 

Variables

 __author__
 
 __version__
 
 __doc__
 
 log
 
 matchL1
 

Function Documentation

◆ analyseChainName()

def DictFromChainName.analyseChainName (   chainName,
  L1thresholds,
  L1item 
)
Function to obtain the chain configuration dictionary from the short name by parsing its
components and finding the corresponding properties which are defined in SignatureDicts.
The naming convention is defined in https://twiki.cern.ch/twiki/bin/view/Atlas/TriggerNamingRun2
and https://twiki.cern.ch/twiki/bin/view/Atlas/TriggerNamingRun3

Definition at line 201 of file DictFromChainName.py.

201 def analyseChainName(chainName, L1thresholds, L1item):
202  """
203  Function to obtain the chain configuration dictionary from the short name by parsing its
204  components and finding the corresponding properties which are defined in SignatureDicts.
205  The naming convention is defined in https://twiki.cern.ch/twiki/bin/view/Atlas/TriggerNamingRun2
206  and https://twiki.cern.ch/twiki/bin/view/Atlas/TriggerNamingRun3
207  """
208 
209  # ---- dictionary with all chain properties ----
210  from TriggerMenuMT.HLT.Menu.SignatureDicts import ChainDictTemplate
211  from TriggerMenuMT.HLT.Menu.SignatureDicts import getSignatureInformation
212  from TriggerMenuMT.HLT.Jet.JetRecoCommon import etaRangeAbbrev
213  genchainDict = deepcopy(ChainDictTemplate)
214  genchainDict['chainName'] = chainName
215 
216  # ---- remove the L1 item from the name ----
217  hltChainName = chainName.rsplit("_L1",1)[0]
218 
219  # ---- check for HLT_HLT in name ---
220  if 'HLT_HLT' in hltChainName:
221  log.error("%s is incorrect, please fix the HLT_HLT part", hltChainName)
222  raise RuntimeError("[analyseChainName] chain name contains HLT_HLT, please fix in corresponding menu where this chain is included")
223 
224  # ---- specific chain part information ----
225  allChainProperties=[]
226  cparts = hltChainName.split("_")
227  if 'HLT' in hltChainName:
228  cparts.remove('HLT')
229 
230  # ---- handle EB directive ----
231  genchainDict['eventBuildType'] = getEBPartFromParts( chainName, cparts )
232  if genchainDict['eventBuildType']:
233  cparts.remove( genchainDict['eventBuildType'] )
234 
235  hltChainNameShort = '_'.join(cparts)
236 
237  # ---- identify the topo algorithm and add to genchainDict -----
238  from TriggerMenuMT.HLT.Menu.SignatureDicts import AllowedTopos, AllowedTopos_comb, AllowedTopos_Bphysics_topoVariant, AllowedTopos_Bphysics_topoExtra
239  topo = ''
240  topos=[]
241  extraComboHypos = []
242  bphys_topoVariant=[]
243  bphys_topoExtra = []
244  bphysTopos = False
245  toposIndexed={}
246  topoindex = -5
247  for cindex, cpart in enumerate(cparts):
248  #should make this if...elif...?
249  if cpart in AllowedTopos:
250  log.debug('" %s" is in this part of the name %s -> topo alg', AllowedTopos, cpart)
251  topo = cpart
252  topoindex = cindex
253  toposIndexed.update({topo : topoindex})
254  hltChainNameShort=hltChainNameShort.replace('_'+cpart, '')
255  topos.append(topo)
256  elif cpart in AllowedTopos_Bphysics_topoVariant:
257  log.debug('[analyseChainName] chain part %s is a BLS topo variant, adding to bphys_topoVariant', cpart)
258  bphys_topoVariant.append(cpart)
259  toposIndexed.update({cpart : cindex})
260  bphysTopos = True
261  elif cpart in AllowedTopos_Bphysics_topoExtra:
262  log.debug('[analyseChainName] chain part %s is a BLS extra topo hypo, adding to bphys_topoExtra', cpart)
263  bphys_topoExtra.append(cpart)
264  toposIndexed.update({cpart : cindex})
265  bphysTopos = True
266  else:
267  log.debug('[analyseChainName] chain part %s is not a general topo, BLS extra or variant topo hypo, checking comb topos next', cpart)
268  if cpart in AllowedTopos_comb:
269  log.debug('[analyseChainName] chain part %s is a combined topo hypo, adding to extraComboHypo', cpart)
270  toposIndexed.update({cpart : cindex})
271  extraComboHypos.append(cpart)
272 
273  genchainDict['topo'] = topos
274  genchainDict['extraComboHypos'] = extraComboHypos
275 
276  if bphysTopos is True:
277  genchainDict['topoVariant'] = bphys_topoVariant
278  genchainDict['topoExtra'] = bphys_topoExtra
279 
280  # remove the parts that have been already identified
281  for t, i in enumerate(toposIndexed):
282  if (t in cparts):
283  log.debug('topo %s with index %s is going to be deleted from chain parts', t, i)
284  del cparts[i]
285 
286 
287  # ---- Find the signature defining patterns ----
288  # ---- and write them out in dictionary ----
289  # ---- expected format: <Multiplicity(int)><TriggerType(str)>
290  # <Threshold(int)><isolation,...(str|str+int)> ----
291  # EXCEPT FOR CHAINS ...
292  from TriggerMenuMT.HLT.Menu.SignatureDicts import getBasePattern
293  pattern = getBasePattern()
294  mdicts=[]
295  multichainindex=[]
296 
297 
298  # ---- obtain dictionary parts for signature defining patterns ----
299  from TriggerMenuMT.HLT.Menu.SignatureDicts import getSignatureNameFromToken, AllowedCosmicChainIdentifiers, \
300  AllowedCalibChainIdentifiers, AllowedMonitorChainIdentifiers, AllowedBeamspotChainIdentifiers
301 
302  from TriggerMenuMT.HLT.Config.Utility.MenuAlignmentTools import get_alignment_group_from_pattern as getAlignmentGroupFromPattern
303 
304  def buildDict(signature, sigToken ):
305  groupdict = {'signature': signature, 'threshold': '', 'multiplicity': '',
306  'trigType': sigToken, 'extra': ''}
307  mdicts.append( groupdict )
308 
309  for cpart in cparts:
310 
311  log.debug("Looping over chain part: %s", cpart)
312  m = pattern.match(cpart)
313 
314  if m:
315  log.debug("Pattern found in this string: %s", cpart)
316  groupdict = m.groupdict()
317 
318  multiChainIndices = [i for i in range(len(hltChainNameShort)) if ( hltChainNameShort.startswith(cpart, i) ) ]
319  log.debug("MultiChainIndices: %s", multiChainIndices)
320  for theMultiChainIndex in multiChainIndices:
321  # this check is necessary for the bjet chains, example: j45_bloose_3j45
322  # j45 would be found in [0, 13], and 3j45 in [12]
323  # so need to make sure the multiplicities are considered here!
324  if (theMultiChainIndex != 0) & (hltChainNameShort[theMultiChainIndex-1] != '_'):
325  continue
326 
327  if theMultiChainIndex not in multichainindex:
328  multichainindex.append(theMultiChainIndex)
329 
330  log.debug("HLTChainName: %s", hltChainName)
331  log.debug("HLTChainNameShort: %s", hltChainNameShort)
332  log.debug("cpart: %s", cpart)
333  log.debug("groupdict: %s", groupdict)
334  log.debug("multichainindex: %s", multichainindex)
335 
336  sName = getSignatureNameFromToken(cpart)
337 
338  groupdict['signature'] = sName
339  log.debug("groupdict['signature']: %s",groupdict['signature'])
340 
341  mdicts.append(groupdict)
342 
343  elif cpart =='noalg':
344  multichainindex.append(hltChainNameShort.index(cpart))
345  buildDict( 'Streaming', 'streamer')
346  break # stop loop here so that further parts like noalg_idmon are discarded, this allows have copies with different output streams and prescales. Caveat: all noalg chains go into the Streaming slice
347  elif cpart =='acceptedevts':
348  multichainindex.append(hltChainNameShort.index(cpart))
349  buildDict( 'Calib', 'calib')
350  break # stop loop here so that further parts like acceptedevts_larnoiseburst are discarded. They are only used to define different prescales
351  else:
352  for chainCategory in [(['mb'], 'MinBias', 'mb'),
353  (['hi'], 'HeavyIon', 'mb'),
354  (AllowedCosmicChainIdentifiers, 'Cosmic', 'cosmic'),
355  (AllowedCalibChainIdentifiers, 'Calib', 'calib'),
356  (AllowedMonitorChainIdentifiers, 'Monitor', 'calib'),
357  (AllowedBeamspotChainIdentifiers, 'Beamspot', 'beamspot'),
358  (['eb'], 'EnhancedBias', 'eb')]:
359  if cpart in chainCategory[0]:
360  log.debug('Doing chain type %s', chainCategory[1])
361  multichainindex.append(hltChainNameShort.index(cpart))
362  buildDict(chainCategory[1], chainCategory[2])
363 
364 
365  # If multiple parts exist, split the string and analyse each
366  # part depending on the signature it belongs to
367  multichainparts=[]
368  multichainindex = sorted(multichainindex, key=int)
369  cN = deepcopy(hltChainNameShort)
370  for i in reversed(multichainindex):
371  if i!=0:
372  log.debug('Appending to multichainparts (i!=0): %s', hltChainNameShort[i:len(cN)])
373 
374  multichainparts.append(hltChainNameShort[i:len(cN)])
375  cN = cN[0:i-1]
376  else:
377  log.debug('Appending to multichainparts: %s', hltChainNameShort[i:len(cN)])
378  multichainparts.append(cN)
379  log.debug("multichainparts: %s",multichainparts)
380 
381  # build the chainProperties dictionary for each part of the chain
382  # add it to a allChainProperties
383  multichainparts.reverse()
384  log.debug('multichainparts after reverse: %s', multichainparts)
385 
386  # verify if the L1 setup is consistent with the chain
387  # sizes of seeds matter
388  if len(L1thresholds) != 0:
389  assert len(L1thresholds) == len(multichainparts), 'ERROR IN CHAIN {} definition, l1 thresholds specified {} have different length than chain parts {}'\
390  .format(chainName, str(L1thresholds), str(multichainparts) )
391 
392  # tmp removed this check since the L1seeds depend on sym or asym cases
393  # if len(L1thresholds) == 0:
394  # getAllThresholdsFromItem, getUniqueThresholdsFromItem
395  # assert len( getAllThresholdsFromItem( L1item )) == len(multichainparts), 'ERROR IN CHAIN {} definition, l1 thresholds extracted from the L1 item name {} have different length than chain parts {}, set L1 thresholds ChainProp'\
396  # .format( chainName, str( getAllThresholdsFromItem( L1item ) ), str(multichainparts))
397 
398  # check the case when _L1 appears more than once in the name
399  if chainName.count("_L1") > 1:
400  verifyExplicitL1Thresholds(chainName,multichainparts,L1thresholds)
401 
402  for chainindex, chainparts in enumerate(multichainparts):
403  chainProperties = {} #will contain properties for one part of chain if multiple parts
404  chainpartsNoL1 = chainparts.rsplit('_L1',1)[0] if 'L1' in chainparts else chainparts
405 
406  if len(L1thresholds) != 0:
407  chainProperties['L1threshold'] = L1thresholds[chainindex]
408  else:
409  __th = getAllThresholdsFromItem ( L1item )
410  assert chainindex < len(__th), "In defintion of the chain {chainName} there is not enough thresholds to be used, index: {chainindex} >= number of thresholds, thresholds are: {__th}"
411  chainProperties['L1threshold'] = __th[chainindex] #replced getUniqueThresholdsFromItem
412 
413  parts=chainpartsNoL1.split('_')
414  log.debug("[analyseChainName] chain parts w/o L1 are %s", parts)
415  if None in parts:
416  log.error("[analyseChainName] chainpartsNoL1 -> parts: %s -> %s", chainpartsNoL1, parts)
417  raise Exception("[analyseChainName] parts contains None, please identify how this is happening")
418  parts=list(filter(None,parts))
419  log.debug("[analyseChainName] chainpartsNoL1 %s, parts %s", chainpartsNoL1, parts)
420 
421  # --- check for duplicate strings in chain part name ---
422  duplicateParts = ([item for item, count in collections.Counter(parts).items() if count > 1])
423  log.debug("[analyseChainName] chainpartsNoL1 %s contains duplicate strings %s", chainpartsNoL1, duplicateParts)
424  if duplicateParts:
425  log.error("[analyseChainName] chain %s has duplicate strings %s, please fix!!", chainName, duplicateParts)
426  raise RuntimeError("[analyseChainName] Check the chain name, there are duplicate configurations: %s", duplicateParts)
427 
428  chainProperties['trigType']=mdicts[chainindex]['trigType']
429  if 'extra' in chainProperties:
430  raise RuntimeError("[analyseChainName] Overwrote 'extra' value, only one supported!")
431  else:
432  chainProperties['extra']=mdicts[chainindex]['extra']
433  multiplicity = mdicts[chainindex]['multiplicity'] if not mdicts[chainindex]['multiplicity'] == '' else '1'
434  chainProperties['multiplicity'] = multiplicity
435  chainProperties['threshold']=mdicts[chainindex]['threshold']
436  chainProperties['signature']=mdicts[chainindex]['signature']
437 
438  # if we have a L1 topo in a multi-chain then we want to remove it from the chain name
439  # but only if it's the same as the L1item_main; otherwise it belongs to chain part and we q
440  # have to keep it in the name
441  chainProperties['chainPartName'] = chainparts
442  if ('-' in L1item) and (len(multichainparts) > 1):
443  chainProperties['chainPartName'] = chainpartsNoL1
444 
445  if len(multichainparts) > 1 and L1item.count("_") > 1 :
446  chainProperties['chainPartName'] = chainpartsNoL1
447 
448  log.debug('[analyseChainname] Chainparts: %s', chainparts)
449  if (chainProperties['signature'] != 'Cosmic') \
450  & (chainProperties['signature'] != 'Calib')\
451  & (chainProperties['signature'] != 'Streaming') \
452  & (chainProperties['signature'] != 'Beamspot') \
453  & (chainProperties['signature'] != 'Monitor') :
454  parts.pop(0)
455 
456 
457  #---- Check if topo is a bphysics topo -> change signature ----
458  from TriggerMenuMT.HLT.Menu.SignatureDicts import AllAllowedTopos_Bphysics
459  for t in genchainDict['topo']:
460  if (t in AllAllowedTopos_Bphysics):
461  chainProperties['signature'] = 'Bphysics'
462  if "tnpInfo" in chainProperties.keys() and chainProperties['tnpInfo'] != "":
463  chainProperties['alignmentGroup'] = getAlignmentGroupFromPattern('Bphysics',chainProperties['tnpInfo'])
464  else:
465  chainProperties['alignmentGroup'] = getAlignmentGroupFromPattern('Bphysics',chainProperties['extra'])
466 
467  # ---- import the relevant dictionaries for each part of the chain ----
468  SignatureDefaultValues, allowedSignaturePropertiesAndValues = getSignatureInformation(chainProperties['signature'])
469  log.debug('SignatureDefaultValues: %s', SignatureDefaultValues)
470  allDefaults = list(SignatureDefaultValues.values())
471  log.debug('All default values in a list')
472 
473  # ---- update chain properties with default properties ----
474  result = deepcopy(SignatureDefaultValues)
475  result.update(chainProperties)
476  chainProperties = result
477 
478  # ---- check that all parts to be matched are not specified as defaults already ----
479  overlaps = [x for x in parts if x in allDefaults]
480  log.debug("parts that are also in defaults: %s ", overlaps)
481  if overlaps:
482  #log.error("[analyseChainName] The following string(s) is/are already defined as defaults, please remove: %s", overlaps)
483  #raise RuntimeError("[analyseChainname] Default config appearing in chain name, please remove: %s", overlaps)
484  log.warning("[analyseChainName] The following chainpart %s contains the string(s) %s which is/are already defined as defaults, please remove!", chainparts, overlaps)
485 
486  # ---- check remaining parts for complete matches in allowedPropertiesAndValues Dict ----
487  # ---- unmatched = list of tokens that are not found in the allowed values as a whole ----
488  matchedparts = []
489  log.debug("[analyseChainname] parts to match are %s", parts)
490  for pindex, part in enumerate(parts):
491  for prop, allowedValues in allowedSignaturePropertiesAndValues.items():
492  if part in allowedValues:
493  if type(chainProperties[prop]) is list:
494  chainProperties[prop] += [part]
495  else:
496  chainProperties[prop] = part
497  matchedparts.append(part)
498 
499  # Jet-specific operations
500  if chainProperties['signature']=='Jet':
501 
502  # ----- at this point we can figure out if the chain is a bJet chain and update defaults accordingly
503  if chainProperties['bTag'] != '':
504  log.debug('Setting b-jet chain defaults')
505  # b-jet chain, so we now use the bJet defaults if they have not already been overriden
506  bJetDefaultValues, allowedbJetPropertiesAndValues = getSignatureInformation('Bjet')
507  for prop, value in bJetDefaultValues.items():
508  propSet=False
509  for value in allowedbJetPropertiesAndValues[prop]:
510  if value in matchedparts:
511  propSet=True
512  break
513 
514  # if the property was not set already, then set if according to the b-jet defaults
515  if propSet is False:
516  log.debug('Changing %s from %s to %s', prop, str(chainProperties[prop]), str(bJetDefaultValues[prop]))
517  chainProperties[prop] = bJetDefaultValues[prop]
518 
519 
520  if chainProperties['signature'] == 'Jet' and chainProperties['beamspotChain'] != '':
521  log.debug('Setting beamspot chain defaults')
522  BeamspotDefaultValues, allowedBeamspotPropertiesAndValues = getSignatureInformation('Beamspot_Jet')
523 
524  for prop, value in BeamspotDefaultValues.items():
525  propSet=False
526  for value in allowedBeamspotPropertiesAndValues[prop]:
527  if value in matchedparts:
528  propSet=True
529  break
530 
531  # if the property was not set already, then set if according to the b-jet defaults
532  if propSet is False:
533  log.debug('Changing %s from %s to %s', prop, str(chainProperties[prop]), str(BeamspotDefaultValues[prop]))
534  chainProperties[prop] = BeamspotDefaultValues[prop]
535 
536 
537  # Substitute after b-jet defaults have been set otherwise they will be overridden
538  if chainProperties['extra']:
539  # Atypical handling here: jets translate the 1 char suffix to an eta range
540  try:
541  etarange = etaRangeAbbrev[chainProperties['extra']]
542  chainProperties['etaRange'] = etarange
543  except KeyError:
544  raise RuntimeError(f"Invalid jet 'extra' value {chainProperties['extra']} in {chainProperties['chainPartName']}. Only [a,c,f] allowed")
545 
546  # ---- checking the parts that haven't been matched yet ----
547  log.debug("matched parts %s", matchedparts)
548  leftoverparts = set(parts)-set(matchedparts)
549  log.debug('leftoverparts %s', leftoverparts)
550  for pindex, part in enumerate(leftoverparts):
551  for prop, allowedValues in allowedSignaturePropertiesAndValues.items():
552  if prop in chainProperties.keys():
553  continue
554  for aV in allowedValues:
555  if (aV in part):
556  if (chainProperties['signature'] in ['Egamma', 'Muon'] )& (prop in ['trkInfo','hypoInfo']):
557  chainProperties[prop] = part
558  part = part.replace(part,'')
559  else:
560  chainProperties[prop] = aV
561  part = part.replace(aV,'')
562  break # done with allowed values for that property
563 
564  assert len(part.split()) == 0, "These parts of the chain name {} are not understood: {}".format(chainpartsNoL1,part)
565 
566 
567  # ---- remove properties that aren't allowed in the chain properties for a given siganture ----
568  forbiddenProperties = set(chainProperties.keys()) - set(allowedSignaturePropertiesAndValues.keys())
569  log.debug('chainProperties: %s', sorted(set(chainProperties.keys())))
570  log.debug('allowedSignaturePropertiesAndValues: %s', sorted(set(allowedSignaturePropertiesAndValues.keys())))
571  for fb in forbiddenProperties:
572  forbiddenValue = chainProperties.pop(fb)
573  assert forbiddenValue == '', "Property {} not allowed for signature '{}', but specified '{}'".format (fb, chainProperties['signature'], forbiddenValue)
574 
575  # ---- set the alignment group here, once we have fully worked out the properties ----
576  # ---- this is for the benefit of the probe leg in T&P chains ----
577 
578  if any(x in chainName for x in ('larnoiseburst', 'idcalib', 'metcalo', 'mettrk')):
579  chainProperties['alignmentGroup'] = 'JetMET'
580  else:
581  if 'tnpInfo' in chainProperties.keys() and chainProperties['tnpInfo'] != "":
582  chainProperties['alignmentGroup'] = getAlignmentGroupFromPattern(mdicts[chainindex]['signature'],chainProperties['tnpInfo'])
583  else:
584  chainProperties['alignmentGroup'] = getAlignmentGroupFromPattern(mdicts[chainindex]['signature'],chainProperties['extra'])
585 
586  # ---- the info of the general and the specific chain parts dict ----
587  allChainProperties.append(chainProperties)
588 
589  # ---- depending on if signatures are different in this chain, break up the chainProperties dictionary ----
590  # ---- finally also taking care of the signature key ----
591  genchainDict['chainParts'] = allChainProperties
592  for cPart in allChainProperties:
593  if cPart['signature'] == 'Jet' and cPart['bTag'] != '':
594  cPart['signature'] = 'Bjet'
595  if 'tnpInfo' in cPart.keys() and cPart['tnpInfo'] != "":
596  cPart['alignmentGroup'] = getAlignmentGroupFromPattern('Bjet', cPart['tnpInfo'])
597  else:
598  cPart['alignmentGroup'] = getAlignmentGroupFromPattern('Bjet', cPart['extra'])
599  genchainDict['signatures'] += [cPart['signature']]
600  genchainDict['alignmentGroups'] += [cPart['alignmentGroup']]
601 
602  # Postprocess chains with multiple jet chainParts
603  # to set them consistently from only one specification
604  if len(genchainDict['chainParts'])>1:
605  if 'Jet' in genchainDict['signatures'] or 'Bjet' in genchainDict['signatures']:
606  genchainDict['chainParts'] = unifyJetRecoParts(genchainDict['chainParts'])
607 
608  #genchainDict['signature'] = allChainProperties[0]['signature']
609 
610  return genchainDict
611 
612 

◆ checkChainStream()

def DictFromChainName.checkChainStream (   myStream)

Definition at line 620 of file DictFromChainName.py.

620 def checkChainStream(myStream):
621  if len(myStream) == 1:
622  if myStream[0] == 'express':
623  return False
624  return True
625 

◆ dictFromChainName()

def DictFromChainName.dictFromChainName (   flags,
  chainInfo 
)
Transforms ChainProp into the ChainDict

The logic:
---- Loop over all chains (keys) in dictionary ----
---- Then complete the dict with other info    ----
Default input format will be namedtuple:
ChainProp: ['name', 'L1Thresholds'=[], 'stream', 'groups', 'merging'=[], 'topoStartFrom'=False, 'monGroups' = []],
but for nwo plain chain name is also supported

Definition at line 626 of file DictFromChainName.py.

626 def dictFromChainName(flags, chainInfo):
627  """
628  Transforms ChainProp into the ChainDict
629 
630  The logic:
631  ---- Loop over all chains (keys) in dictionary ----
632  ---- Then complete the dict with other info ----
633  Default input format will be namedtuple:
634  ChainProp: ['name', 'L1Thresholds'=[], 'stream', 'groups', 'merging'=[], 'topoStartFrom'=False, 'monGroups' = []],
635  but for nwo plain chain name is also supported
636 
637  """
638 
639  # these if/elif/else statements are due to temporary development
640  if type(chainInfo) is str:
641  chainName = chainInfo
642  l1Thresholds = []
643  stream = ''
644  groups = []
645  mergingStrategy = 'parallel'
646  mergingOffset = -1
647  mergingOrder = []
648  topoStartFrom = ''
649  monGroups = []
650 
651  elif 'ChainProp' in str(type(chainInfo)):
652  #this is how we define chains in the menu - the normal behaviour of this function
653  chainName = chainInfo.name
654  l1Thresholds = chainInfo.l1SeedThresholds
655  stream = chainInfo.stream
656  groups = flattenChainGroups(chainInfo.groups)
657  mergingStrategy = chainInfo.mergingStrategy
658  mergingOffset = chainInfo.mergingOffset
659  mergingOrder = chainInfo.mergingOrder
660  topoStartFrom = chainInfo.topoStartFrom
661  monGroups = chainInfo.monGroups
662 
663  else:
664  raise RuntimeError("Format of chainInfo passed to genChainDict not known")
665 
666  #check here the content of the stream
667  if not checkChainStream(stream):
668  raise RuntimeError("Chain {}, format of chainInfo:stream {} is not valid".format(chainName, stream))
669 
670  L1item = getL1item(flags, chainName)
671 
672  log.debug("Analysing chain with name: %s", chainName)
673  chainDict = analyseChainName(chainName, l1Thresholds, L1item)
674  log.debug('ChainProperties: %s', chainDict)
675 
676  for chainPart in chainDict['chainParts']:
677  # fill the sigFolder and subSigs folder
678  for sf in chainPart['sigFolder']:
679  if sf in chainDict['sigDicts']:
680  chainDict['sigDicts'][sf].extend(chainPart['subSigs'])
681  else:
682  chainDict['sigDicts'].update({sf:chainPart['subSigs']})
683  if sf == 'Bjet':
684  chainDict['sigDicts'].update({'Jet':['Jet']})
685 
686 
687  thisSignature = chainPart['signature']
688  thisAlignGroup = chainPart['alignmentGroup']
689  thisExtra = chainPart['extra']
690  thisL1 = chainPart['L1threshold']
691  thisChainPartName = chainPart['chainPartName']
692 
693  if thisSignature in ['Muon','Bphysics']:
694  if 'MuonnoL1' in thisAlignGroup or 'lateMu' in thisExtra:
695  if 'FSNOSEED' not in thisL1:
696  log.error("Muon noL1 and lateMu chain should be seeded from FSNOSEED. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
697  else:
698  if 'MU' not in thisL1:
699  log.error("Standard muon and Bphysics chain should be seeded from L1_MU. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
700  #incorrectL1=True
701 
702  if thisSignature in ['Electron','Photon'] and not ('UPC' in stream): # don't apply for HI UPC chains
703  if 'EM' not in thisL1 and 'BKee' not in thisL1 and 'All' not in thisL1:
704  log.error("Standard egamma chains should be seeded from L1_EM. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
705  #incorrectL1=True
706 
707  if thisSignature in ['Tau']:
708  if 'TAU' not in thisL1:
709  log.error("Standard tau chains should be seeded from L1_TAU. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
710  #incorrectL1=True
711 
712  if thisSignature in ['Jet','Bjet','MET','UnconventionalTracking']:
713  if 'FSNOSEED' not in thisL1:
714  log.error("Jet, b-jet, MET chains should be seeded from FSNOSEED. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
715  #incorrectL1=True
716 
717  if thisChainPartName in ['noalg']:
718  # All streamers should be unseeded except RoI-based PEB streamers which need a real RoI for PEB
719  if 'FSNOSEED' not in thisL1 and not isRoIBasedPEB(chainDict['eventBuildType']):
720  log.error("noalg chains should be seeded from FSNOSEED. Check %s seeded from %s (defined L1: %s), signature %s",chainDict['chainName'],thisL1,l1Thresholds,thisSignature)
721  #incorrectL1=True
722 
723 # if incorrectL1 is True:
724 # raise Exception("You are using incorrect L1 seed, please check for ERROR messages...")
725 
726 
727  log.debug('Parts: signature %s, align %s, extra %s, L1 %s', thisSignature, thisAlignGroup, thisExtra, thisL1)
728 
729 
730 
731  # setting the L1 item
732  chainDict['L1item'] = L1item
733  chainDict['stream'] = stream
734  chainDict['groups'] = groups
735  chainDict['mergingStrategy'] = mergingStrategy
736  chainDict['mergingOffset'] = mergingOffset
737  chainDict['mergingOrder'] = mergingOrder
738  chainDict['topoStartFrom'] = topoStartFrom
739  chainDict['monGroups'] = monGroups
740  chainDict['chainNameHash'] = string2hash(chainDict['chainName'])
741 
742 
743  allChainMultiplicities = getChainMultFromDict(chainDict)
744  chainDict['chainMultiplicities'] = allChainMultiplicities
745  log.debug('Setting chain multiplicities: %s ', allChainMultiplicities)
746 
747 
751 
752  return chainDict
753 

◆ flattenChainGroups()

def DictFromChainName.flattenChainGroups (   A)

Definition at line 613 of file DictFromChainName.py.

613 def flattenChainGroups(A):
614  rt = []
615  for i in A:
616  if isinstance(i,list): rt.extend(flattenChainGroups(i))
617  else: rt.append(i)
618  return rt
619 

◆ getAllThresholdsFromItem()

def DictFromChainName.getAllThresholdsFromItem (   item)
Breaks the item name into parts separated by the _ and from each element extract the threshold name

Fails when used on topo items or ill formatted items
Examples: L1_MU4 returns [MU4]
L1_2MU4 returns [MU4, MU4]
L1_MU4_MU6 returns [MU4, MU6]

Definition at line 58 of file DictFromChainName.py.

58 def getAllThresholdsFromItem(item):
59  """
60  Breaks the item name into parts separated by the _ and from each element extract the threshold name
61 
62  Fails when used on topo items or ill formatted items
63  Examples: L1_MU4 returns [MU4]
64  L1_2MU4 returns [MU4, MU4]
65  L1_MU4_MU6 returns [MU4, MU6]
66  """
67  assert item.startswith("L1_"), "The L1 item {} name does not start with L1".format( item )
68  assert "-" not in item, "The {} is Topo item and can not be parsed".format( item )
69 
70  multThressholds = item.split("_")[1:] # skips the L1_
71  thresholds = []
72  for mt in multThressholds:
73  assert mt[0] != '1', 'Issue while parsing {}, multiplicity of 1, should not be configured, if multiplicity greater than 9 is needed then support for it needs to be added'.format( mt )
74  if mt[0] in '23456789': # first letter is a number == multiplicity, multiplicity 1 is not specified
75  thresholds.extend( int(mt[0])*[mt[1:]] )
76  else:
77  thresholds.append( mt ) # no muliplicity prefix
78  return thresholds
79 

◆ getChainMultFromDict()

def DictFromChainName.getChainMultFromDict (   chainDict)
Look for all multiplicities stored in chains

Definition at line 129 of file DictFromChainName.py.

129 def getChainMultFromDict(chainDict):
130  """
131  Look for all multiplicities stored in chains
132  """
133  allMultis = []
134 
135  for cpart in chainDict['chainParts']:
136  if cpart['multiplicity'] != '':
137  allMultis.append( int(cpart['multiplicity']))
138  return allMultis
139 
140 
141 # For certain chains, we need to include the L1 seed threshold
142 # in the leg name for disambiguation.
143 # This checks that the explicit threshold matches the threshold list
144 # In this case, the seed thresholds cannot be inferred from the L1 name

◆ getChainThresholdFromName()

def DictFromChainName.getChainThresholdFromName (   chainParts,
  signature 
)
Decode threshold value from the chain name

Definition at line 106 of file DictFromChainName.py.

106 def getChainThresholdFromName(chainParts, signature):
107  """
108  Decode threshold value from the chain name
109  """
110 
111  from TriggerMenuMT.HLT.Menu.SignatureDicts import getBasePattern
112  pattern = getBasePattern()
113  trigType = []
114  thresholdToPass = 0
115 
116  allThresh = []
117  for cpart in chainParts:
118  m = pattern.match( cpart )
119  if m:
120  log.debug("In getChainThresholdFromName: Pattern found in this string: %s", cpart)
121  groupdict = m.groupdict()
122  allThresh.append(groupdict['threshold'])
123  trigType.append(groupdict['trigType'])
124  if signature == groupdict['trigType']:
125  thresholdToPass = groupdict['threshold']
126  break
127  return thresholdToPass
128 

◆ getEBPartFromParts()

def DictFromChainName.getEBPartFromParts (   chainName,
  chainParts 
)
If EB identifier is in the name, return it.

Checks if there is only one identifier

Definition at line 91 of file DictFromChainName.py.

91 def getEBPartFromParts( chainName, chainParts ):
92  """
93  If EB identifier is in the name, return it.
94 
95  Checks if there is only one identifier
96  """
97  # ---- event building identifier ----
98  from TriggerMenuMT.HLT.Menu.EventBuildingInfo import getAllEventBuildingIdentifiers
99  eventBuildTypes = set( getAllEventBuildingIdentifiers() ).intersection( chainParts )
100  assert len(eventBuildTypes) <= 1, 'Chain {} has more than one Event Building identifier: {}, that is not supported'.format( chainName, eventBuildTypes)
101  if eventBuildTypes:
102  return eventBuildTypes.pop()
103  return ''
104 
105 

◆ getL1item()

def DictFromChainName.getL1item (   flags,
  chainName 
)

Definition at line 54 of file DictFromChainName.py.

54 def getL1item(flags, chainName):
55  mainL1 = getOverallL1item(flags, chainName)
56  return mainL1
57 

◆ getOverallL1item()

def DictFromChainName.getOverallL1item (   flags,
  chainName 
)
Extracts the L1 seed from the chain name, checks for issue in naming, if found, fails

In simple case the L1 items is just the last part of the name, after the _L1...
There are though more complicated names like ...._L1...._L1..._L1... in such cases the L1 seed item is the last one

Definition at line 24 of file DictFromChainName.py.

24 def getOverallL1item(flags, chainName):
25  """
26  Extracts the L1 seed from the chain name, checks for issue in naming, if found, fails
27 
28  In simple case the L1 items is just the last part of the name, after the _L1...
29  There are though more complicated names like ...._L1...._L1..._L1... in such cases the L1 seed item is the last one
30  """
31  assert '_L1' in chainName, 'ERROR IN CHAIN {}, missing L1 seed at the end i.e. _L1...' .format(chainName)
32 
33  from TriggerMenuMT.HLT.Menu.L1Seeds import valid_multiseeds, getSpecificL1Seeds
34  from TrigConfigSvc.TriggerConfigAccess import getL1MenuAccess
35 
36  # this assumes that the last string of a chain name is the overall L1 item
37  cNameParts = chainName.rsplit("_L1",1)
38  l1seed = 'L1_' + cNameParts[-1]
39  # For reference, remapping of L1seeds lived originally in LVL1MenuConfig/LVL1Menu/L1Seeds.py
40  # L1 collections can be read out from there in case they are needed again
41  if l1seed == 'L1_All':
42  return ''
43  if l1seed == 'L1_test': #Multiseeded chains are build like this
44  return 'L1_EM24VHI,L1_MU20'
45  if l1seed in valid_multiseeds:
46  # For these item seed specifications we need to derive the precise list of item names from the L1Menu.
47  lvl1access = getL1MenuAccess(flags)
48  itemsDict = lvl1access.items(includeKeys = ['name','ctpid','triggerType'])
49  l1seedlist = getSpecificL1Seeds(l1seed, itemsDict, flags.Trigger.triggerMenuSetup)
50  return l1seedlist
51 
52  return l1seed
53 

◆ getUniqueThresholdsFromItem()

def DictFromChainName.getUniqueThresholdsFromItem (   item)
As above but eliminates repeated thresholds

Definition at line 80 of file DictFromChainName.py.

81  """
82  As above but eliminates repeated thresholds
83  """
84  allThreshold = getAllThresholdsFromItem(item)
85  s = set()
86  def _(t):
87  s.add(t)
88  return t
89  return [ _(t) for t in allThreshold if t not in s ]
90 

◆ main()

def DictFromChainName.main ( )

Definition at line 754 of file DictFromChainName.py.

754 def main():
755 
756  from AthenaConfiguration.AllConfigFlags import initConfigFlags
757  flags = initConfigFlags()
758 
759  parser = flags.getArgumentParser()
760  parser.add_argument(
761  'chain',
762  type=str,
763  help='Chain name to be parsed into chain dictionary')
764  parser.add_argument(
765  '-t', '--thresholds',
766  nargs='+',
767  help='L1 thresholds, needed for multileg or fullscan chains')
768  args = flags.fillFromArgs(parser=parser)
769  flags.lock()
770 
771  if args.thresholds:
772  from TriggerMenuMT.HLT.Config.Utility.ChainDefInMenu import ChainProp
773  cd = dictFromChainName(flags, ChainProp(args.chain,l1SeedThresholds=args.thresholds,groups=[]))
774  else:
775  cd = dictFromChainName(flags, args.chain)
776 
777  from pprint import pprint
778  pprint(cd)
779 
780  import json
781  with open(f'{args.chain}.dict.json','w') as f:
782  json.dump(cd, f, indent=2)
783 
784  return 0
785 

◆ unifyJetRecoParts()

def DictFromChainName.unifyJetRecoParts (   chainParts)

Definition at line 164 of file DictFromChainName.py.

164 def unifyJetRecoParts(chainParts):
165  from TriggerMenuMT.HLT.Menu.SignatureDicts import getSignatureInformation, JetRecoKeys
166 
167  """
168  Postprocess the jet chainParts to set all the reco config consistently
169  For formatting reasons, we extract these from the last jet chainPart
170  then propagate to all jet chainParts.
171  Any inconsistencies in non-default options are considered a malformed chain
172  Technically we can't tell if the default was explicitly set, though.
173  """
174 
175  jetDefaults, _ = getSignatureInformation('Jet')
176  # Extract the jet chainParts, and get the reco specs from the last one
177  _jetRecoKeys = JetRecoKeys
178  jetChainParts = [cPart for cPart in chainParts if cPart['signature'] in ['Jet','Bjet']]
179  jetRecoDict = {k:jetChainParts[-1][k] for k in _jetRecoKeys}
180 
181  # Check consistency of the preceding jet parts
182  for p in jetChainParts[:-1]:
183  for k in _jetRecoKeys:
184  # Assume that keys are all defined
185  if p[k] != jetDefaults[k]: # OK if the spec is default
186  log.error('Inconsistent jet reco setting for %s in chainPart %s', k, p['chainPartName'])
187  log.error('Jet chainParts: %s', jetChainParts)
188  raise RuntimeError('Jet reco should be specified only in the last jet chainPart')
189 
190  # Substitute the reco settings consistently and return
191  newChainParts = []
192  for cPart in chainParts:
193  newCPart = deepcopy(cPart)
194  if newCPart['signature'] in ['Jet','Bjet']:
195  for k in _jetRecoKeys:
196  newCPart[k] = jetRecoDict[k]
197  newChainParts.append(newCPart)
198 
199  return newChainParts
200 

◆ verifyExplicitL1Thresholds()

def DictFromChainName.verifyExplicitL1Thresholds (   chainname,
  chainparts,
  L1thresholds 
)

Definition at line 146 of file DictFromChainName.py.

146 def verifyExplicitL1Thresholds(chainname,chainparts,L1thresholds):
147  assert len(L1thresholds)>0, f'L1 thresholds cannot be inferred from L1 name for chain {chainname} with explicit L1 seed thresholds'
148 
149  log.debug('Verifying explicit L1 thresholds for %s, received L1thresholds %s',chainname,L1thresholds)
150 
151  counter = 0
152  for part, threshold in zip(chainparts,L1thresholds):
153  if '_L1' in part:
154  matches = matchL1.findall(part)
155  assert len(matches)==1, f"Inappropriate number of L1 thresholds {matches} in chain part '{part}'"
156  thisL1, remainder = matches[0] # list of tuples
157  assert remainder == '', f"Explicit L1 threshold should be last element in chain part {part}"
158  log.verbose(' ChainPart %s has explicit L1 threshold %s',part,thisL1)
159  assert 'PROBE' not in thisL1, f"Omit 'PROBE' from explicit L1 threshold '{thisL1}'"
160  assert thisL1 == threshold.replace('PROBE',''), f"Explicit L1 threshold for chainpart '{thisL1}' does not match threshold '{threshold}' from list"
161  counter += 1
162  assert counter>0, f"Did not find explicit L1 seeds in chain parts for {chainname}!"
163 

Variable Documentation

◆ __author__

DictFromChainName.__author__
private

Definition at line 10 of file DictFromChainName.py.

◆ __doc__

DictFromChainName.__doc__
private

Definition at line 12 of file DictFromChainName.py.

◆ __version__

DictFromChainName.__version__
private

Definition at line 11 of file DictFromChainName.py.

◆ log

DictFromChainName.log

Definition at line 22 of file DictFromChainName.py.

◆ matchL1

DictFromChainName.matchL1

Definition at line 145 of file DictFromChainName.py.

DictFromChainName.getAllThresholdsFromItem
def getAllThresholdsFromItem(item)
Definition: DictFromChainName.py:58
DictFromChainName.getOverallL1item
def getOverallL1item(flags, chainName)
Definition: DictFromChainName.py:24
Run3DQTestingDriver._
_
Definition: Run3DQTestingDriver.py:35
vtune_athena.format
format
Definition: vtune_athena.py:14
python.HLT.Menu.SignatureDicts.getBasePattern
def getBasePattern()
Definition: SignatureDicts.py:1382
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
DictFromChainName.main
def main()
Definition: DictFromChainName.py:754
DictFromChainName.dictFromChainName
def dictFromChainName(flags, chainInfo)
Definition: DictFromChainName.py:626
DictFromChainName.checkChainStream
def checkChainStream(myStream)
Definition: DictFromChainName.py:620
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
covarianceTool.filter
filter
Definition: covarianceTool.py:514
DictFromChainName.unifyJetRecoParts
def unifyJetRecoParts(chainParts)
Definition: DictFromChainName.py:164
python.TriggerConfigAccess.getL1MenuAccess
L1MenuAccess getL1MenuAccess(flags=None)
Definition: TriggerConfigAccess.py:129
DictFromChainName.getChainThresholdFromName
def getChainThresholdFromName(chainParts, signature)
Definition: DictFromChainName.py:106
DictFromChainName.getUniqueThresholdsFromItem
def getUniqueThresholdsFromItem(item)
Definition: DictFromChainName.py:80
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
DictFromChainName.getChainMultFromDict
def getChainMultFromDict(chainDict)
Definition: DictFromChainName.py:129
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
DictFromChainName.flattenChainGroups
def flattenChainGroups(A)
Definition: DictFromChainName.py:613
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
DictFromChainName.getL1item
def getL1item(flags, chainName)
Definition: DictFromChainName.py:54
python.HLT.Menu.SignatureDicts.getSignatureNameFromToken
def getSignatureNameFromToken(chainpart)
Definition: SignatureDicts.py:1309
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
DictFromChainName.verifyExplicitL1Thresholds
def verifyExplicitL1Thresholds(chainname, chainparts, L1thresholds)
Definition: DictFromChainName.py:146
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
Trk::open
@ open
Definition: BinningType.h:40
dqt_zlumi_pandas.update
update
Definition: dqt_zlumi_pandas.py:42
python.HLT.Menu.SignatureDicts.getSignatureInformation
def getSignatureInformation(signature)
Definition: SignatureDicts.py:1331
python.HLT.Menu.L1Seeds.getSpecificL1Seeds
def getSpecificL1Seeds(l1seedname, l1itemobject, menu_name)
Definition: L1Seeds.py:348
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
HLTUtils.string2hash
def string2hash(string)
Definition: HLTUtils.py:5
str
Definition: BTagTrackIpAccessor.cxx:11
python.HLT.Menu.EventBuildingInfo.getAllEventBuildingIdentifiers
def getAllEventBuildingIdentifiers()
Definition: EventBuildingInfo.py:45
DictFromChainName.analyseChainName
def analyseChainName(chainName, L1thresholds, L1item)
Definition: DictFromChainName.py:201
python.HLT.CommonSequences.EventBuildingSequences.isRoIBasedPEB
isRoIBasedPEB
Definition: EventBuildingSequences.py:393
DictFromChainName.getEBPartFromParts
def getEBPartFromParts(chainName, chainParts)
Definition: DictFromChainName.py:91