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 'gXENC100', 'gXENC110',
190
191 'jXE60', 'jXE70', 'jXE80', 'jXE90', 'jXE100', 'jXE110', 'jXE120', 'jXE500',
192
193 'cXE100', 'cXE110',
194
195 'jXEC100', 'jTE200', 'jTEC200', 'jTEFWD100',
196 'gTE5', 'gTE10', 'gTE200',
197 'gTE280', # gRISTRETTO280 - for HI 25ns bunch spacing test
198 'gESPRESSO280',
199 # additional jTE thresholds needed for heavy ion runs
200 'jTE3','jTE4','jTE5', 'jTE10', 'jTE20','jTE50',
201 'jTE100', 'jTE600', 'jTE1500', 'jTE4000', 'jTE6500',
202 'jTEFWDA1', 'jTEFWDC1', 'jTEFWDA5', 'jTEFWDC5', 'jTEFWD2600', 'jTEFWD5600', 'jTEFWD6300', 'jTEFWD6600',
203
204 'gMHT500',
205
206 'jXEPerf100',
207
208 # spares (for any energy thresholds)
209 ]
210
211 for XE in XEThresholds:
212 alg = XEMultiplicityAlgo( name = XE,
213 threshold = XE,
214 nbits = 1)
215 tm.registerTopoAlgo(alg)
216
217 tm.registerTopoAlgo(LArSaturationAlgo())
218
219 tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasA"))
220 tm.registerTopoAlgo(ZeroBiasAlgo("ZeroBiasB"))
221
222
223 @staticmethod
225 """
226 List of the constraints in terms of multiplicity algorithms, to make sure the menu fits
227 in the Topo1 FW.
228
229 The Phase-I L1Topo boards contain 2 FPGAs, with 2 output fibers each (connected to the CTP).
230 Up to 96 bits per fiber.
231 """
232
233 # Any changes in this mapping intended for use in P1 require changes in the L1Topo firmware!
234
235 # If you include additional algorithms to the L1 MC Menu only for development and tests in Athena,
236 # that will still require reserving additional space space in each fiber for the new thrsholds.
237 # Please add them to the end of each fiber, and label those lines.
238
239 # Thresholds containing "Perf" in the name are explicitly for development only within Athena,
240 # and don't require declaring dedicated bits (they're ignored by this check)
241
242 multLimits = namedtuple('ML', ['thrtype', 'conn', 'nbit', 'startbit', 'endbit'])
243 multiplicities = [
244 # FPGA 0, Topo1 fiber 0
245 multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=3, startbit=0, endbit=11),
246 multLimits(thrtype='eEM', conn='Topo1Opt0', nbit=2, startbit=24, endbit=43),
247 multLimits(thrtype='eEMV', conn='Topo1Opt0', nbit=2, startbit=44, endbit=63),
248 multLimits(thrtype='ZeroBiasA', conn='Topo1Opt0', nbit=1, startbit=64, endbit=64),
249
250 # FPGA 0, Topo1 fiber 1
251 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=3, startbit=0, endbit=8 ),
252 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=12, endbit=35),
253 multLimits(thrtype='gLJ', conn='Topo1Opt1', nbit=2, startbit=40, endbit=55),
254 multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=3, startbit=58, endbit=66),
255 multLimits(thrtype='gJ', conn='Topo1Opt1', nbit=2, startbit=70, endbit=75),
256 multLimits(thrtype='eTAU', conn='Topo1Opt1', nbit=2, startbit=78, endbit=81), # L1 MC pp Menu only
257
258 # FPGA 1, Topo1 fiber 2
259 multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=3, startbit=0, endbit=32),
260 multLimits(thrtype='jJ', conn='Topo1Opt2', nbit=2, startbit=36, endbit=73),
261
262 # FPGA 1, Topo1 fiber 3
263 multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=3, startbit=0, endbit=2 ),
264 multLimits(thrtype='jTAU', conn='Topo1Opt3', nbit=2, startbit=6, endbit=7 ),
265 multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=3, startbit=14, endbit=22),
266 multLimits(thrtype='cTAU', conn='Topo1Opt3', nbit=2, startbit=23, endbit=30),
267 multLimits(thrtype='jEM', conn='Topo1Opt3', nbit=2, startbit=31, endbit=36),
268 multLimits(thrtype='LArSaturation', conn='Topo1Opt3', nbit=1, startbit=37, endbit=37),
269 multLimits(thrtype='ZeroBiasB', conn='Topo1Opt3', nbit=1, startbit=38, endbit=38),
270 multLimits(thrtype='EN', conn='Topo1Opt3', nbit=1, startbit=39, endbit=86),
271 ]
272
273 for conn in l1menu.connectors:
274 if 'Topo1' not in conn.name or conn.legacy: continue
275
276 for tl in conn.triggerLines:
277 if 'Perf' in tl.name: continue
278
279 algo = l1menu.topoAlgos.topoAlgos[AlgCategory.MULTI][AlgType.MULT][f'Mult_{tl.name}']
280
281 thrtype = algo.input
282 if 'LArSaturation' in algo.name:
283 thrtype = 'LArSaturation'
284 elif 'XE' in algo.input or 'TE' in algo.input or 'MHT' in algo.input or 'ESPRESSO' in algo.input:
285 thrtype = 'EN'
286 elif 'eEmVar' in algo.classtype:
287 thrtype = 'eEMV'
288
289 for ml in multiplicities:
290 if conn.name == ml.conn and thrtype == ml.thrtype and algo.nbits == ml.nbit and tl.startbit >= ml.startbit and tl.endbit <= ml.endbit:
291 break
292 else:
293 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.')
294
295 # To ensure the correct alignment, also check for the Empty and (Empty, nbits) instances in the L1 Menu input fibers
296 for etl in conn.emptyTriggerLines:
297 log.debug('Empty Multiplicity placeholder in bits %i-%i of %s', etl.startbit, etl.endbit, conn.name)
298 for ml in multiplicities:
299 # We don't want to have any overlaps with the multiplicity declarations
300 if conn.name == ml.conn and etl.startbit >= ml.startbit and etl.endbit <= ml.endbit:
301 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!')