ATLAS Offline Software
TopoAlgoDefMultiplicity.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 from collections import namedtuple
3 from AthenaCommon.Logging import logging
4 log = logging.getLogger(__name__)
5 
6 from ..Base.TopoAlgos import EMMultiplicityAlgo, TauMultiplicityAlgo, JetMultiplicityAlgo, XEMultiplicityAlgo, LArSaturationAlgo, ZeroBiasAlgo
7 from ..Base.TopoAlgorithms import AlgType, AlgCategory
8 
10  """
11  Defines the TopoAlgorithms that calculate multiplicities for L1Calo thresholds
12  The thresholds have to be explicitly defined here.
13  """
14  @staticmethod
16 
17  emThresholds_3bits = [
18  'eEM5', 'eEM7', 'eEM9', 'eEM10L',
19  ]
20  emThresholds_2bits = [
21  'eEM12L', 'eEM15', 'eEM18', 'eEM18L', 'eEM18M', 'eEM22M',
22  'eEM24L',
23  'eEM22A', 'eEM22C',
24  'eEM12',
25  ]
26  emVarThresholds_2bits = [
27  'eEM24VM', 'eEM26', 'eEM26L', 'eEM26M', 'eEM26T', 'eEM28M',
28  'eEM1', 'eEM2', 'eEM20M', 'eEM24M',
29  'eEM40L',
30 
31  # spares
32  'eEMSPARE1',
33  ]
34 
35  for em in emThresholds_3bits:
36  alg = EMMultiplicityAlgo( name = em,
37  threshold = em,
38  nbits = 3, classtype='eEmMultiplicity')
39  tm.registerTopoAlgo(alg)
40 
41  for em in emThresholds_2bits:
42  alg = EMMultiplicityAlgo( name = em,
43  threshold = em,
44  nbits = 2, classtype='eEmMultiplicity')
45  tm.registerTopoAlgo(alg)
46 
47  for em in emVarThresholds_2bits:
48  alg = EMMultiplicityAlgo( name = em,
49  threshold = em,
50  nbits = 2, classtype='eEmVarMultiplicity')
51  tm.registerTopoAlgo(alg)
52 
53  emThresholds_2bits = [
54  'jEM25', 'jEM20M',
55 
56  'jEM35', # prospective Run 4 L1 item, ATR-30180
57  ]
58  for em in emThresholds_2bits:
59  alg = EMMultiplicityAlgo( name = em,
60  threshold = em,
61  nbits = 2, classtype='jEmMultiplicity')
62  tm.registerTopoAlgo(alg)
63 
64  etauThresholds_3bits = [
65  'eTAU1', 'eTAU12', 'eTAU20', 'eTAU70',
66  ]
67  jtauThresholds_3bits = [
68  'jTAU20'
69  ]
70  ctauThresholds_3bits = [
71  'cTAU12M', 'cTAU20M', 'cTAUSPARE1',
72  ]
73  etauThresholds_2bits = [
74  'eTAU20L', 'eTAU20M', 'eTAU30', 'eTAU30M', 'eTAU35', 'eTAU35M', 'eTAU40HM', 'eTAU60', 'eTAU80', 'eTAU140',
75  'eTAU40HT', 'eTAU60HM','eTAU60HL', 'eTAU80HL',
76  ]
77  jtauThresholds_2bits = [
78  'jTAU1',
79  ]
80  ctauThresholds_2bits = [
81  'cTAU30M', 'cTAU35M', 'cTAU50M',
82 
83  # spares
84  'cTAUSPARE2',
85  ]
86 
87  for tau in etauThresholds_3bits:
88  alg = TauMultiplicityAlgo( name = tau,
89  threshold = tau,
90  nbits = 3, classtype='eTauMultiplicity')
91  tm.registerTopoAlgo(alg)
92 
93  for tau in jtauThresholds_3bits:
94  alg = TauMultiplicityAlgo( name = tau,
95  threshold = tau,
96  nbits = 3, classtype='jTauMultiplicity')
97  tm.registerTopoAlgo(alg)
98 
99  for tau in ctauThresholds_3bits:
100  alg = TauMultiplicityAlgo( name = tau,
101  threshold = tau,
102  nbits = 3, classtype='cTauMultiplicity')
103  tm.registerTopoAlgo(alg)
104 
105  for tau in etauThresholds_2bits:
106  alg = TauMultiplicityAlgo( name = tau,
107  threshold = tau,
108  nbits = 2, classtype='eTauMultiplicity')
109  tm.registerTopoAlgo(alg)
110 
111  for tau in jtauThresholds_2bits:
112  alg = TauMultiplicityAlgo( name = tau,
113  threshold = tau,
114  nbits = 2, classtype='jTauMultiplicity')
115  tm.registerTopoAlgo(alg)
116 
117  for tau in ctauThresholds_2bits:
118  alg = TauMultiplicityAlgo( name = tau,
119  threshold = tau,
120  nbits = 2, classtype='cTauMultiplicity')
121  tm.registerTopoAlgo(alg)
122 
123 
124  jJThresholds_3bits = [
125  'jJ5', 'jJ10', 'jJ20', 'jJ30', 'jJ30p0ETA25', 'jJ40', 'jJ40p0ETA25', 'jJ50', 'jJ55', 'jJ55p0ETA23', 'jJ60',
126  ]
127  jJThresholds_2bits = [
128  'jJ70p0ETA23', 'jJ80', 'jJ80p0ETA25', 'jJ85p0ETA21',
129  'jJ90', 'jJ125',
130  'jJ140', 'jJ160', 'jJ180', 'jJ500',
131 
132  'jJ40p30ETA49', 'jJ50p30ETA49', 'jJ60p30ETA49', 'jJ90p30ETA49', 'jJ125p30ETA49',
133 
134  'jJ50p0ETA25',
135 
136  'jJ5p30ETA49', 'jJ10p30ETA49',
137 
138  'jJ56p0ETA49', # prospective Run 4 L1 item, ATR-30180
139 
140  ]
141 
142  for jJet in jJThresholds_3bits:
143  alg = JetMultiplicityAlgo( name = jJet,
144  threshold = jJet,
145  nbits = 3, classtype='jJetMultiplicity')
146  tm.registerTopoAlgo(alg)
147 
148  for jJet in jJThresholds_2bits:
149  alg = JetMultiplicityAlgo( name = jJet,
150  threshold = jJet,
151  nbits = 2, classtype='jJetMultiplicity')
152  tm.registerTopoAlgo(alg)
153 
154 
155  gJThresholds_3bits = [ 'gJ20p0ETA25', 'gJ20p25ETA49', 'gJSPARE1', ]
156  gJThresholds_2bits = [ 'gJ50p0ETA25', 'gJ100p0ETA25', 'gJ400p0ETA25' ]
157 
158  for gJet in gJThresholds_3bits:
159  alg = JetMultiplicityAlgo( name = gJet,
160  threshold = gJet,
161  nbits = 3, classtype='gJetMultiplicity')
162  tm.registerTopoAlgo(alg)
163 
164  for gJet in gJThresholds_2bits:
165  alg = JetMultiplicityAlgo( name = gJet,
166  threshold = gJet,
167  nbits = 2, classtype='gJetMultiplicity')
168  tm.registerTopoAlgo(alg)
169 
170  gLJThresholds_2bits = [
171  'gLJ80p0ETA25', 'gLJ100p0ETA25', 'gLJ140p0ETA25', 'gLJ160p0ETA25',
172 
173  'gLJ90p0ETA25', # prospective Run 4 L1 item, ATR-30180
174 
175  # spares
176  'gLJSPARE1', 'gLJSPARE2', 'gLJSPARE3',
177  ]
178 
179  for gLJet in gLJThresholds_2bits:
180  alg = JetMultiplicityAlgo( name = gLJet,
181  threshold = gLJet,
182  nbits = 2, classtype='gLJetMultiplicity')
183  tm.registerTopoAlgo(alg)
184 
185  XEThresholds = [
186  'gXEJWOJ60', 'gXEJWOJ70', 'gXEJWOJ80', 'gXEJWOJ100', 'gXEJWOJ110', 'gXEJWOJ120', 'gXEJWOJ500',
187  #'gXERHO70', 'gXERHO100',
188  'gXENC70', 'gXENC100',
189 
190  'jXE60', 'jXE70', 'jXE80', 'jXE90', 'jXE100', 'jXE110', 'jXE120', 'jXE500',
191 
192  'jXEC100', 'jTE200', 'jTEC200', 'jTEFWD100', 'jTEFWDA100', 'jTEFWDC100',
193  'gTE3', 'gTE5', 'gTE10', 'gTE200',
194 
195  # additional jTE thresholds needed for heavy ion runs
196  'jTE3','jTE4','jTE5', 'jTE10', 'jTE20','jTE50',
197  'jTE100', 'jTE600', 'jTE1500', 'jTE4000', 'jTE6500', 'jTE8300', 'jTE9000', 'jTE10000', 'jTE12000',
198  'jTEFWDA1', 'jTEFWDC1', 'jTEFWDA5', 'jTEFWDC5', 'jTEFWD8300',
199 
200  'gMHT500',
201 
202  'jXEPerf100',
203 
204  # spares (for any energy thresholds)
205  ]
206 
207  for XE in XEThresholds:
208  alg = XEMultiplicityAlgo( name = XE,
209  threshold = XE,
210  nbits = 1)
211  tm.registerTopoAlgo(alg)
212 
213  tm.registerTopoAlgo(LArSaturationAlgo())
214 
215  tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasA"))
216  tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasB"))
217 
218 
219  @staticmethod
221  """
222  List of the constraints in terms of multiplicity algorithms, to make sure the menu fits
223  in the Topo1 FW.
224 
225  The Phase-I L1Topo boards contain 2 FPGAs, with 2 output fibers each (connected to the CTP).
226  Up to 96 bits per fiber.
227  """
228 
229  # Any changes in this mapping intended for use in P1 require changes in the L1Topo firmware!
230 
231  # If you include additional algorithms to the L1 MC Menu only for development and tests in Athena,
232  # that will still require reserving additional space space in each fiber for the new thrsholds.
233  # Please add them to the end of each fiber, and label those lines.
234 
235  # Thresholds containing "Perf" in the name are explicitly for development only within Athena,
236  # and don't require declaring dedicated bits (they're ignored by this check)
237 
238  multLimits = namedtuple('ML', ['thrtype', 'conn', 'nbit', 'startbit', 'endbit'])
239  multiplicities = [
240  # FPGA 0, Topo1 fiber 0
241  multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=3, startbit=0, endbit=11),
242  multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=2, startbit=24, endbit=43),
243  multLimits(thrtype='eEMV', conn='Topo1Opt0', nbit=2, startbit=44, endbit=63),
244  multLimits(thrtype='ZeroBiasA', conn='Topo1Opt0', nbit=1, startbit=64, endbit=64),
245 
246  # FPGA 0, Topo1 fiber 1
247  multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=3, startbit=0, endbit=8 ),
248  multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=12, endbit=35),
249  multLimits(thrtype='gLJ', conn='Topo1Opt1', nbit=2, startbit=40, endbit=55),
250  multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=3, startbit=58, endbit=66),
251  multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=2, startbit=70, endbit=75),
252  multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=78, endbit=81), # L1 MC pp Menu only
253 
254  # FPGA 1, Topo1 fiber 2
255  multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=3, startbit=0, endbit=32),
256  multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=2, startbit=36, endbit=73),
257 
258  # FPGA 1, Topo1 fiber 3
259  multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=3, startbit=0, endbit=2 ),
260  multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=2, startbit=6, endbit=7 ),
261  multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=3, startbit=14, endbit=22),
262  multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=2, startbit=23, endbit=30),
263  multLimits(thrtype='jEM', conn='Topo1Opt3', nbit=2, startbit=31, endbit=36),
264  multLimits(thrtype='LArSaturation', conn='Topo1Opt3', nbit=1, startbit=37, endbit=37),
265  multLimits(thrtype='ZeroBiasB', conn='Topo1Opt3', nbit=1, startbit=38, endbit=38),
266  multLimits(thrtype='EN', conn='Topo1Opt3', nbit=1, startbit=39, endbit=86),
267  ]
268 
269  for conn in l1menu.connectors:
270  if 'Topo1' not in conn.name or conn.legacy: continue
271 
272  for tl in conn.triggerLines:
273  if 'Perf' in tl.name: continue
274 
275  algo = l1menu.topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT][f'Mult_{tl.name}']
276 
277  thrtype = algo.input
278  if 'LArSaturation' in algo.name:
279  thrtype = 'LArSaturation'
280  elif 'XE' in algo.input or 'TE' in algo.input or 'MHT' in algo.input:
281  thrtype = 'EN'
282  elif 'eEmVar' in algo.classtype:
283  thrtype = 'eEMV'
284 
285  for ml in multiplicities:
286  if conn.name == ml.conn and thrtype == ml.thrtype and algo.nbits == ml.nbit and tl.startbit >= ml.startbit and tl.endbit <= ml.endbit:
287  break
288  else:
289  raise RuntimeError(f'The multiplicity algorithm {algo.name} with startbit {tl.startbit} does not fit in the current Topo1 and CTP FWs. If this is intended, please correct the multiplicity constraints and communicate the new menu to the L1Topo and CTP groups.')
290 
291  # To ensure the correct alignment, also check for the Empty and (Empty, nbits) instances in the L1 Menu input fibers
292  for etl in conn.emptyTriggerLines:
293  log.debug('Empty Multiplicity placeholder in bits %i-%i of %s', etl.startbit, etl.endbit, conn.name)
294  for ml in multiplicities:
295  # We don't want to have any overlaps with the multiplicity declarations
296  if conn.name == ml.conn and etl.startbit >= ml.startbit and etl.endbit <= ml.endbit:
297  raise RuntimeError(f'One of the Empty or (Empty, nbits) Multiplicity algorithm placeholders in the L1 Menu is overlapping with the declared multiplicity algorithm bit ranges ({conn.name}, bits {etl.startbit}-{etl.endbit}). Check the bit mapping and algorithm alignments!')
python.L1.Base.TopoAlgos.JetMultiplicityAlgo
Definition: TopoAlgos.py:225
python.L1.Base.TopoAlgos.TauMultiplicityAlgo
Definition: TopoAlgos.py:215
python.L1.Base.TopoAlgos.XEMultiplicityAlgo
Definition: TopoAlgos.py:235
python.L1.Base.TopoAlgos.ZeroBiasAlgo
Definition: TopoAlgos.py:267
python.L1.Config.TopoAlgoDefMultiplicity.TopoAlgoDefMultiplicity
Definition: TopoAlgoDefMultiplicity.py:9
python.L1.Base.TopoAlgos.LArSaturationAlgo
Definition: TopoAlgos.py:262
python.L1.Config.TopoAlgoDefMultiplicity.TopoAlgoDefMultiplicity.registerTopoAlgos
def registerTopoAlgos(tm)
Definition: TopoAlgoDefMultiplicity.py:15
python.L1.Config.TopoAlgoDefMultiplicity.TopoAlgoDefMultiplicity.checkMultAlgoFWconstraints
def checkMultAlgoFWconstraints(l1menu)
Definition: TopoAlgoDefMultiplicity.py:220
python.L1.Base.TopoAlgos.EMMultiplicityAlgo
Definition: TopoAlgos.py:205