ATLAS Offline Software
Loading...
Searching...
No Matches
TopoAlgoDefMultiplicity.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2from collections import namedtuple
3from AthenaCommon.Logging import logging
4log = logging.getLogger(__name__)
5
6from ..Base.TopoAlgos import EMMultiplicityAlgo, TauMultiplicityAlgo, JetMultiplicityAlgo, XEMultiplicityAlgo, LArSaturationAlgo, ZeroBiasAlgo
7from ..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', 'eTAU2', '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', 'eTAU120',
75 'eTAU40HT', 'eTAU60HM','eTAU60HL', 'eTAU80HL',
76 'eTAU28', 'eTAU28M', 'eTAU140', # prospective Run 4 L1 item, ATDAQPPES-19
77 ]
78 jtauThresholds_2bits = [
79 'jTAU1',
80 ]
81 ctauThresholds_2bits = [
82 'cTAU30M', 'cTAU35M', 'cTAU50M',
83
84 # spares
85 'cTAUSPARE2',
86 ]
87
88 for tau in etauThresholds_3bits:
89 alg = TauMultiplicityAlgo( name = tau,
90 threshold = tau,
91 nbits = 3, classtype='eTauMultiplicity')
92 tm.registerTopoAlgo(alg)
93
94 for tau in jtauThresholds_3bits:
95 alg = TauMultiplicityAlgo( name = tau,
96 threshold = tau,
97 nbits = 3, classtype='jTauMultiplicity')
98 tm.registerTopoAlgo(alg)
99
100 for tau in ctauThresholds_3bits:
101 alg = TauMultiplicityAlgo( name = tau,
102 threshold = tau,
103 nbits = 3, classtype='cTauMultiplicity')
104 tm.registerTopoAlgo(alg)
105
106 for tau in etauThresholds_2bits:
107 alg = TauMultiplicityAlgo( name = tau,
108 threshold = tau,
109 nbits = 2, classtype='eTauMultiplicity')
110 tm.registerTopoAlgo(alg)
111
112 for tau in jtauThresholds_2bits:
113 alg = TauMultiplicityAlgo( name = tau,
114 threshold = tau,
115 nbits = 2, classtype='jTauMultiplicity')
116 tm.registerTopoAlgo(alg)
117
118 for tau in ctauThresholds_2bits:
119 alg = TauMultiplicityAlgo( name = tau,
120 threshold = tau,
121 nbits = 2, classtype='cTauMultiplicity')
122 tm.registerTopoAlgo(alg)
123
124
125 jJThresholds_3bits = [
126 'jJ5', 'jJ10', 'jJ20', 'jJ30', 'jJ30p0ETA25', 'jJ40', 'jJ40p0ETA25', 'jJ50', 'jJ55', 'jJ55p0ETA23', 'jJ60',
127 ]
128 jJThresholds_2bits = [
129 'jJ70', # prospective Run 4 L1 item, ATDAQPPES-19
130 'jJ70p0ETA23', 'jJ80', 'jJ80p0ETA25', 'jJ85p0ETA21',
131 'jJ90', 'jJ125',
132 'jJ140', 'jJ160', 'jJ180', 'jJ500',
133
134 'jJ40p30ETA49', 'jJ50p30ETA49', 'jJ60p30ETA49', 'jJ90p30ETA49', 'jJ125p30ETA49',
135
136 'jJ50p0ETA25',
137
138 'jJ5p30ETA49', 'jJ10p30ETA49',
139
140 'jJ56p0ETA49', # prospective Run 4 L1 item, ATR-30180
141
142 ]
143
144 for jJet in jJThresholds_3bits:
145 alg = JetMultiplicityAlgo( name = jJet,
146 threshold = jJet,
147 nbits = 3, classtype='jJetMultiplicity')
148 tm.registerTopoAlgo(alg)
149
150 for jJet in jJThresholds_2bits:
151 alg = JetMultiplicityAlgo( name = jJet,
152 threshold = jJet,
153 nbits = 2, classtype='jJetMultiplicity')
154 tm.registerTopoAlgo(alg)
155
156
157 gJThresholds_3bits = [ 'gJ20p0ETA25', 'gJ20p25ETA49', 'gJSPARE1', ]
158 gJThresholds_2bits = [ 'gJ50p0ETA25', 'gJ100p0ETA25', 'gJ400p0ETA25' ]
159
160 for gJet in gJThresholds_3bits:
161 alg = JetMultiplicityAlgo( name = gJet,
162 threshold = gJet,
163 nbits = 3, classtype='gJetMultiplicity')
164 tm.registerTopoAlgo(alg)
165
166 for gJet in gJThresholds_2bits:
167 alg = JetMultiplicityAlgo( name = gJet,
168 threshold = gJet,
169 nbits = 2, classtype='gJetMultiplicity')
170 tm.registerTopoAlgo(alg)
171
172 gLJThresholds_2bits = [
173 'gLJ80p0ETA25', 'gLJ100p0ETA25', 'gLJ140p0ETA25', 'gLJ160p0ETA25',
174
175 'gLJ90p0ETA25', # prospective Run 4 L1 item, ATR-30180
176
177 # spares
178 'gLJSPARE1', 'gLJSPARE2', 'gLJSPARE3',
179 ]
180
181 for gLJet in gLJThresholds_2bits:
182 alg = JetMultiplicityAlgo( name = gLJet,
183 threshold = gLJet,
184 nbits = 2, classtype='gLJetMultiplicity')
185 tm.registerTopoAlgo(alg)
186
187 XEThresholds = [
188 'gXEJWOJ60', 'gXEJWOJ70', 'gXEJWOJ80', 'gXEJWOJ100', 'gXEJWOJ110', 'gXEJWOJ120', 'gXEJWOJ500',
189 #'gXERHO70', 'gXERHO100',
190 'gXENC70', 'gXENC100',
191
192 'jXE60', 'jXE70', 'jXE80', 'jXE90', 'jXE100', 'jXE110', 'jXE120', 'jXE500',
193
194 'jXEC100', 'jTE200', 'jTEC200', 'jTEFWD100', 'jTEFWDA100', 'jTEFWDC100',
195 'gTE5', 'gTE10', 'gTE200',
196 'gTE280', # gRISTRETTO280 - for HI 25ns bunch spacing test
197 'gESPRESSO280',
198 # additional jTE thresholds needed for heavy ion runs
199 'jTE3','jTE4','jTE5', 'jTE10', 'jTE20','jTE50',
200 'jTE100', 'jTE600', 'jTE1500', 'jTE4000', 'jTE6500',
201 'jTEFWDA1', 'jTEFWDC1', 'jTEFWDA5', 'jTEFWDC5', 'jTEFWD2600', 'jTEFWD5600', 'jTEFWD6300', 'jTEFWD6600',
202
203 'gMHT500',
204
205 'jXEPerf100',
206
207 # spares (for any energy thresholds)
208 ]
209
210 for XE in XEThresholds:
211 alg = XEMultiplicityAlgo( name = XE,
212 threshold = XE,
213 nbits = 1)
214 tm.registerTopoAlgo(alg)
215
216 tm.registerTopoAlgo(LArSaturationAlgo())
217
218 tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasA"))
219 tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasB"))
220
221
222 @staticmethod
224 """
225 List of the constraints in terms of multiplicity algorithms, to make sure the menu fits
226 in the Topo1 FW.
227
228 The Phase-I L1Topo boards contain 2 FPGAs, with 2 output fibers each (connected to the CTP).
229 Up to 96 bits per fiber.
230 """
231
232 # Any changes in this mapping intended for use in P1 require changes in the L1Topo firmware!
233
234 # If you include additional algorithms to the L1 MC Menu only for development and tests in Athena,
235 # that will still require reserving additional space space in each fiber for the new thrsholds.
236 # Please add them to the end of each fiber, and label those lines.
237
238 # Thresholds containing "Perf" in the name are explicitly for development only within Athena,
239 # and don't require declaring dedicated bits (they're ignored by this check)
240
241 multLimits = namedtuple('ML', ['thrtype', 'conn', 'nbit', 'startbit', 'endbit'])
242 multiplicities = [
243 # FPGA 0, Topo1 fiber 0
244 multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=3, startbit=0, endbit=11),
245 multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=2, startbit=24, endbit=43),
246 multLimits(thrtype='eEMV', conn='Topo1Opt0', nbit=2, startbit=44, endbit=63),
247 multLimits(thrtype='ZeroBiasA', conn='Topo1Opt0', nbit=1, startbit=64, endbit=64),
248
249 # FPGA 0, Topo1 fiber 1
250 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=3, startbit=0, endbit=8 ),
251 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=12, endbit=35),
252 multLimits(thrtype='gLJ', conn='Topo1Opt1', nbit=2, startbit=40, endbit=55),
253 multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=3, startbit=58, endbit=66),
254 multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=2, startbit=70, endbit=75),
255 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=78, endbit=81), # L1 MC pp Menu only
256
257 # FPGA 1, Topo1 fiber 2
258 multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=3, startbit=0, endbit=32),
259 multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=2, startbit=36, endbit=73),
260
261 # FPGA 1, Topo1 fiber 3
262 multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=3, startbit=0, endbit=2 ),
263 multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=2, startbit=6, endbit=7 ),
264 multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=3, startbit=14, endbit=22),
265 multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=2, startbit=23, endbit=30),
266 multLimits(thrtype='jEM', conn='Topo1Opt3', nbit=2, startbit=31, endbit=36),
267 multLimits(thrtype='LArSaturation', conn='Topo1Opt3', nbit=1, startbit=37, endbit=37),
268 multLimits(thrtype='ZeroBiasB', conn='Topo1Opt3', nbit=1, startbit=38, endbit=38),
269 multLimits(thrtype='EN', conn='Topo1Opt3', nbit=1, startbit=39, endbit=86),
270 ]
271
272 for conn in l1menu.connectors:
273 if 'Topo1' not in conn.name or conn.legacy: continue
274
275 for tl in conn.triggerLines:
276 if 'Perf' in tl.name: continue
277
278 algo = l1menu.topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT][f'Mult_{tl.name}']
279
280 thrtype = algo.input
281 if 'LArSaturation' in algo.name:
282 thrtype = 'LArSaturation'
283 elif 'XE' in algo.input or 'TE' in algo.input or 'MHT' in algo.input or 'ESPRESSO' in algo.input:
284 thrtype = 'EN'
285 elif 'eEmVar' in algo.classtype:
286 thrtype = 'eEMV'
287
288 for ml in multiplicities:
289 if conn.name == ml.conn and thrtype == ml.thrtype and algo.nbits == ml.nbit and tl.startbit >= ml.startbit and tl.endbit <= ml.endbit:
290 break
291 else:
292 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.')
293
294 # To ensure the correct alignment, also check for the Empty and (Empty, nbits) instances in the L1 Menu input fibers
295 for etl in conn.emptyTriggerLines:
296 log.debug('Empty Multiplicity placeholder in bits %i-%i of %s', etl.startbit, etl.endbit, conn.name)
297 for ml in multiplicities:
298 # We don't want to have any overlaps with the multiplicity declarations
299 if conn.name == ml.conn and etl.startbit >= ml.startbit and etl.endbit <= ml.endbit:
300 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!')