144 if 'MuCTPi' in connDefName
or 'Legacy' in connDefName:
147 boardName = connDefName+fpgaName
150 allowedInputs[
'Topo1Opt0'] = [
'MU',
'eEM',
'eTAU',
'gJ',
'gLJ',
'ZeroBiasA']
151 allowedInputs[
'Topo1Opt1'] = [
'MU',
'eEM',
'eTAU',
'gJ',
'gLJ', ]
152 allowedInputs[
'Topo1Opt2'] = [
'MU',
'eTAU',
'cTAU',
'j',
'cXE',
'gXE',
'gTE',
'gMHT',
'gESPRESSO',
'LArSaturation',
'ZeroBiasB']
153 allowedInputs[
'Topo1Opt3'] = [
'MU',
'eTAU',
'cTAU',
'j',
'cXE',
'gXE',
'gTE',
'gMHT',
'gESPRESSO',
'gRISTRETTO',
'LArSaturation',
'ZeroBiasB']
154 allowedInputs[
'Topo2El0'] = [
'MU',
'eTAU',
'j', ]
155 allowedInputs[
'Topo2El1'] = [
'eEM',
'j', ]
156 allowedInputs[
'Topo3El0'] = [
'eEM',
'eTAU',
'j', ]
157 allowedInputs[
'Topo3El1'] = [
'MU',
'eEM',
'eTAU',
'g', ]
159 if boardName
not in allowedInputs.keys():
160 raise RuntimeError(
"Connector name %s not found" % boardName )
162 if 'Mult_' in algo.name:
163 if not (any(x
in algo.threshold
for x
in allowedInputs[boardName])):
164 raise RuntimeError(
"Algorithm %s in board %s with threshold %s not allowed" % (algo.name, boardName, algo.threshold ))
166 if 'Mult_' not in algo.name:
167 for algoInput
in algo.inputs:
168 if not (any(x
in algoInput
for x
in allowedInputs[boardName])):
169 raise RuntimeError(
"Algorithm %s in board %s with input %s not allowed" % (algo.name, boardName, algoInput ))
172 fullName = boardName + connName
175 allowedInputs[
'Ctpin7EM1'] = 8*[
'EM']
176 allowedInputs[
'Ctpin7EM2'] = 8*[
'EM']
177 allowedInputs[
'Ctpin7TAU1'] = 8*[
'HA']
178 allowedInputs[
'Ctpin7TAU2'] = 8*[
'HA']
180 allowedInputs[
'Ctpin8JET1'] = 10*[
'J']
181 allowedInputs[
'Ctpin8JET2'] = 15*[
'J']
182 allowedInputs[
'Ctpin8EN1'] = 8*[
'TE'] + 8*[
'XE'] + 8*[
'XS']
183 allowedInputs[
'Ctpin8EN2'] = 8*[
'TE'] + 8*[
'XE']
185 invalidThresholds =
False
186 for ithr,thr
in enumerate(thresholds):
188 allowedThr = allowedInputs[fullName][ithr]
189 if thr[:len(allowedThr)] != allowedThr:
190 log.error(f
"Threshold {thr} does not match expected type {allowedThr} at position {ithr} in connector {fullName}")
191 invalidThresholds =
True
193 log.error(f
"Too many thresholds ({len(thresholds)}) provided for connector {fullName}, which only supports {len(allowedInputs[fullName])} thresholds")
194 invalidThresholds =
True
195 if invalidThresholds:
196 raise RuntimeError(
"Incorrect specification of legacy L1Calo thresholds")
221 from collections
import namedtuple
222 ctpInput = namedtuple(
'ctpInput',
"name, conn, nbit")
227 ctpInputBitSets = dict()
228 ctpInputNameSets = dict()
229 ctpUnusedInputBitSets = dict()
230 ctpUnusedInputNameSets = dict()
231 for item
in self.
items:
232 ctpOutputs.append(item.name)
233 for thrName
in item.thresholdNames():
234 if thrName[:3]==
'ZB_':
235 thrName = thrName[3:]
236 if thrName
not in thrNames:
237 thrNames.append(thrName)
238 thrNames_notFound = []
239 for thrName
in thrNames:
240 thrName_found =
False
242 if conn.ctype != CType.ELEC:
243 for tl
in conn.triggerLines:
244 if thrName == tl.name:
245 ctpInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
248 for fpga
in conn.triggerLines:
249 for clock
in conn.triggerLines[fpga]:
250 for tl
in conn.triggerLines[fpga][clock]:
251 if thrName == tl.name:
252 ctpInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
254 if not thrName_found:
255 thrNames_notFound.append(thrName)
258 if conn.ctype != CType.ELEC:
259 for tl
in conn.triggerLines:
261 if thrName[:3]==
'ZB_':
262 thrName = thrName[3:]
264 for ctpIn
in ctpInputs:
265 if thrName == ctpIn.name:
268 ctpUnusedInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
270 for fpga
in conn.triggerLines:
271 for clock
in conn.triggerLines[fpga]:
272 for tl
in conn.triggerLines[fpga][clock]:
274 if thrName[:3]==
'ZB_':
275 thrName = thrName[3:]
277 for ctpIn
in ctpInputs:
278 if thrName == ctpIn.name:
281 ctpUnusedInputs.append(ctpInput(name=thrName,conn=conn.name,nbit=tl.nbits))
283 if len(thrNames_notFound)>0:
284 log.error(
"Thresholds [%s] are not found",
",".join(thrNames_notFound))
285 log.error(
"Input thresholds are [%s]",
",".join([ input.name
for input
in ctpInputs]))
286 raise RuntimeError(
"Not all input thresholds found!")
288 for ctpIn
in ctpInputs:
291 if thrName[:2]
in [
'EM',
'HA',
'XE',
'TE',
'XS']:
292 thrset =
'legacyCalo'
293 elif thrName[:1]==
'J':
294 thrset =
'legacyCalo'
295 elif thrName[:2]==
'MU':
297 elif thrName[:3]
in [
'MBT',
'AFP',
'BCM',
'CAL',
'NIM',
'ZDC',
'BPT',
'LUC',
'BMA']:
299 elif thrName[:6]==
'R2TOPO':
300 thrset =
'legacyTopo'
301 elif thrName[:1]
in [
'e',
'j',
'c',
'g']:
303 elif thrName[:4]==
'TOPO':
304 if 'Topo2' in ctpIn.conn:
306 elif 'Topo3' in ctpIn.conn:
309 if thrset
not in ctpInputBitSets:
310 ctpInputBitSets[thrset] = 0
311 ctpInputNameSets[thrset] = []
312 if thrName
not in ctpInputNameSets[thrset]:
313 ctpInputNameSets[thrset].append(thrName)
314 ctpInputBitSets[thrset] += ctpIn.nbit
316 for ctpIn
in ctpUnusedInputs:
319 if thrName[:2]
in [
'EM',
'HA',
'XE',
'TE',
'XS']:
320 thrset =
'legacyCalo'
321 elif thrName[:1]==
'J':
322 thrset =
'legacyCalo'
323 elif thrName[:2]==
'MU':
325 elif thrName[:3]
in [
'MBT',
'AFP',
'BCM',
'CAL',
'NIM',
'ZDC',
'BPT',
'LUC']:
327 elif thrName[:6]==
'R2TOPO':
328 thrset =
'legacyTopo'
329 elif thrName[:1]
in [
'e',
'j',
'c',
'g']:
331 elif thrName[:4]==
'TOPO':
332 if 'Topo2' in ctpIn.conn:
334 elif 'Topo3' in ctpIn.conn:
337 if thrset
not in ctpUnusedInputBitSets:
338 ctpUnusedInputBitSets[thrset] = 0
339 ctpUnusedInputNameSets[thrset] = []
340 if thrName
not in ctpUnusedInputNameSets[thrset]:
341 ctpUnusedInputNameSets[thrset].append(thrName)
342 ctpUnusedInputBitSets[thrset] += ctpIn.nbit
345 log.info(
"Check total number of CTP input and output bits:")
346 log.info(
"Number of output bits: %i", len(ctpOutputs) )
347 for thrset
in ctpInputBitSets:
348 log.info(
"Used inputs in %s: %i thresholds and %i bits", thrset, len(ctpInputNameSets[thrset]), ctpInputBitSets[thrset] )
349 if thrset
is not None:
350 log.debug(
"Threshold set %s: %s", thrset,
",".join(ctpInputNameSets[thrset]) )
352 log.info(
"Unrecognised CTP input bits: %s",
",".join(ctpInputNameSets[thrset]) )
353 totalInputs += ctpInputBitSets[thrset]
354 log.info(
"Number of used inputs bits: %i" , totalInputs )
355 totalUnusedInputs = 0
356 for thrset
in ctpUnusedInputBitSets:
357 log.debug(
"Unused thresholds in %s: %i thresholds and %i bits", thrset, len(ctpUnusedInputNameSets[thrset]), ctpUnusedInputBitSets[thrset] )
358 if thrset
is not None:
359 log.debug(
"Unused threshold set %s: %s", thrset,
",".join(ctpUnusedInputNameSets[thrset]) )
361 log.debug(
"Unrecognised CTP input bits: %s",
",".join(ctpUnusedInputNameSets[thrset]) )
362 totalUnusedInputs += ctpUnusedInputBitSets[thrset]
363 log.debug(
"Number of un-used inputs bits: %i" , totalUnusedInputs )
366 if ( totalInputs > Limits.MaxTrigItems
or len(ctpOutputs) > Limits.MaxTrigItems):
368 log.warning(f
"Input or output bits limit of {Limits.MaxTrigItems} exceeded in the dummy CTP menu -- OK")
370 raise RuntimeError(
"Both the numbers of inputs and outputs need to be not greater than %i in a physics menu!" % Limits.MaxTrigItems)
390 for thrtype
in ThrType.Run3Types():
391 ttconfig = getTypeWideThresholdConfig(ttype=thrtype, \
392 do_HI_tob_thresholds=self.
flags.Trigger.L1.Menu.doHeavyIonTobThresholds, \
393 do_eFex_BDT_Tau=self.
flags.Trigger.L1.Menu.doeFexBDTTau, \
394 collisions=self.
flags.Beam.NumberOfCollisions)
395 inputtype = thrtype.name
396 if inputtype ==
'cTAU':
398 for key, value
in ttconfig.items():
399 if "ptMinToTopo" in key:
400 if inputtype
in ptMin:
401 if ptMin[inputtype] > value:
402 ptMin[inputtype] = value
404 ptMin[inputtype] = value
408 for algo
in self.
topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT]:
409 alg = self.
topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT][algo]
410 threshold = alg.threshold
411 inputtype = alg.input
412 if 'cTAU' in inputtype:
414 elif any(substring
in inputtype
for substring
in [
'XE',
'TE',
'MHT',
'ESPRESSO',
'RISTRETTO',
'LArSaturation',
'ZeroBias']):
418 if hasattr(thr,
'thresholdValues'):
419 etvalues = thr.thresholdValues
420 for etvalue
in etvalues:
424 if hasattr(thr,
'et'):
427 if inputtype
in thresholdMin:
428 if minEt < thresholdMin[inputtype]:
429 thresholdMin[inputtype] = minEt
431 thresholdMin[inputtype] = minEt
434 for algo
in self.
topoAlgos.topoAlgos[AlgCategory.TOPO][AlgType.SORT]:
435 alg = self.
topoAlgos.topoAlgos[AlgCategory.TOPO][AlgType.SORT][algo]
436 if alg.inputvalue ==
'MuonTobs':
438 for (pos, variable)
in enumerate(alg.variables):
439 if variable.name ==
"MinET":
440 value = variable.value/10
442 if alg.inputvalue ==
'eEmTobs':
444 elif alg.inputvalue ==
'eTauTobs':
446 elif alg.inputvalue ==
'jJetTobs':
449 raise RuntimeError(
"checkPtMinToTopo: input type %s in sorting algo not recognised" % alg.inputvalue)
450 if inputtype
in thresholdMin:
451 if value < thresholdMin[inputtype]:
452 thresholdMin[inputtype] = value
454 thresholdMin[inputtype] = value
455 for thr
in thresholdMin:
457 if thresholdMin[thr] < ptMin[thr]:
458 raise RuntimeError(
"checkPtMinToTopo: for threshold type %s the minimum threshold %i is less than ptMinToTopo %i" % (thr, thresholdMin[thr], ptMin[thr]))
460 raise RuntimeError(
"checkPtMinToTopo: for threshold type %s the minimum threshold is %i and no ptMinToTopo value is found" % (thr, thresholdMin[thr]))
463 from ..Menu.L1TopoParams
import L1TopoParams
as params
465 algo_param_mismatch = []
467 for algtype
in [AlgType.SORT, AlgType.DEC]:
469 for algname,algo
in self.
topoAlgos.topoAlgos[AlgCategory.TOPO][algtype].
items():
470 log.debug(f
'Checking variable parameter ordering for {algname} ({algo.classtype})')
471 pars_for_algo = params[algo.classtype]
472 generics_map = {g.name:g.value
for g
in algo.generics}
475 ordered_params =
None
476 if 'common_parameters' in pars_for_algo:
477 common_params = pars_for_algo[
'common_parameters']
478 if 'parameters' in pars_for_algo:
479 ordered_params = pars_for_algo[
'parameters']
481 if common_params
is None and ordered_params
is None:
482 for cond
in pars_for_algo.keys():
483 if cond ==
'comment':
continue
486 pass_condition =
True
487 for c
in cond.split(
' and '):
488 condname, condval = c.split(
' = ')
489 if condname
in generics_map:
490 if int(condval) == generics_map[condname]:
493 pass_condition =
False
495 elif int(condval) == 0:
498 pass_condition =
False
502 if 'common_parameters' in pars_for_algo[cond]:
503 common_params = pars_for_algo[cond][
'common_parameters']
504 if 'parameters' in pars_for_algo[cond]:
505 ordered_params = pars_for_algo[cond][
'parameters']
508 if common_params
is None and ordered_params
is None and common_params
is None:
509 raise RuntimeError(f
'checkL1TopoParams: Did not find ordered parameter list for L1Topo algorithm type {algo.classtype}')
511 menu_params = [p.name
for p
in algo.variables]
512 log.debug(f
'Menu contains parameter list: {menu_params}')
514 if common_params
is None: common_params = []
515 if ordered_params
is None: ordered_params = []
516 log.debug(f
'Expected parameter list: {common_params + ordered_params}')
520 non_common_param_count = len(menu_params) - len(common_params)
521 if non_common_param_count > len(ordered_params):
522 log.debug(f
'Can repeat the parameters: {ordered_params}')
523 if non_common_param_count % len(ordered_params) == 0:
524 ordered_params = int(non_common_param_count/len(ordered_params)) * ordered_params
526 log.error(
"Mismatch in number of parameters")
528 total_params = common_params + ordered_params
529 if menu_params != total_params:
530 log.error(f
'checkL1TopoParams: Parameter list for {algo.name}/{algo.classtype} does not match specification')
531 log.error(f
' Menu contains parameter list {menu_params}')
532 log.error(f
' Expected parameter list {total_params}')
533 algo_param_mismatch.append(algo)
535 if algo_param_mismatch:
536 log.error(
'checkL1TopoParams: Following L1Topo algorithms have incorrect parameter ordering in L1Menu:')
537 for algo
in algo_param_mismatch:
538 log.error(f
' {algo.name} ({algo.classtype})')
539 raise RuntimeError(
'checkL1TopoParams: L1Topo algorithm parameters do not match specification')
543 connected_boards = []
544 for layout,connectors
in self.
ctp.inputConnectors.items():
545 for connector, contents
in connectors.items():
548 connected_boards += [board
for board
in contents.values()
if board]
550 connected_boards.append(contents)
552 for conn_name
in connected_boards:
554 if conn.ctype != CType.ELEC:
555 for tl
in conn.triggerLines:
557 if thrName[:3]==
'ZB_':
558 thrName = thrName[3:]
559 all_ctpin.append(thrName)
561 for fpga
in conn.triggerLines:
562 for clock
in conn.triggerLines[fpga]:
563 for tl
in conn.triggerLines[fpga][clock]:
565 if thrName[:3]==
'ZB_':
566 thrName = thrName[3:]
567 all_ctpin.append(thrName)
569 for item
in self.
items:
570 for thrName
in item.thresholdNames():
571 if thrName[:3]==
'ZB_':
572 thrName = thrName[3:]
573 if thrName
not in all_ctpin:
575 f
'checkItemsHaveInputs: Threshold {thrName} used by {item.name} is not on a board connected to CTP')