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', 'eEM3', 'eEM20M', 'eEM24M',
29 'eEM40L',
30
31 # spares
32 ]
33
34 for em in emThresholds_3bits:
35 alg = EMMultiplicityAlgo( name = em,
36 threshold = em,
37 nbits = 3, classtype='eEmMultiplicity')
38 tm.registerTopoAlgo(alg)
39
40 for em in emThresholds_2bits:
41 alg = EMMultiplicityAlgo( name = em,
42 threshold = em,
43 nbits = 2, classtype='eEmMultiplicity')
44 tm.registerTopoAlgo(alg)
45
46 for em in emVarThresholds_2bits:
47 alg = EMMultiplicityAlgo( name = em,
48 threshold = em,
49 nbits = 2, classtype='eEmVarMultiplicity')
50 tm.registerTopoAlgo(alg)
51
52 emThresholds_2bits = [
53 'jEM25', 'jEM20M',
54
55 'jEM35', # prospective Run 4 L1 item, ATR-30180
56 ]
57 for em in emThresholds_2bits:
58 alg = EMMultiplicityAlgo( name = em,
59 threshold = em,
60 nbits = 2, classtype='jEmMultiplicity')
61 tm.registerTopoAlgo(alg)
62
63 etauThresholds_3bits = [
64 'eTAU1', 'eTAU2', 'eTAU12', 'eTAU20', 'eTAU70',
65 ]
66 jtauThresholds_3bits = [
67 'jTAU20'
68 ]
69 ctauThresholds_3bits = [
70 'cTAU12M', 'cTAU20M', 'cTAUSPARE1',
71 ]
72 etauThresholds_2bits = [
73 'eTAU20L', 'eTAU20M', 'eTAU30', 'eTAU30M', 'eTAU35', 'eTAU35M', 'eTAU40HM', 'eTAU60', 'eTAU80', 'eTAU120',
74 'eTAU40HT', 'eTAU60HM','eTAU60HL', 'eTAU80HL',
75 'eTAU28', 'eTAU28M', 'eTAU140', # prospective Run 4 L1 item, ATDAQPPES-19
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 'jJ70', # prospective Run 4 L1 item, ATDAQPPES-19
129 'jJ70p0ETA23', 'jJ80', 'jJ80p0ETA25', 'jJ85p0ETA21',
130 'jJ90', 'jJ125',
131 'jJ140', 'jJ160', 'jJ180', 'jJ500',
132
133 'jJ40p30ETA49', 'jJ50p30ETA49', 'jJ60p30ETA49', 'jJ90p30ETA49', 'jJ125p30ETA49',
134
135 'jJ50p0ETA25',
136
137 'jJ5p30ETA49', 'jJ10p30ETA49',
138
139 'jJ56p0ETA49', # prospective Run 4 L1 item, ATR-30180
140
141 ]
142
143 for jJet in jJThresholds_3bits:
144 alg = JetMultiplicityAlgo( name = jJet,
145 threshold = jJet,
146 nbits = 3, classtype='jJetMultiplicity')
147 tm.registerTopoAlgo(alg)
148
149 for jJet in jJThresholds_2bits:
150 alg = JetMultiplicityAlgo( name = jJet,
151 threshold = jJet,
152 nbits = 2, classtype='jJetMultiplicity')
153 tm.registerTopoAlgo(alg)
154
155
156 gJThresholds_3bits = [ 'gJ20p0ETA25', 'gJ20p25ETA49', 'gJSPARE1', ]
157 gJThresholds_2bits = [ 'gJ50p0ETA25', 'gJ100p0ETA25', 'gJ400p0ETA25' ]
158
159 for gJet in gJThresholds_3bits:
160 alg = JetMultiplicityAlgo( name = gJet,
161 threshold = gJet,
162 nbits = 3, classtype='gJetMultiplicity')
163 tm.registerTopoAlgo(alg)
164
165 for gJet in gJThresholds_2bits:
166 alg = JetMultiplicityAlgo( name = gJet,
167 threshold = gJet,
168 nbits = 2, classtype='gJetMultiplicity')
169 tm.registerTopoAlgo(alg)
170
171 gLJThresholds_2bits = [
172 'gLJ80p0ETA25', 'gLJ100p0ETA25', 'gLJ140p0ETA25', 'gLJ160p0ETA25',
173
174 'gLJ90p0ETA25', # prospective Run 4 L1 item, ATR-30180
175
176 # spares
177 'gLJSPARE1', 'gLJSPARE2', 'gLJSPARE3',
178 ]
179
180 for gLJet in gLJThresholds_2bits:
181 alg = JetMultiplicityAlgo( name = gLJet,
182 threshold = gLJet,
183 nbits = 2, classtype='gLJetMultiplicity')
184 tm.registerTopoAlgo(alg)
185
186 XEThresholds = [
187 'gXEJWOJ60', 'gXEJWOJ70', 'gXEJWOJ80', 'gXEJWOJ100', 'gXEJWOJ110', 'gXEJWOJ120', 'gXEJWOJ500',
188 'gXENC100', 'gXENC110',
189
190 'jXE60', 'jXE70', 'jXE80', 'jXE90', 'jXE100', 'jXE110', 'jXE120', 'jXE500',
191
192 'cXE100', 'cXE110',
193
194 'jXEC100', 'jTE200', 'jTEC200', 'jTEFWD100',
195 'gTE5', 'gTE10', 'gTE200',
196 'gRISTRETTO280', # for HI 25/50ns mixed 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 or 'RISTRETTO' 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!')