ATLAS Offline Software
Loading...
Searching...
No Matches
JemSubBlock.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 "JemSubBlock.h"
8
9namespace LVL1BS {
10
11// Constant definitions
12
14
16
20
30
31const int JemSubBlock::s_exBit;
32const int JemSubBlock::s_eyBit;
33const int JemSubBlock::s_etBit;
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 JemSubBlock::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
80void JemSubBlock::fillJetElement(const int slice, const JemJetElement& jetEle)
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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::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 JemSubBlock::index(const int slice) const
247{
248 return (format() == NEUTRAL) ? slice : 0;
249}
250
251// Resize a data vector according to format
252
253void JemSubBlock::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
static const int s_eyBit
Definition JemSubBlock.h:84
static const int s_sourceIdBit
Definition JemSubBlock.h:74
static const int s_jeWordId
Definition JemSubBlock.h:70
int sourceId(uint32_t word) const
void setJemHeader(int version, int format, int slice, int crate, int module, int timeslices)
Store JEM header.
static const int s_jetHitsBits
Definition JemSubBlock.h:96
std::vector< uint32_t > m_jetHits
Jet hit counts.
static const int s_exBit
Definition JemSubBlock.h:83
static const int s_jetIndicatorBit
Definition JemSubBlock.h:75
static const uint32_t s_etMask
Definition JemSubBlock.h:91
int dataId(uint32_t word) const
void fillJetElement(int slice, const JemJetElement &jetEle)
Store jet element data.
static const uint32_t s_eyMask
Definition JemSubBlock.h:90
bool packUncompressed()
Pack uncompressed data.
static const int s_hitPaddingBits
Definition JemSubBlock.h:99
bool unpack()
Unpack data.
static const int s_jetElementBits
Definition JemSubBlock.h:94
static const int s_sumIndicatorBit
Definition JemSubBlock.h:86
bool unpackNeutral()
Unpack neutral data.
static const int s_dataIdBit
Definition JemSubBlock.h:69
bool pack()
Pack data.
static const uint32_t s_dataIdMask
Definition JemSubBlock.h:71
static const uint32_t s_threshMask
Definition JemSubBlock.h:80
static const int s_threshBit
Definition JemSubBlock.h:73
static const int s_sumIndicator
Definition JemSubBlock.h:87
int index(int slice) const
static const int s_wordLength
Data word length.
Definition JemSubBlock.h:67
std::vector< uint32_t > m_jeData
Jet element data.
unsigned int ex(int slice) const
Return energy subsum Ex.
static const int s_wordIdVal
JEM header word ID.
Definition JemSubBlock.h:65
bool unpackUncompressed()
Unpack uncompressed data.
static const int s_mainThreshId
Definition JemSubBlock.h:77
int timeslices() const
Return number of timeslices.
bool packNeutral()
Pack neutral data.
void clear()
Clear all data.
void setJetHits(int slice, unsigned int hits)
Store jet hit counts.
unsigned int jetHits(int slice) const
Return jet hit counts.
unsigned int et(int slice) const
Return energy subsum Et.
void resize(std::vector< uint32_t > &vec, int channels=1)
static const int s_energyBits
Definition JemSubBlock.h:97
static const int s_etBit
Definition JemSubBlock.h:85
static const int s_pairsPerPin
Definition JemSubBlock.h:93
static const int s_bunchCrossingBits
Definition JemSubBlock.h:98
static const int s_jetIndicator
Definition JemSubBlock.h:76
std::vector< uint32_t > m_energySubsums
Energy subsum data.
static const int s_mainFwdThreshId
Definition JemSubBlock.h:78
static const int s_subsumId
Definition JemSubBlock.h:88
static const uint32_t s_exMask
Definition JemSubBlock.h:89
static const uint32_t s_sourceIdMask
Definition JemSubBlock.h:81
static const int s_glinkBitsPerSlice
static const uint32_t s_threshWordId
Definition JemSubBlock.h:79
int m_channels
Number of jet element channels.
unsigned int ey(int slice) const
Return energy subsum Ey.
void setEnergySubsums(int slice, unsigned int ex, unsigned int ey, unsigned int et)
Store energy subsum data.
static const int s_jePaddingBits
Definition JemSubBlock.h:95
JemJetElement jetElement(int slice, int channel) const
Return jet element for given channel.
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)