ATLAS Offline Software
Loading...
Searching...
No Matches
JemSubBlockV1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include "JemJetElement.h"
7#include "JemSubBlockV1.h"
8
9namespace LVL1BS {
10
11// Constant definitions
12
14
16
20
30
40
49
50
54
58
59// Clear all data
60
62{
64 m_jeData.clear();
65 m_jetHits.clear();
66 m_energySubsums.clear();
67}
68
69// Store JEM header
70
71void JemSubBlockV1::setJemHeader(const int version, const int format,
72 const int slice, const int crate,
73 const int module, const int timeslices)
74{
76}
77
78// Store jet element data
79
81{
82 if (jetEle.data()) {
83 const int channel = jetEle.channel();
84 if (channel < 0) [[unlikely]] {return;}
85 if (channel < m_channels) {
87 m_jeData[index(slice)*m_channels + channel] = jetEle.data();
88 }
89 }
90}
91
92// Store jet hit counts
93
94void JemSubBlockV1::setJetHits(const int slice, const unsigned int hits)
95{
96 if (hits) {
97 const int jem = module();
98 const int sourceId = (jem == 0 || jem == 7 || jem == 8 || jem == 15)
100 uint32_t word = 0;
101 word |= (hits & s_threshMask) << s_threshBit;
104 word |= s_threshWordId << s_dataIdBit;
106 m_jetHits[index(slice)] = word;
107 }
108}
109
110// Store energy subsum data
111
112void JemSubBlockV1::setEnergySubsums(const int slice, const unsigned int ex,
113 const unsigned int ey, const unsigned int et)
114{
115 uint32_t word = 0;
116 word |= (ex & s_exMask) << s_exBit;
117 word |= (ey & s_eyMask) << s_eyBit;
118 word |= (et & s_etMask) << s_etBit;
119 if (word) {
121 word |= s_subsumId << s_sourceIdBit;
122 word |= s_threshWordId << s_dataIdBit;
124 m_energySubsums[index(slice)] = word;
125 }
126}
127
128// Return jet element for given channel
129
130JemJetElement JemSubBlockV1::jetElement(const int slice, const int channel) const
131{
132 uint32_t je = 0;
133 if (slice >= 0 && slice < timeslices() &&
134 channel >= 0 && channel < m_channels && !m_jeData.empty()) {
135 je = m_jeData[index(slice)*m_channels + channel];
136 }
137 return JemJetElement(je);
138}
139
140// Return jet hit counts
141
142unsigned int JemSubBlockV1::jetHits(const int slice) const
143{
144 unsigned int hits = 0;
145 if (slice >= 0 && slice < timeslices() && !m_jetHits.empty()) {
147 }
148 return hits;
149}
150
151// Return energy subsum Ex
152
153unsigned int JemSubBlockV1::ex(const int slice) const
154{
155 unsigned int ex = 0;
156 if (slice >= 0 && slice < timeslices() && !m_energySubsums.empty()) {
158 }
159 return ex;
160}
161
162// Return energy subsum Ey
163
164unsigned int JemSubBlockV1::ey(const int slice) const
165{
166 unsigned int ey = 0;
167 if (slice >= 0 && slice < timeslices() && !m_energySubsums.empty()) {
169 }
170 return ey;
171}
172
173// Return energy subsum Et
174
175unsigned int JemSubBlockV1::et(const int slice) const
176{
177 unsigned int et = 0;
178 if (slice >= 0 && slice < timeslices() && !m_energySubsums.empty()) {
180 }
181 return et;
182}
183
184// Return number of timeslices
185
187{
188 int slices = slices1();
189 if (slices == 0 && format() == NEUTRAL) {
190 slices = dataWords() / s_glinkBitsPerSlice;
191 }
192 if (slices == 0) slices = 1;
193 return slices;
194}
195
196// Packing/Unpacking routines
197
199{
200 bool rc = false;
201 switch (version()) {
202 case 1:
203 switch (format()) {
204 case NEUTRAL:
205 rc = packNeutral();
206 break;
207 case UNCOMPRESSED:
209 break;
210 default:
211 break;
212 }
213 break;
214 default:
215 break;
216 }
217 return rc;
218}
219
221{
222 bool rc = false;
223 switch (version()) {
224 case 1:
225 switch (format()) {
226 case NEUTRAL:
227 rc = unpackNeutral();
228 break;
229 case UNCOMPRESSED:
231 break;
232 default:
234 break;
235 }
236 break;
237 default:
239 break;
240 }
241 return rc;
242}
243
244// Return data index appropriate to format
245
246int JemSubBlockV1::index(const int slice) const
247{
248 return (format() == NEUTRAL) ? slice : 0;
249}
250
251// Resize a data vector according to format
252
253void JemSubBlockV1::resize(std::vector<uint32_t>& vec, const int channels)
254{
255 if (vec.empty()) {
256 int size = channels;
257 if (format() == NEUTRAL) size *= timeslices();
258 vec.resize(size);
259 }
260}
261
262// Pack neutral data
263
265{
269 const int slices = timeslices();
270 for (int slice = 0; slice < slices; ++slice) {
271 // Jet element data
272 for (int channel = 0; channel < m_channels; ++channel) {
273 const int pin = channel / s_pairsPerPin;
274 const JemJetElement je = jetElement(slice, channel);
276 packerNeutral(pin, je.emParity(), 1);
277 packerNeutral(pin, je.linkError(), 1);
279 packerNeutral(pin, je.hadParity(), 1);
280 packerNeutral(pin, (je.linkError() >> 1), 1);
281 }
282 // Pad out last jet element pin
283 int lastpin = (m_channels - 1) / s_pairsPerPin;
284 packerNeutral(lastpin, 0, s_jePaddingBits);
285 // Jet Hits and Energy Sums with parity bits
286 ++lastpin;
292 int parity = parityBit(1, ex(slice), s_energyBits);
293 parity = parityBit(parity, ey(slice), s_energyBits);
294 parity = parityBit(parity, et(slice), s_energyBits);
295 packerNeutral(lastpin, parity, 1);
296 // Bunch Crossing number and padding
298 packerNeutral(lastpin, 0, s_hitPaddingBits);
299 // G-Link parity
300 for (int pin = 0; pin <= lastpin; ++pin) packerNeutralParity(pin);
301 }
302 return true;
303}
304
305// Pack uncompressed data
306
308{
309 // Jet element data
310 std::vector<uint32_t>::const_iterator pos;
311 for (pos = m_jeData.begin(); pos != m_jeData.end(); ++pos) {
312 if (*pos) packer(*pos, s_wordLength);
313 }
314
315 // Hits and Subsum data
316 if ( !m_jetHits.empty() && m_jetHits[0]) packer(m_jetHits[0], s_wordLength);
317 if ( !m_energySubsums.empty() && m_energySubsums[0]) {
319 }
320 packerFlush();
321 return true;
322}
323
324// Unpack neutral data
325
327{
331 const int slices = timeslices();
332 for (int slice = 0; slice < slices; ++slice) {
333 // Jet element data
334 for (int channel = 0; channel < m_channels; ++channel) {
335 const int pin = channel / s_pairsPerPin;
336 const int emData = unpackerNeutral(pin, s_jetElementBits);
337 const int emParity = unpackerNeutral(pin, 1);
338 int linkError = unpackerNeutral(pin, 1);
339 const int hadData = unpackerNeutral(pin, s_jetElementBits);
340 const int hadParity = unpackerNeutral(pin, 1);
341 linkError |= unpackerNeutral(pin, 1) << 1;
342 const JemJetElement je(channel, emData, hadData, emParity,
343 hadParity, linkError);
345 }
346 // Padding from last jet element pin
347 int lastpin = (m_channels - 1) / s_pairsPerPin;
349 // Jet Hits and Energy Sums
350 ++lastpin;
352 unpackerNeutral(lastpin, 1); // parity bit
353 const unsigned int ex = unpackerNeutral(lastpin, s_energyBits);
354 const unsigned int ey = unpackerNeutral(lastpin, s_energyBits);
355 const unsigned int et = unpackerNeutral(lastpin, s_energyBits);
357 unpackerNeutral(lastpin, 1); // parity bit
358 // Bunch Crossing number and padding
361 // G-Link parity errors
362 for (int pin = 0; pin <= lastpin; ++pin) unpackerNeutralParityError(pin);
363 }
364 const bool rc = unpackerSuccess();
366 return rc;
367}
368
369// Unpack uncompressed data
370
372{
376 unpackerInit();
377 uint32_t word = unpacker(s_wordLength);
378 while (unpackerSuccess()) {
379 const int id = dataId(word);
380 bool err = false;
381 // Jet element data
382 if (id == s_jeWordId) {
383 const JemJetElement jetEle(word);
384 const int channel = jetEle.channel();
385 if (channel < m_channels && m_jeData[channel] == 0) {
386 m_jeData[channel] = word;
387 } else err = true;
388 // Other data
389 } else {
390 switch (sourceId(word)) {
391 // Jet hit counts/thresholds
392 case s_mainThreshId:
393 case s_mainFwdThreshId: {
394 if (m_jetHits[0] == 0) m_jetHits[0] = word;
395 else err = true;
396 break;
397 }
398 // Energy subsums
399 case s_subsumId: {
400 if (m_energySubsums[0] == 0) m_energySubsums[0] = word;
401 else err = true;
402 break;
403 }
404 default:
405 err = true;
406 break;
407 }
408 }
409 if (err) {
411 return false;
412 }
413 word = unpacker(s_wordLength);
414 }
415 return true;
416}
417
418} // end namespace
std::vector< size_t > vec
static Double_t rc
JEM jet element dataword class.
uint32_t data() const
std::vector< uint32_t > m_energySubsums
Energy subsum data.
static const int s_sumIndicator
static const int s_glinkBitsPerSlice
std::vector< uint32_t > m_jetHits
Jet hit counts.
int timeslices() const
Return number of timeslices.
bool packNeutral()
Pack neutral data.
static const int s_mainThreshId
static const int s_pairsPerPin
void clear()
Clear all data.
int index(int slice) const
void fillJetElement(int slice, const JemJetElement &jetEle)
Store jet element data.
static const uint32_t s_threshWordId
std::vector< uint32_t > m_jeData
Jet element data.
bool pack()
Pack data.
void setJemHeader(int version, int format, int slice, int crate, int module, int timeslices)
Store JEM header.
unsigned int et(int slice) const
Return energy subsum Et.
static const int s_jetIndicator
static const int s_mainFwdThreshId
static const int s_jetIndicatorBit
static const int s_jeWordId
unsigned int jetHits(int slice) const
Return jet hit counts.
int sourceId(uint32_t word) const
static const int s_sourceIdBit
void resize(std::vector< uint32_t > &vec, int channels=1)
static const uint32_t s_eyMask
static const int s_exBit
static const int s_wordIdVal
JEM header word ID.
static const uint32_t s_sourceIdMask
bool unpackUncompressed()
Unpack uncompressed data.
static const uint32_t s_etMask
static const int s_jetElementBits
static const uint32_t s_exMask
static const int s_wordLength
Data word length.
bool packUncompressed()
Pack uncompressed data.
static const int s_hitPaddingBits
bool unpackNeutral()
Unpack neutral data.
JemJetElement jetElement(int slice, int channel) const
Return jet element for given channel.
static const uint32_t s_threshMask
static const int s_energyBits
static const int s_jePaddingBits
static const int s_jetHitsBits
static const int s_eyBit
static const int s_etBit
static const int s_bunchCrossingBits
unsigned int ex(int slice) const
Return energy subsum Ex.
static const int s_dataIdBit
static const int s_subsumId
int m_channels
Number of jet element channels.
bool unpack()
Unpack data.
void setJetHits(int slice, unsigned int hits)
Store jet hit counts.
static const uint32_t s_dataIdMask
static const int s_sumIndicatorBit
void setEnergySubsums(int slice, unsigned int ex, unsigned int ey, unsigned int et)
Store energy subsum data.
int dataId(uint32_t word) const
static const int s_threshBit
unsigned int ey(int slice) const
Return energy subsum Ey.
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
int parityBit(int init, uint32_t datum, int nbits) const
Return the parity bit for given data.
uint32_t unpacker(int nbits)
Unpack given number of bits of data.
void setUnpackErrorCode(int code)
Set the unpacking error code.
bool unpackerSuccess() const
Return unpacker success flag.
void setHeader(int wordId, int version, int format, int seqno, int crate, int module, int slices2, int slices1)
Store header data.
bool unpackerNeutralParityError(int pin)
Unpack and test G-Link parity bit for given pin.
int dataWords() const
Return number of data words.
void clear()
Clear all data.
void packerNeutralParity(int pin)
Pack current G-Link parity bit for given pin.
void packerFlush()
Flush the current data word padded with zeros.
uint32_t unpackerNeutral(int pin, int nbits)
Unpack given number of bits of neutral data for given pin.
int bunchCrossing() const
Return the Bunch Crossing number (neutral format only)
void unpackerInit()
Initialise unpacker.
void packerNeutral(int pin, uint32_t datum, int nbits)
Pack given neutral data from given pin.
void setBunchCrossing(int bc)
Set the Bunch Crossing number (neutral format only)
Definition index.py:1
setEventNumber uint32_t
#define unlikely(x)