ATLAS Offline Software
L1Menu.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 from .CTP import CTP
4 from .Items import MenuItemsCollection
5 from .Thresholds import MenuThresholdsCollection
6 from .TopoAlgorithms import MenuTopoAlgorithmsCollection, AlgType, AlgCategory
7 from .Boards import MenuBoardsCollection
8 from .Connectors import MenuConnectorsCollection, CType
9 from .MenuUtils import get_smk_psk_Name
10 from .Limits import Limits
11 from .L1MenuFlags import L1MenuFlags
12 from .ThresholdType import ThrType
13 from ..Config.TypeWideThresholdConfig import getTypeWideThresholdConfig
14 
15 from collections import OrderedDict as odict
16 from AthenaCommon.Logging import logging
17 log = logging.getLogger(__name__)
18 
19 class L1Menu(object):
20  """
21  This class holds everything that is needed to define the menu
22  """
23 
24  def __init__(self, menuName, flags):
25  self.menuName = menuName
26 
27  # items in menu
29 
30  # store cached flags
31  self.flags = flags
32 
33  # all thresholds that are in menu (new and legacy)
35 
36  # all thresholds that are in menu (new and legacy)
38 
39  # all connectors between legacyCalo, muctpi, topo and the CTPIN/CTPCORE
41 
42  # board definition
44 
45  # CTP Info in the menu
46  self.ctp = CTP()
47 
48  if self.menuName:
49  smk_psk_Name = get_smk_psk_Name(self.menuName)
50  self.items.menuName = smk_psk_Name["smkName"]
51  self.items.pssName = smk_psk_Name["pskName"]
52 
53  @staticmethod
54  def partitioning():
55  first = L1MenuFlags.MenuPartitioning()
56  last = first[1:] + [ Limits.MaxTrigItems ]
57  partitioning = dict( zip([1,2,3],zip(first,last)) )
58  return partitioning
59 
60  def setBunchGroupSplitting(self, v = True):
61  MenuItemsCollection.splitBunchGroups = v
62 
63 
64  def addItem(self, item):
65  self.items += item
66 
67 
68  def getItem(self,name):
69  return self.items.findItemByName(name)
70 
71 
72  def addThreshold(self, threshold):
73  self.thresholds += threshold
74 
75 
76  def addTopoAlgo(self, algo, category):
77  algo.setThresholds( self.thresholds ) # each algo gets a pointer to the full thresholds definition (for the extrainfo)
78  self.topoAlgos.addAlgo(algo, category)
79 
80 
81  def addBoard(self, boardDef):
82  return self.boards.addBoard(boardDef)
83 
84 
85  def addConnector(self, connDef):
86  self.connectors.addConnector(connDef)
87 
88 
89  def setupCTPMonitoring(self):
90  self.ctp.setupMonitoring(self.menuName, self.items, self.thresholds, self.connectors)
91 
92  def check(self):
93  log.info("Doing L1 Menu checks")
94  from collections import defaultdict as dd
95  missing = dd(list)
96  allThresholds = set([thr.name for thr in self.thresholds])
97  allUsedThresholds = set()
98  for item in self.items:
99  for thrName in item.thresholdNames():
100  if 'SPARE' in thrName:
101  raise RuntimeError("CTP input %s is used by %s but SPARE thresholds are not to be used!" %(thrName, item) )
102  if thrName not in allThresholds:
103  missing[thrName].append(item.name)
104  else:
105  allUsedThresholds.add(thrName)
106 
107  for thrName in sorted(missing.keys()):
108  log.warning("Threshold %s (used by %s) is not defined in the menu", thrName,",".join(missing[thrName]))
109 
110  if len(allThresholds)-len(allUsedThresholds)>0:
111  unusedThresholds = allThresholds.difference(allUsedThresholds)
112  log.debug("The following thresholds are unused")
113  log.debug("MU: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("MU")]))
114  log.debug("EM: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("EM")]))
115  log.debug("HA: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("HA")]))
116  log.debug("J: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("J")]))
117  log.debug("eFEX: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("e")]))
118  log.debug("jFEX: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("j")]))
119  log.debug("cTAU: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("cTAU")]))
120  log.debug("gFEX: %s", ", ".join([thr for thr in unusedThresholds if thr.startswith("g")]))
121 
123  from collections import defaultdict as dd
124  from ..Menu.LegacyMenuThresholds import legacyThresholds
125  extraThresholds = dd(list)
126  for item in self.items:
127  for thrName in item.thresholdNames():
128  if thrName[:3]=='ZB_':
129  thrName = thrName[3:]
130  if thrName[0] not in ('e','j','g', 'c') and thrName[:2] not in ["MU"] and "TOPO" not in thrName[:4]:
131  if thrName not in legacyThresholds:
132  extraThresholds[thrName].append(item.name)
133 
134  for thrName in sorted(extraThresholds.keys()):
135  log.warning("Threshold %s (used by %s) should not be used!", thrName,",".join(extraThresholds[thrName]))
136 
138  if 'MC' not in self.menuName:
139  from collections import defaultdict as dd
140  perfThresholds = dd(list)
141  for item in self.items:
142  for thrName in item.thresholdNames():
143  if 'Perf' in thrName:
144  perfThresholds[thrName].append(item.name)
145  for thrName in sorted(perfThresholds.keys()):
146  raise RuntimeError("Threshold %s (used by %s) should not be used!", thrName,",".join(perfThresholds[thrName]))
147 
148  def checkBoardInputs(self, algo, connDefName, fpgaName ):
149  if 'MuCTPi' in connDefName or 'Legacy' in connDefName:
150  return
151 
152  boardName = connDefName+fpgaName
153 
154  allowedInputs = odict()
155  allowedInputs['Topo1Opt0'] = ['MU', 'eEM', 'eTAU', 'gJ', 'gLJ', 'ZeroBiasA'] # TOPO1A, FPGA1
156  allowedInputs['Topo1Opt1'] = ['MU', 'eEM', 'eTAU', 'gJ', 'gLJ', ] # TOPO1A, FPGA2
157  allowedInputs['Topo1Opt2'] = ['MU', 'eTAU', 'cTAU', 'j', 'gXE', 'gTE', 'gMHT'] # TOPO1B, FPGA1
158  allowedInputs['Topo1Opt3'] = ['MU', 'eTAU', 'cTAU', 'j', 'gXE', 'gTE', 'gMHT', 'LArSaturation', 'ZeroBiasB'] # TOPO1B, FPGA2
159  allowedInputs['Topo2El0'] = ['MU', 'eTAU', 'j', ] # TOPO2, FPGA1
160  allowedInputs['Topo2El1'] = [ 'eEM', 'j', ] # TOPO2, FPGA2
161  allowedInputs['Topo3El0'] = [ 'eEM', 'eTAU', 'j', ] # TOPO3, FPGA1
162  allowedInputs['Topo3El1'] = ['MU', 'eEM', 'eTAU', 'g', ] # TOPO3, FPGA2
163 
164  if boardName not in allowedInputs.keys():
165  raise RuntimeError("Connector name %s not found" % boardName )
166 
167  if 'Mult_' in algo.name:
168  if not (any(x in algo.threshold for x in allowedInputs[boardName])):
169  raise RuntimeError("Algorithm %s in board %s with threshold %s not allowed" % (algo.name, boardName, algo.threshold ))
170 
171  if 'Mult_' not in algo.name:
172  for algoInput in algo.inputs:
173  if not (any(x in algoInput for x in allowedInputs[boardName])):
174  raise RuntimeError("Algorithm %s in board %s with input %s not allowed" % (algo.name, boardName, algoInput ))
175 
176  def checkL1CaloThresholds(self, thresholds, boardName, connName):
177  fullName = boardName + connName
178 
179  allowedInputs = odict()
180  allowedInputs['Ctpin7EM1'] = 8*['EM']
181  allowedInputs['Ctpin7EM2'] = 8*['EM']
182  allowedInputs['Ctpin7TAU1'] = 8*['HA']
183  allowedInputs['Ctpin7TAU2'] = 8*['HA']
184 
185  allowedInputs['Ctpin8JET1'] = 10*['J'] # 3-bit JET
186  allowedInputs['Ctpin8JET2'] = 15*['J'] # 2-bit JET
187  allowedInputs['Ctpin8EN1'] = 8*['TE'] + 8*['XE'] + 8*['XS']
188  allowedInputs['Ctpin8EN2'] = 8*['TE'] + 8*['XE']
189 
190  invalidThresholds = False
191  for ithr,thr in enumerate(thresholds):
192  try:
193  allowedThr = allowedInputs[fullName][ithr]
194  if thr[:len(allowedThr)] != allowedThr:
195  log.error(f"Threshold {thr} does not match expected type {allowedThr} at position {ithr} in connector {fullName}")
196  invalidThresholds = True
197  except IndexError:
198  log.error(f"Too many thresholds ({len(thresholds)}) provided for connector {fullName}, which only supports {len(allowedInputs[fullName])} thresholds")
199  invalidThresholds = True
200  if invalidThresholds:
201  raise RuntimeError("Incorrect specification of legacy L1Calo thresholds")
202 
204  for conn in self.connectors:
205  if conn.ctype == CType.CTPIN:
206  if len(conn.triggerLines)>31:
207  raise RuntimeError("Too many CTP inputs in %s: %i but a max of 31 are allowed" %(conn.name,len(conn.triggerLines)))
208 
210  from collections import namedtuple
211  ctpInput = namedtuple('ctpInput',"name, conn, nbit")
212  ctpInputs = []
213  ctpUnusedInputs = []
214  ctpOutputs = []
215  thrNames = []
216  ctpInputBitSets = dict()
217  ctpInputNameSets = dict()
218  ctpUnusedInputBitSets = dict()
219  ctpUnusedInputNameSets = dict()
220  for item in self.items:
221  ctpOutputs.append(item.name)
222  for thrName in item.thresholdNames():
223  if thrName[:3]=='ZB_':
224  thrName = thrName[3:]
225  if thrName not in thrNames:
226  thrNames.append(thrName)
227  thrNames_notFound = []
228  for thrName in thrNames:
229  thrName_found = False
230  for conn in self.connectors:
231  if conn.ctype != CType.ELEC:
232  for tl in conn.triggerLines:
233  if thrName == tl.name:
234  ctpInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
235  thrName_found = True
236  else:
237  for fpga in conn.triggerLines:
238  for clock in conn.triggerLines[fpga]:
239  for tl in conn.triggerLines[fpga][clock]:
240  if thrName == tl.name:
241  ctpInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
242  thrName_found = True
243  if not thrName_found:
244  thrNames_notFound.append(thrName)
245 
246  for conn in self.connectors:
247  if conn.ctype != CType.ELEC:
248  for tl in conn.triggerLines:
249  thrName = tl.name
250  if thrName[:3]=='ZB_':
251  thrName = thrName[3:]
252  usedInput = False
253  for ctpIn in ctpInputs:
254  if thrName == ctpIn.name:
255  usedInput = True
256  if not usedInput:
257  ctpUnusedInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
258  else:
259  for fpga in conn.triggerLines:
260  for clock in conn.triggerLines[fpga]:
261  for tl in conn.triggerLines[fpga][clock]:
262  thrName = tl.name
263  if thrName[:3]=='ZB_':
264  thrName = thrName[3:]
265  usedInput = False
266  for ctpIn in ctpInputs:
267  if thrName == ctpIn.name:
268  usedInput = True
269  if not usedInput:
270  ctpUnusedInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
271 
272  if len(thrNames_notFound)>0:
273  log.error("Thresholds [%s] are not found", ",".join(thrNames_notFound))
274  log.error("Input thresholds are [%s]", ",".join([ input.name for input in ctpInputs]))
275  raise RuntimeError("Not all input thresholds found!")
276 
277  for ctpIn in ctpInputs:
278  thrset = None
279  thrName = ctpIn.name
280  if thrName[:2] in ['EM','HA','XE','TE','XS']:
281  thrset = 'legacyCalo'
282  elif thrName[:1]=='J':
283  thrset = 'legacyCalo'
284  elif thrName[:2]=='MU':
285  thrset = 'muon'
286  elif thrName[:3] in ['MBT','AFP','BCM','CAL','NIM','ZDC','BPT','LUC','BMA']:
287  thrset = 'detector'
288  elif thrName[:6]=='R2TOPO':
289  thrset = 'legacyTopo'
290  elif thrName[:1] in ['e','j','c','g']:
291  thrset = 'topo1'
292  elif thrName[:4]=='TOPO':
293  if 'Topo2' in ctpIn.conn:
294  thrset = 'topo2'
295  elif 'Topo3' in ctpIn.conn:
296  thrset = 'topo3'
297 
298  if thrset not in ctpInputBitSets:
299  ctpInputBitSets[thrset] = 0
300  ctpInputNameSets[thrset] = []
301  if thrName not in ctpInputNameSets[thrset]:
302  ctpInputNameSets[thrset].append(thrName)
303  ctpInputBitSets[thrset] += ctpIn.nbit
304 
305  for ctpIn in ctpUnusedInputs:
306  thrset = None
307  thrName = ctpIn.name
308  if thrName[:2] in ['EM','HA','XE','TE','XS']:
309  thrset = 'legacyCalo'
310  elif thrName[:1]=='J':
311  thrset = 'legacyCalo'
312  elif thrName[:2]=='MU':
313  thrset = 'muon'
314  elif thrName[:3] in ['MBT','AFP','BCM','CAL','NIM','ZDC','BPT','LUC']:
315  thrset = 'detector'
316  elif thrName[:6]=='R2TOPO':
317  thrset = 'legacyTopo'
318  elif thrName[:1] in ['e','j','c','g']:
319  thrset = 'topo1'
320  elif thrName[:4]=='TOPO':
321  if 'Topo2' in ctpIn.conn:
322  thrset = 'topo2'
323  elif 'Topo3' in ctpIn.conn:
324  thrset = 'topo3'
325 
326  if thrset not in ctpUnusedInputBitSets:
327  ctpUnusedInputBitSets[thrset] = 0
328  ctpUnusedInputNameSets[thrset] = []
329  if thrName not in ctpUnusedInputNameSets[thrset]:
330  ctpUnusedInputNameSets[thrset].append(thrName)
331  ctpUnusedInputBitSets[thrset] += ctpIn.nbit
332 
333  totalInputs = 0
334  log.info("Check total number of CTP input and output bits:")
335  log.info("Number of output bits: %i", len(ctpOutputs) )
336  for thrset in ctpInputBitSets:
337  log.info("Used inputs in %s: %i thresholds and %i bits", thrset, len(ctpInputNameSets[thrset]), ctpInputBitSets[thrset] )
338  if thrset is not None:
339  log.debug("Threshold set %s: %s", thrset, ",".join(ctpInputNameSets[thrset]) )
340  else:
341  log.info("Unrecognised CTP input bits: %s", ",".join(ctpInputNameSets[thrset]) )
342  totalInputs += ctpInputBitSets[thrset]
343  log.info("Number of used inputs bits: %i" , totalInputs )
344  totalUnusedInputs = 0
345  for thrset in ctpUnusedInputBitSets:
346  log.debug("Unused thresholds in %s: %i thresholds and %i bits", thrset, len(ctpUnusedInputNameSets[thrset]), ctpUnusedInputBitSets[thrset] )
347  if thrset is not None:
348  log.debug("Unused threshold set %s: %s", thrset, ",".join(ctpUnusedInputNameSets[thrset]) )
349  else:
350  log.debug("Unrecognised CTP input bits: %s", ",".join(ctpUnusedInputNameSets[thrset]) )
351  totalUnusedInputs += ctpUnusedInputBitSets[thrset]
352  log.debug("Number of un-used inputs bits: %i" , totalUnusedInputs )
353 
354  # Fail menu generation for menus going to P1:
355  if ( totalInputs > Limits.MaxTrigItems or len(ctpOutputs) > Limits.MaxTrigItems):
356  if 'AllCTPIn' in self.menuName:
357  log.warning(f"Input or output bits limit of {Limits.MaxTrigItems} exceeded in the dummy CTP menu -- OK")
358  else:
359  raise RuntimeError("Both the numbers of inputs and outputs need to be not greater than %i in a physics menu!" % Limits.MaxTrigItems)
360 
361  # Avoid that L1 item is defined only for BGRP0 as this include also the CALREQ BGRP2 (ATR-24781)
362  def checkBGRP(self):
363  for item in self.items:
364  if len(item.bunchGroups)==1 and item.bunchGroups[0]=='BGRP0':
365  raise RuntimeError("L1 item %s is defined with only BGRP0, ie it can trigger also in the CALREQ BGRP2 bunches. Please add another bunch group (ATR-24781)" % item.name)
366  if 'BGRP2' in item.bunchGroups:
367  thrtype = item.logic.content['threshold'].ttype
368  if thrtype in ThrType.CaloTypes():
369  # The LAr Digital Trigger sends an "align frame" to the FEXes in BCID 3500 (in BGRP2)
370  # No trigger can be sent during this align frame, so we block all calo triggers from this BGRP
371  raise RuntimeError(f"L1 item {item.name} with threshold type {thrtype} is in CALREQ BGRP2. This is not allowed!")
372 
373 
374  def checkPtMinToTopo(self):
375  # check that the ptMinToTopo for all types of thresholds is lower than the minimum Et cuts applied in multiplicity and decision algorithms
376 
377  # collect the ptMinToTopo values
378  ptMin = {}
379  for thrtype in ThrType.Run3Types():
380  ttconfig = getTypeWideThresholdConfig(thrtype, self.flags.Trigger.L1.Menu.doHeavyIonTobThresholds, self.flags.Trigger.L1.Menu.doeFexBDTTau)
381  inputtype = thrtype.name
382  if inputtype == 'cTAU':
383  inputtype = 'eTAU'
384  for key, value in ttconfig.items():
385  if "ptMinToTopo" in key:
386  if inputtype in ptMin:
387  if ptMin[inputtype] > value:
388  ptMin[inputtype] = value
389  else:
390  ptMin[inputtype] = value
391 
392  # loop over multiplicity algorithms and get the min et values
393  thresholdMin = {}
394  for algo in self.topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT]:
395  alg = self.topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT][algo]
396  threshold = alg.threshold
397  inputtype = alg.input
398  if 'cTAU' in inputtype:
399  inputtype = 'eTAU'
400  elif any(substring in inputtype for substring in ['XE','TE','MHT','LArSaturation','ZeroBias']):
401  continue
402  thr = self.thresholds.thresholds[threshold]
403  minEt = 99999
404  if hasattr(thr, 'thresholdValues'):
405  etvalues = thr.thresholdValues
406  for etvalue in etvalues:
407  et = etvalue.value
408  if et < minEt:
409  minEt = et
410  if hasattr(thr, 'et'):
411  if thr.et < minEt:
412  minEt = thr.et
413  if inputtype in thresholdMin:
414  if minEt < thresholdMin[inputtype]:
415  thresholdMin[inputtype] = minEt
416  else:
417  thresholdMin[inputtype] = minEt
418 
419  # loop over sorting algorithms and get the min et values
420  for algo in self.topoAlgos.topoAlgos[AlgCategory.TOPO][AlgType.SORT]:
421  alg = self.topoAlgos.topoAlgos[AlgCategory.TOPO][AlgType.SORT][algo]
422  if alg.inputvalue == 'MuonTobs':
423  continue
424  for (pos, variable) in enumerate(alg.variables):
425  if variable.name == "MinET":
426  value = variable.value/10 # convert energies from 100MeV to GeV units
427  inputtype = ''
428  if alg.inputvalue == 'eEmTobs':
429  inputtype = 'eEM'
430  elif alg.inputvalue == 'eTauTobs':
431  inputtype = 'eTAU'
432  elif alg.inputvalue == 'jJetTobs':
433  inputtype = 'jJ'
434  else:
435  raise RuntimeError("checkPtMinToTopo: input type %s in sorting algo not recognised" % alg.inputvalue)
436  if inputtype in thresholdMin:
437  if value < thresholdMin[inputtype]:
438  thresholdMin[inputtype] = value
439  else:
440  thresholdMin[inputtype] = value
441  for thr in thresholdMin:
442  if thr in ptMin:
443  if thresholdMin[thr] < ptMin[thr]:
444  raise RuntimeError("checkPtMinToTopo: for threshold type %s the minimum threshold %i is less than ptMinToTopo %i" % (thr, thresholdMin[thr], ptMin[thr]))
445  else:
446  raise RuntimeError("checkPtMinToTopo: for threshold type %s the minimum threshold is %i and no ptMinToTopo value is found" % (thr, thresholdMin[thr]))
447 
448  def checkL1TopoParams(self):
449  from ..Menu.L1TopoParams import L1TopoParams as params
450 
451  algo_param_mismatch = []
452  # No need to check multiplicity algs
453  for algtype in [AlgType.SORT, AlgType.DEC]:
454  # Only check Phase-I Topo algs
455  for algname,algo in self.topoAlgos.topoAlgos[AlgCategory.TOPO][algtype].items():
456  log.debug(f'Checking variable parameter ordering for {algname} ({algo.classtype})')
457  pars_for_algo = params[algo.classtype]
458  generics_map = {g.name:g.value for g in algo.generics}
459  # No conditional parameters
460  common_params = None # Common parameters at the beginning, not repeated on multiple algo instances
461  ordered_params = None # Parameters that can be repeated if configuring multiple algo instances
462  if 'common_parameters' in pars_for_algo:
463  common_params = pars_for_algo['common_parameters']
464  if 'parameters' in pars_for_algo:
465  ordered_params = pars_for_algo['parameters']
466  # If all of the param lists are None, we have conditionals
467  if common_params is None and ordered_params is None:
468  for cond in pars_for_algo.keys():
469  if cond == 'comment': continue
470 
471  # Check that the condition is valid
472  pass_condition = True
473  for c in cond.split(' and '):
474  condname, condval = c.split(' = ')
475  if condname in generics_map:
476  if int(condval) == generics_map[condname]:
477  continue
478  else:
479  pass_condition = False
480  break
481  elif int(condval) == 0: # If the generic is not defined, assume that false is ok
482  continue
483  else:
484  pass_condition = False
485  break
486 
487  if pass_condition:
488  if 'common_parameters' in pars_for_algo[cond]:
489  common_params = pars_for_algo[cond]['common_parameters']
490  if 'parameters' in pars_for_algo[cond]:
491  ordered_params = pars_for_algo[cond]['parameters']
492  break
493 
494  if common_params is None and ordered_params is None and common_params is None:
495  raise RuntimeError(f'checkL1TopoParams: Did not find ordered parameter list for L1Topo algorithm type {algo.classtype}')
496 
497  menu_params = [p.name for p in algo.variables]
498  log.debug(f'Menu contains parameter list: {menu_params}')
499 
500  if common_params is None: common_params = []
501  if ordered_params is None: ordered_params = []
502  log.debug(f'Expected parameter list: {common_params + ordered_params}')
503 
504  # Handle case where parameters are supplied repeatedly to
505  # configure multiple instances
506  non_common_param_count = len(menu_params) - len(common_params)
507  if non_common_param_count > len(ordered_params):
508  log.debug(f'Can repeat the parameters: {ordered_params}')
509  if non_common_param_count % len(ordered_params) == 0:
510  ordered_params = int(non_common_param_count/len(ordered_params)) * ordered_params
511  else:
512  log.error("Mismatch in number of parameters")
513 
514  total_params = common_params + ordered_params
515  if menu_params != total_params:
516  log.error(f'checkL1TopoParams: Parameter list for {algo.name}/{algo.classtype} does not match specification')
517  log.error(f' Menu contains parameter list {menu_params}')
518  log.error(f' Expected parameter list {total_params}')
519  algo_param_mismatch.append(algo)
520 
521  if algo_param_mismatch:
522  log.error('checkL1TopoParams: Following L1Topo algorithms have incorrect parameter ordering in L1Menu:')
523  for algo in algo_param_mismatch:
524  log.error(f' {algo.name} ({algo.classtype})')
525  raise RuntimeError('checkL1TopoParams: L1Topo algorithm parameters do not match specification')
526 
528  all_ctpin = []
529  connected_boards = []
530  for layout,connectors in self.ctp.inputConnectors.items():
531  for connector, contents in connectors.items():
532  if layout=='ctpin':
533  # Ignore empty
534  connected_boards += [board for board in contents.values() if board]
535  else:
536  connected_boards.append(contents)
537 
538  for conn_name in connected_boards:
539  conn = self.connectors[conn_name]
540  if conn.ctype != CType.ELEC:
541  for tl in conn.triggerLines:
542  thrName = tl.name
543  if thrName[:3]=='ZB_':
544  thrName = thrName[3:]
545  all_ctpin.append(thrName)
546  else:
547  for fpga in conn.triggerLines:
548  for clock in conn.triggerLines[fpga]:
549  for tl in conn.triggerLines[fpga][clock]:
550  thrName = tl.name
551  if thrName[:3]=='ZB_':
552  thrName = thrName[3:]
553  all_ctpin.append(thrName)
554 
555  for item in self.items:
556  for thrName in item.thresholdNames():
557  if thrName[:3]=='ZB_':
558  thrName = thrName[3:]
559  if thrName not in all_ctpin:
560  raise RuntimeError(
561  f'checkItemsHaveInputs: Threshold {thrName} used by {item.name} is not on a board connected to CTP')
python.L1.Base.L1Menu.L1Menu.flags
flags
Definition: L1Menu.py:31
python.L1.Base.L1Menu.L1Menu.getItem
def getItem(self, name)
Definition: L1Menu.py:68
python.L1.Config.TypeWideThresholdConfig.getTypeWideThresholdConfig
def getTypeWideThresholdConfig(ttype, do_HI_tob_thresholds=False, do_eFex_BDT_Tau=True)
Definition: TypeWideThresholdConfig.py:102
python.L1.Base.L1Menu.L1Menu.thresholds
thresholds
Definition: L1Menu.py:34
python.L1.Base.L1Menu.L1Menu.setBunchGroupSplitting
def setBunchGroupSplitting(self, v=True)
Definition: L1Menu.py:60
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.L1.Base.L1Menu.L1Menu.boards
boards
Definition: L1Menu.py:43
python.L1.Base.L1Menu.L1Menu.ctp
ctp
Definition: L1Menu.py:46
python.L1.Base.TopoAlgorithms.MenuTopoAlgorithmsCollection
Definition: TopoAlgorithms.py:53
python.L1.Base.L1Menu.L1Menu.addThreshold
def addThreshold(self, threshold)
Definition: L1Menu.py:72
python.L1.Base.L1Menu.L1Menu.checkCountCTPInputsOutput
def checkCountCTPInputsOutput(self)
Definition: L1Menu.py:209
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.L1.Base.L1Menu.L1Menu.partitioning
def partitioning()
Definition: L1Menu.py:54
python.L1.Base.L1Menu.L1Menu.checkPerfThresholds
def checkPerfThresholds(self)
Definition: L1Menu.py:137
python.L1.Base.L1Menu.L1Menu.checkBoardInputs
def checkBoardInputs(self, algo, connDefName, fpgaName)
Definition: L1Menu.py:148
python.L1.Base.MenuUtils.get_smk_psk_Name
def get_smk_psk_Name(menuName)
Definition: MenuUtils.py:30
python.L1.Base.L1Menu.L1Menu.addTopoAlgo
def addTopoAlgo(self, algo, category)
Definition: L1Menu.py:76
python.L1.Base.Connectors.MenuConnectorsCollection
Definition: Connectors.py:54
python.L1.Base.L1Menu.L1Menu.checkCTPINconnectors
def checkCTPINconnectors(self)
Definition: L1Menu.py:203
python.L1.Base.L1Menu.L1Menu.topoAlgos
topoAlgos
Definition: L1Menu.py:37
python.L1.Base.Thresholds.MenuThresholdsCollection
Definition: Trigger/TriggerCommon/TriggerMenuMT/python/L1/Base/Thresholds.py:18
python.L1.Base.L1Menu.L1Menu.addConnector
def addConnector(self, connDef)
Definition: L1Menu.py:85
python.L1.Base.L1Menu.L1Menu.checkBGRP
def checkBGRP(self)
Definition: L1Menu.py:362
python.L1.Base.L1Menu.L1Menu.addBoard
def addBoard(self, boardDef)
Definition: L1Menu.py:81
python.L1.Base.CTP.CTP
Definition: CTP.py:13
python.L1.Base.L1Menu.L1Menu.addItem
def addItem(self, item)
Definition: L1Menu.py:64
python.L1.Base.L1Menu.L1Menu.setupCTPMonitoring
def setupCTPMonitoring(self)
Definition: L1Menu.py:89
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
python.L1.Base.L1Menu.L1Menu.checkItemsHaveInputs
def checkItemsHaveInputs(self)
Definition: L1Menu.py:527
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.L1.Base.L1Menu.L1Menu.check
def check(self)
Definition: L1Menu.py:92
library_scraper.dd
list dd
Definition: library_scraper.py:46
python.L1.Base.Items.MenuItemsCollection
Definition: Items.py:17
python.L1.Base.L1Menu.L1Menu.checkL1TopoParams
def checkL1TopoParams(self)
Definition: L1Menu.py:448
python.L1.Base.L1Menu.L1Menu
Definition: L1Menu.py:19
python.L1.Base.L1Menu.L1Menu.connectors
connectors
Definition: L1Menu.py:40
python.L1.Base.L1Menu.L1Menu.checkL1CaloThresholds
def checkL1CaloThresholds(self, thresholds, boardName, connName)
Definition: L1Menu.py:176
pickleTool.object
object
Definition: pickleTool.py:30
python.L1.Base.L1Menu.L1Menu.checkPtMinToTopo
def checkPtMinToTopo(self)
Definition: L1Menu.py:374
python.L1.Base.L1Menu.L1Menu.items
items
Definition: L1Menu.py:28
python.L1.Base.Boards.MenuBoardsCollection
Definition: Boards.py:36
python.L1.Base.L1Menu.L1Menu.menuName
menuName
Definition: L1Menu.py:25
python.L1.Base.L1Menu.L1Menu.__init__
def __init__(self, menuName, flags)
Definition: L1Menu.py:24
python.L1.Base.L1Menu.L1Menu.checkLegacyThresholds
def checkLegacyThresholds(self)
Definition: L1Menu.py:122