ATLAS Offline Software
Loading...
Searching...
No Matches
CmxEnergySubBlock.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <utility>
6
7#include "CmxEnergySubBlock.h"
8
9namespace LVL1BS {
10
11// Constant definitions
12
14
36
45
46
50
54
55// Clear all data
56
62
63// Return energy subsum for given JEM and energy type
64
65unsigned int CmxEnergySubBlock::energy(const int slice, const int jem,
66 const EnergyType eType) const
67{
68 unsigned int e = 0;
69 if (slice >= 0 && slice < timeslices() && !m_sumsData.empty()) {
70 if (jem >= 0 && jem < s_maxJems) {
71 e = m_sumsData[index(slice, jem) + eType] & s_energyJemMask;
72 }
73 }
74 return e;
75}
76
77// Return energy subsum error for given JEM and energy type
78
79int CmxEnergySubBlock::error(const int slice, const int jem,
80 const EnergyType eType) const
81{
82 int parity = 0;
83 if (slice >= 0 && slice < timeslices() && !m_sumsData.empty()) {
84 if (jem >= 0 && jem < s_maxJems) {
85 parity = (m_sumsData[index(slice, jem) + eType] >> s_errorBit)
87 }
88 }
89 return parity << 1;
90}
91
92// Return energy subsum for given source, sum type and energy type
93
94unsigned int CmxEnergySubBlock::energy(const int slice,
95 const SourceType source,
96 const SumType sType,
97 const EnergyType eType) const
98{
99 unsigned int e = 0;
100 if (slice >= 0 && slice < timeslices() && !m_sumsData.empty()) {
101 const int pos = s_maxJems + 2 * source + sType;
102 e = m_sumsData[index(slice, pos) + eType] & s_energySumMask;
103 }
104 return e;
105}
106
107// Return energy subsum error for given source, sum type and energy type
108
110 const SourceType source,
111 const SumType sType,
112 const EnergyType eType) const
113{
114 int parity = 0;
115 int overflow = 0;
116 if (slice >= 0 && slice < timeslices() && !m_sumsData.empty()) {
117 const int pos = s_maxJems + 2 * source + sType;
118 const uint32_t word = m_sumsData[index(slice, pos) + eType];
119 overflow = (word >> s_overflowBit) & s_overflowMask;
120 if (source == REMOTE) parity = (word >> s_errorBit) & s_errorMask;
121 }
122 return (parity << 1) + overflow;
123}
124
125// Return hits map for given hits type and sum type
126
127unsigned int CmxEnergySubBlock::hits(const int slice,
128 const HitsType hType,
129 const SumType sType) const
130{
131 unsigned int map = 0;
132 if (slice >= 0 && slice < timeslices() && !m_sumsData.empty()) {
133 const int pos = s_maxJems + 2 * TOTAL + sType;
134 map = (m_sumsData[index(slice, pos) + hType] >> s_etHitsBit)
135 & s_etHitsMask;
136 }
137 return map;
138}
139
140// Store energy subsums and errors for given JEM
141
142void CmxEnergySubBlock::setSubsums(const int slice, const int jem,
143 const unsigned int ex, const unsigned int ey,
144 const unsigned int et, const int exError,
145 const int eyError, const int etError)
146{
147 if (slice >= 0 && slice < timeslices() && jem >= 0 && jem < s_maxJems) {
148 resize();
149 const int ix = index(slice, jem);
150 unsigned int energy = 0;
151 int error = 0;
152 int parity = 0;
153 uint32_t word = 0;
154 for (int eType = 0; eType < MAX_ENERGY_TYPE; ++eType) {
155 if (eType == ENERGY_EX) {
156 energy = ex;
157 error = exError;
158 } else if (eType == ENERGY_EY) {
159 energy = ey;
160 error = eyError;
161 } else {
162 energy = et;
163 error = etError;
164 }
165 parity = (error >> 1) & s_errorMask;
166 if (energy || parity) {
167 word = energy & s_energyJemMask;
168 word |= parity << s_errorBit;
169 word |= eType << s_energyTypeJemBit;
170 word |= jem << s_jemBit;
171 word |= MODULE_ID << s_wordIdBit;
172 m_sumsData[ix + eType] = word;
173 }
174 }
175 }
176}
177
178// Store energy subsums and errors for given source and sum type
179
180void CmxEnergySubBlock::setSubsums(const int slice, const SourceType source,
181 const SumType sType,
182 const unsigned int ex, const unsigned int ey,
183 const unsigned int et, const int exError,
184 const int eyError, const int etError)
185{
186 if (slice >= 0 && slice < timeslices()) {
187 resize();
188 const int pos = s_maxJems + 2 * source + sType;
189 const int ix = index(slice, pos);
190 unsigned int energy = 0;
191 int error = 0;
192 int overflow = 0;
193 int parity = 0;
194 uint32_t word = 0;
195 uint32_t baseword = (CRATE_SYSTEM_ID << s_wordIdBit) +
196 (source << s_sourceBit) +
197 (sType << s_sumTypeBit);
198 for (int eType = 0; eType < MAX_ENERGY_TYPE; ++eType) {
199 if (eType == ENERGY_EX) {
200 energy = ex;
201 error = exError;
202 } else if (eType == ENERGY_EY) {
203 energy = ey;
204 error = eyError;
205 } else {
206 energy = et;
207 error = etError;
208 }
209 overflow = error & s_overflowMask;
210 parity = (source == REMOTE) ? ((error >> 1) & s_errorMask) : 0;
211 if (energy || overflow || parity) {
212 word = m_sumsData[ix + eType];
213 word |= energy & s_energySumMask;
214 word |= overflow << s_overflowBit;
215 word |= parity << s_errorBit;
216 word |= eType << s_energyTypeBit;
217 word |= baseword;
218 m_sumsData[ix + eType] = word;
219 }
220 }
221 }
222}
223
224// Store hits map for given hits type and sum type
225
226void CmxEnergySubBlock::setEtHits(const int slice, const HitsType hType,
227 const SumType sType, const unsigned int map)
228{
229 if (map && slice >= 0 && slice < timeslices()) {
230 resize();
231 const int pos = s_maxJems + 2 * TOTAL + sType;
232 const int ix = index(slice, pos);
233 uint32_t word = m_sumsData[ix + hType];
234 word |= (map & s_etHitsMask) << s_etHitsBit;
235 word |= hType << s_energyTypeBit;
236 word |= sType << s_sumTypeBit;
237 word |= TOTAL << s_sourceBit;
238 word |= CRATE_SYSTEM_ID << s_wordIdBit;
239 m_sumsData[ix + hType] = word;
240 }
241}
242
243// Packing/Unpacking routines
244
246{
247 bool rc = false;
248 switch (version()) {
249 case 3: //<<== CHECK
250 switch (format()) {
251 case NEUTRAL:
252 rc = packNeutral();
253 break;
254 case UNCOMPRESSED:
256 break;
257 default:
258 break;
259 }
260 break;
261 default:
262 break;
263 }
264 return rc;
265}
266
268{
269 bool rc = false;
270
271 switch (version()) {
272 case 1: //<<== CHECK
273 switch (format()) {
274 case NEUTRAL:
275 rc = unpackNeutral();
276 break;
277 case UNCOMPRESSED:
279 break;
280 default:
282 break;
283 }
284 break;
285 default:
287 break;
288 }
289 return rc;
290}
291
292// Return data index appropriate to format
293
294int CmxEnergySubBlock::index(const int slice, const int pos) const
295{
296 int ix = 3 * pos;
297 if (format() == NEUTRAL) ix += slice * s_maxSums;
298 return ix;
299}
300
301// Resize the sums vector according to format
302
304{
305 if (m_sumsData.empty()) {
306 int size = s_maxSums;
307 if (format() == NEUTRAL) size *= timeslices();
308 m_sumsData.resize(size);
309 }
310}
311
312// Pack neutral data
313
315{
316 resize();
317 const int slices = timeslices();
318 for (int slice = 0; slice < slices; ++slice) {
319 for (int pin = 0; pin < s_maxJems; ++pin) {
320 // JEM energy sums (jem == pin); parity errors
323 packerNeutral(pin, (error(slice, pin, ENERGY_EX) >> 1), 1);
326 packerNeutral(pin, (error(slice, pin, ENERGY_EY) >> 1), 1);
329 packerNeutral(pin, (error(slice, pin, ENERGY_ET) >> 1), 1);
332 packerNeutral(pin, 0, 1);
333 }
334 // Remote Ex, Ey, Et
335 int pin = s_maxJems;
338 packerNeutral(pin, (error(slice, REMOTE, STANDARD, ENERGY_EX) >> 1), 1);
342 ENERGY_EX) >> 1), 1);
343 packerNeutral(pin, (error(slice, REMOTE, STANDARD, ENERGY_EX) & 0x1), 1); // Seems inconsistent with SLink?
346 packerNeutral(pin, (error(slice, REMOTE, STANDARD, ENERGY_EY) >> 1), 1);
350 ENERGY_EY) >> 1), 1);
351 packerNeutral(pin, (error(slice, REMOTE, STANDARD, ENERGY_EY) & 0x1), 1);
354 packerNeutral(pin, 0, 1);
357 packerNeutral(pin, (error(slice, REMOTE, STANDARD, ENERGY_ET) & 0x1), 1);
358 // Local Ex, Ey, Et
359 ++pin;
362 packerNeutral(pin, 0, 1);
365 packerNeutral(pin, 0, 1);
366 packerNeutral(pin, (error(slice, LOCAL, STANDARD, ENERGY_EX) & 0x1), 1);
369 packerNeutral(pin, 0, 1);
372 packerNeutral(pin, 0, 1);
373 packerNeutral(pin, (error(slice, LOCAL, STANDARD, ENERGY_EY) & 0x1), 1);
376 packerNeutral(pin, 0, 1);
379 packerNeutral(pin, (error(slice, LOCAL, STANDARD, ENERGY_ET) & 0x1), 1);
380 // Total Ex, Ey, Et
381 ++pin;
384 packerNeutral(pin, 0, 1);
387 packerNeutral(pin, 0, 1);
388 packerNeutral(pin, (error(slice, TOTAL, STANDARD, ENERGY_EX) & 0x1), 1);
391 packerNeutral(pin, 0, 1);
394 packerNeutral(pin, (error(slice, TOTAL, STANDARD, ENERGY_ET) & 0x1), 1);
395 packerNeutral(pin, (error(slice, TOTAL, STANDARD, ENERGY_EY) & 0x1), 1);
400 // Bunchcrossing number, Fifo overflow
401 ++pin;
403 packerNeutral(pin, daqOverflow(), 1);
404 // Et hit maps
413 // G-Link parity errors
414 for (int p = 0; p <= pin; ++p) packerNeutralParity(p);
415 }
416 return true;
417}
418
419// Pack uncompressed data
420
422{
423 std::vector<uint32_t>::const_iterator pos;
424 for (pos = m_sumsData.begin(); pos != m_sumsData.end(); ++pos) {
425 if (*pos) packer(*pos, s_wordLength);
426 }
427 packerFlush();
428 return true;
429}
430
431// Unpack neutral data
432
434{
435 resize();
436 int bunchCrossing = 0; // BunchCrossing number
437 int overflow = 0; // FIFO overflow
438 int parity = 0; // GLink parity
439 unsigned int en[MAX_ENERGY_TYPE]; // Energies standard
440 unsigned int rn[MAX_ENERGY_TYPE]; // Energies restricted/weighted
441 int er[MAX_ENERGY_TYPE]; // Errors standard (bit 0 overflow, bit 1 parity)
442 int rr[MAX_ENERGY_TYPE]; // Errors restricted/weighted
443 const int slices = timeslices();
444 for (int slice = 0; slice < slices; ++slice) {
445 for (int pin = 0; pin < s_maxJems; ++pin) {
446 // JEM energy sums (jem == pin); parity errors
447 for (int eType = 0; eType < MAX_ENERGY_TYPE; ++eType) {
448 en[eType] = unpackerNeutral(pin, s_jemSumBits);
450 er[eType] = unpackerNeutral(pin, 1) << 1;
451 }
454 unpackerNeutral(pin, 1);
455 setSubsums(slice, pin, en[ENERGY_EX], en[ENERGY_EY], en[ENERGY_ET],
456 er[ENERGY_EX], er[ENERGY_EY], er[ENERGY_ET]);
457 }
458 // Remote Ex, Ey, Et, parity, overflow
459 int pin = s_maxJems;
461 er[ENERGY_EX] = unpackerNeutral(pin, 1) << 1;
462 er[ENERGY_ET] = er[ENERGY_EX];
464 rr[ENERGY_EX] = unpackerNeutral(pin, 1) << 1;
466 er[ENERGY_EX] |= unpackerNeutral(pin, 1); // Or is it both?
468 er[ENERGY_EY] = unpackerNeutral(pin, 1) << 1;
469 er[ENERGY_ET] |= er[ENERGY_EY];
471 rr[ENERGY_EY] = unpackerNeutral(pin, 1) << 1;
473 er[ENERGY_EY] |= unpackerNeutral(pin, 1);
475 unpackerNeutral(pin, 1);
477 er[ENERGY_ET] |= unpackerNeutral(pin, 1);
479 en[ENERGY_EX], en[ENERGY_EY], en[ENERGY_ET],
480 er[ENERGY_EX], er[ENERGY_EY], er[ENERGY_ET]);
482 rn[ENERGY_EX], rn[ENERGY_EY], rn[ENERGY_ET],
484 // Local Ex, Ey, Et, overflow
485 ++pin;
487 unpackerNeutral(pin, 1);
489 unpackerNeutral(pin, 1);
490 er[ENERGY_EX] = unpackerNeutral(pin, 1); // Or is it both?
491 rr[ENERGY_EX] = 0;
493 unpackerNeutral(pin, 1);
495 unpackerNeutral(pin, 1);
496 er[ENERGY_EY] = unpackerNeutral(pin, 1);
497 rr[ENERGY_EY] = 0;
499 unpackerNeutral(pin, 1);
501 er[ENERGY_ET] = unpackerNeutral(pin, 1);
502 rr[ENERGY_ET] = 0;
504 en[ENERGY_EX], en[ENERGY_EY], en[ENERGY_ET],
505 er[ENERGY_EX], er[ENERGY_EY], er[ENERGY_ET]);
507 rn[ENERGY_EX], rn[ENERGY_EY], rn[ENERGY_ET],
509 // Total Ex, Ey, Et, overflow
510 ++pin;
512 unpackerNeutral(pin, 1);
514 unpackerNeutral(pin, 1);
515 er[ENERGY_EX] = unpackerNeutral(pin, 1); // Or is it both?
516 rr[ENERGY_EX] = 0;
518 unpackerNeutral(pin, 1);
520 er[ENERGY_ET] = unpackerNeutral(pin, 1);
521 rr[ENERGY_ET] = 0;
522 er[ENERGY_EY] = unpackerNeutral(pin, 1);
523 rr[ENERGY_EY] = 0;
527 en[ENERGY_EX], en[ENERGY_EY], en[ENERGY_ET],
528 er[ENERGY_EX], er[ENERGY_EY], er[ENERGY_ET]);
530 rn[ENERGY_EX], rn[ENERGY_EY], rn[ENERGY_ET],
532 // Bunchcrossing number, Fifo overflow
533 ++pin;
535 overflow = unpackerNeutral(pin, 1);
536 // Et hit maps
548 // G-Link parity errors
549 for (int p = 0; p <= pin; ++p) parity |= unpackerNeutralParityError(p);
550 }
552 setDaqOverflow(overflow);
553 setGlinkParity(parity);
554
555 const bool rc = unpackerSuccess();
557 return rc;
558}
559
560// Unpack uncompressed data
561
563{
564 resize();
565 unpackerInit();
566 bool error = false;
567 uint32_t word = unpacker(s_wordLength);
568 while (unpackerSuccess()) {
569 if (word) {
570 const int wordId = (word >> s_wordIdBit) & s_wordIdMask;
571 if (wordId == MODULE_ID) {
572 const int jem = (word >> s_jemBit) & s_jemMask;
573 const int eType = (word >> s_energyTypeJemBit) & s_energyTypeMask;
574 const int pos = 3 * jem + eType;
575 if (eType < MAX_ENERGY_TYPE && m_sumsData[pos] == 0) {
576 m_sumsData[pos] = word;
577 } else error = true;
578 } else if (wordId == CRATE_SYSTEM_ID) {
579 const int source = (word >> s_sourceBit) & s_sourceMask;
580 const int sType = (word >> s_sumTypeBit) & s_sumTypeMask;
581 const int eType = (word >> s_energyTypeBit) & s_energyTypeMask;
582 const int pos = 3 * (s_maxJems + 2 * source + sType) + eType;
583 if (source < MAX_SOURCE_TYPE && eType < MAX_ENERGY_TYPE
584 && m_sumsData[pos] == 0) {
585 m_sumsData[pos] = word;
586 } else error = true;
587 } else error = true;
588 if (error) {
590 return false;
591 }
592 }
593 word = unpacker(s_wordLength);
594 }
595 return true;
596}
597
598} // end namespace
const boost::regex rr(r_r)
static Double_t rc
static const uint32_t s_jemMask
unsigned int hits(int slice, HitsType hType, SumType sType) const
Return hits map for given hits type and sum type.
static const uint32_t s_overflowMask
static const uint32_t s_sumTypeMask
static const int s_energyTypeJemBit
static const int s_sumBitsEtCrate
static const uint32_t s_errorMask
static const int s_bunchCrossingBits
static const uint32_t s_energyTypeMask
static const uint32_t s_etHitsMask
static const int s_energyTypeBit
static const int s_jemPaddingBits
static const uint32_t s_energySumMask
void setSubsums(int slice, int jem, unsigned int ex, unsigned int ey, unsigned int et, int exError, int eyError, int etError)
Store energy subsums and errors for given JEM.
static const uint32_t s_sourceMask
void setEtHits(int slice, HitsType hType, SumType sType, unsigned int map)
Store hits map for given hits type and sum type.
bool unpackUncompressed()
Unpack uncompressed data.
static const int s_sumBitsEtSys
bool packUncompressed()
Pack uncompressed data.
bool packNeutral()
Pack neutral data.
static const uint32_t s_energyJemMask
static const int s_wordLength
Data word length.
unsigned int energy(int slice, int jem, EnergyType eType) const
Return energy subsum for given JEM and energy type.
void clear()
Clear all data.
static const uint32_t s_wordIdMask
int index(int slice, int pos) const
bool unpackNeutral()
Unpack neutral data.
std::vector< uint32_t > m_sumsData
Energy subsums data.
int error(int slice, int jem, EnergyType eType) const
Return energy subsum error for given JEM and energy type.
int timeslices() const
void setDaqOverflow(int bit=1)
Set DAQ FIFO Overflow bit in Sub-status word.
void setGlinkParity(int bit=1)
Set G-Link Parity bit in Sub-status word.
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
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.
bool unpackerNeutralParityError(int pin)
Unpack and test G-Link parity bit for given pin.
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)
STL class.
Definition index.py:1
setEventNumber uint32_t
Extra patterns decribing particle interation process.