15#include <fmt/format.h>
26 mChannelsInitialized(false)
32 mMinorDecodingErrors.clear();
42 gsl::span<const uint32_t> payloadwords(payloadwordsOrig.data(), payloadwordsOrig.size());
49void AltroDecoder::checkRCUTrailer()
53 if (trailersize > buffersize) {
60 mChannelsInitialized =
false;
66 while (currentpos < maxpayloadsize) {
67 auto currentword =
buffer[currentpos++];
68 if (currentword >> 30 != 1) {
73 auto channelheader = currentword;
74 int32_t hwaddress = channelheader & 0xFFF;
75 uint16_t payloadsize = (channelheader >> 16) & 0x3FF;
76 bool badchannel = (channelheader >> 29) & 0x1;
79 if (!checkChannelHWAddress(hwaddress)) {
87 if (currentfec < lastFEC) {
96 bool foundChannelError =
false;
97 int numberofwords = (payloadsize + 2) / 3;
98 std::vector<uint16_t> bunchwords;
99 for (
int iword = 0; iword < numberofwords; iword++) {
100 if (currentpos >= maxpayloadsize) {
102 foundChannelError =
true;
105 currentword =
buffer[currentpos++];
106 if ((currentword >> 30) != 0) {
109 foundChannelError =
true;
113 bunchwords.push_back((currentword >> 20) & 0x3FF);
114 bunchwords.push_back((currentword >> 10) & 0x3FF);
115 bunchwords.push_back(currentword & 0x3FF);
117 if (foundChannelError) {
122 mChannels.emplace_back(hwaddress, payloadsize);
123 auto& currentchannel = mChannels.back();
124 currentchannel.setBadChannel(badchannel);
127 int currentsample = 0;
128 while (currentsample < currentchannel.getPayloadSize() && bunchwords.size() > currentsample + 2) {
130 if (bunchwords[currentsample] == 0) {
134 int bunchlength = bunchwords[currentsample] - 2,
135 starttime = bunchwords[currentsample + 1];
137 if ((
unsigned long)bunchlength > bunchwords.size() - currentsample - 2) {
143 if ((
unsigned int)bunchlength > mMaxBunchLength) {
149 if ((
unsigned int)starttime > mMaxBunchLength) {
154 if (bunchlength == 0) {
159 currentsample += bunchlength + 2;
162 auto& currentbunch = currentchannel.createBunch(bunchlength, starttime);
163 currentbunch.initFromRange(gsl::span<uint16_t>(&bunchwords[currentsample + 2], std::min((
unsigned long)bunchlength, bunchwords.size() - currentsample - 2)));
164 currentsample += bunchlength + 2;
167 mChannelsInitialized =
true;
170bool AltroDecoder::checkChannelHWAddress(
int hwaddress)
182 if (!(altro == 0 || altro == 2 || altro == 3 || altro == 4)) {
199 if (!mChannelsInitialized) {
210 int errorNumber = -1;
213 case AltroErrType::RCU_TRAILER_ERROR:
216 case AltroErrType::RCU_VERSION_ERROR:
219 case AltroErrType::RCU_TRAILER_SIZE_ERROR:
222 case AltroErrType::ALTRO_BUNCH_HEADER_ERROR:
225 case AltroErrType::ALTRO_BUNCH_LENGTH_ERROR:
228 case AltroErrType::ALTRO_PAYLOAD_ERROR:
231 case AltroErrType::ALTRO_MAPPING_ERROR:
234 case AltroErrType::CHANNEL_ERROR:
251 switch (errornumber) {
253 errorType = AltroErrType::RCU_TRAILER_ERROR;
256 errorType = AltroErrType::RCU_VERSION_ERROR;
259 errorType = AltroErrType::RCU_TRAILER_SIZE_ERROR;
262 errorType = AltroErrType::ALTRO_BUNCH_HEADER_ERROR;
265 errorType = AltroErrType::ALTRO_BUNCH_LENGTH_ERROR;
268 errorType = AltroErrType::ALTRO_PAYLOAD_ERROR;
271 errorType = AltroErrType::ALTRO_MAPPING_ERROR;
274 errorType = AltroErrType::CHANNEL_ERROR;
286 case AltroErrType::RCU_TRAILER_ERROR:
287 return "RCUTrailerError";
288 case AltroErrType::RCU_VERSION_ERROR:
289 return "RCUTrailerVersionError";
290 case AltroErrType::RCU_TRAILER_SIZE_ERROR:
291 return "RCUTrailerSizeError";
292 case AltroErrType::ALTRO_BUNCH_HEADER_ERROR:
293 return "BunchHeaderError";
294 case AltroErrType::ALTRO_BUNCH_LENGTH_ERROR:
295 return "BunchLengthError";
296 case AltroErrType::ALTRO_PAYLOAD_ERROR:
297 return "ALTROPayloadError";
298 case AltroErrType::ALTRO_MAPPING_ERROR:
299 return "ALTROMappingError";
300 case AltroErrType::CHANNEL_ERROR:
301 return "ChannelError";
309 case AltroErrType::RCU_TRAILER_ERROR:
310 return "RCU Trailer";
311 case AltroErrType::RCU_VERSION_ERROR:
312 return "RCU Version";
313 case AltroErrType::RCU_TRAILER_SIZE_ERROR:
314 return "RCU Trailer Size";
315 case AltroErrType::ALTRO_BUNCH_HEADER_ERROR:
316 return "ALTRO Bunch Header";
317 case AltroErrType::ALTRO_BUNCH_LENGTH_ERROR:
318 return "ALTRO Bunch Length";
319 case AltroErrType::ALTRO_PAYLOAD_ERROR:
320 return "ALTRO Payload";
321 case AltroErrType::ALTRO_MAPPING_ERROR:
322 return "ALTRO Mapping";
323 case AltroErrType::CHANNEL_ERROR:
332 case AltroErrType::RCU_TRAILER_ERROR:
333 return "RCU trailer decoding error";
334 case AltroErrType::RCU_VERSION_ERROR:
335 return "Inconsistent RCU trailer version";
336 case AltroErrType::RCU_TRAILER_SIZE_ERROR:
337 return "Invalid RCU trailer size";
338 case AltroErrType::ALTRO_BUNCH_HEADER_ERROR:
339 return "Inconsistent bunch header";
340 case AltroErrType::ALTRO_BUNCH_LENGTH_ERROR:
341 return "Bunch length exceeding payload size";
342 case AltroErrType::ALTRO_PAYLOAD_ERROR:
343 return "Payload could not be decoded";
344 case AltroErrType::ALTRO_MAPPING_ERROR:
345 return "Invalid hardware address in ALTRO mapping";
346 case AltroErrType::CHANNEL_ERROR:
347 return "Channels not initizalized";
356 auto address = mChannelHeader & 0xFFF,
357 payload = (mChannelHeader >> 16) & 0x3FF;
358 bool good = (mChannelHeader >> 29) & 0x1;
360 result <<
" Channel header=0x" << std::hex << mChannelHeader
361 <<
" (Address=0x" <<
address <<
", payload " << std::dec << payload <<
", good " << (good ?
"yes" :
"no") <<
")"
362 <<
", word=0x" << std::hex << mPayloadWord << std::dec;
371 int errorNumber = -1;
374 case MinorAltroErrType::CHANNEL_END_PAYLOAD_UNEXPECT:
377 case MinorAltroErrType::CHANNEL_PAYLOAD_EXCEED:
380 case MinorAltroErrType::CHANNEL_ORDER:
383 case MinorAltroErrType::CHANNEL_HEADER:
386 case MinorAltroErrType::BUNCH_HEADER_NULL:
389 case MinorAltroErrType::BUNCH_LENGTH_EXCEED:
392 case MinorAltroErrType::BUNCH_LENGTH_ALLOW_EXCEED:
395 case MinorAltroErrType::BUNCH_STARTTIME:
408 switch (errornumber) {
410 errorType = MinorAltroErrType::CHANNEL_END_PAYLOAD_UNEXPECT;
413 errorType = MinorAltroErrType::CHANNEL_PAYLOAD_EXCEED;
416 errorType = MinorAltroErrType::CHANNEL_ORDER;
419 errorType = MinorAltroErrType::CHANNEL_HEADER;
422 errorType = MinorAltroErrType::BUNCH_HEADER_NULL;
425 errorType = MinorAltroErrType::BUNCH_LENGTH_EXCEED;
428 errorType = MinorAltroErrType::BUNCH_LENGTH_ALLOW_EXCEED;
431 errorType = MinorAltroErrType::BUNCH_STARTTIME;
443 case MinorAltroErrType::CHANNEL_END_PAYLOAD_UNEXPECT:
444 return "ChannelEndPayloadUnexpected";
445 case MinorAltroErrType::CHANNEL_PAYLOAD_EXCEED:
446 return "ChannelPayloadExceed";
447 case MinorAltroErrType::CHANNEL_ORDER:
448 return "ChannelOrderError";
449 case MinorAltroErrType::CHANNEL_HEADER:
450 return "ChannelHeader";
451 case MinorAltroErrType::BUNCH_HEADER_NULL:
452 return "BunchHeaderNull";
453 case MinorAltroErrType::BUNCH_LENGTH_EXCEED:
454 return "BunchLengthExceed";
455 case MinorAltroErrType::BUNCH_LENGTH_ALLOW_EXCEED:
456 return "BunchLengthAllowExceed";
457 case MinorAltroErrType::BUNCH_STARTTIME:
458 return "BunchStarttimeExceed";
466 case MinorAltroErrType::CHANNEL_END_PAYLOAD_UNEXPECT:
467 return "Channel end unexpected";
468 case MinorAltroErrType::CHANNEL_PAYLOAD_EXCEED:
469 return "Channel exceed";
470 case MinorAltroErrType::CHANNEL_ORDER:
472 case MinorAltroErrType::CHANNEL_HEADER:
473 return "Channel header invalid";
474 case MinorAltroErrType::BUNCH_HEADER_NULL:
475 return "Bunch header null";
476 case MinorAltroErrType::BUNCH_LENGTH_EXCEED:
477 return "Bunch length exceed";
478 case MinorAltroErrType::BUNCH_LENGTH_ALLOW_EXCEED:
479 return "Bunch length impossible";
480 case MinorAltroErrType::BUNCH_STARTTIME:
481 return "Bunch starttime exceed";
489 case MinorAltroErrType::CHANNEL_END_PAYLOAD_UNEXPECT:
490 return "Unexpected end of payload in altro channel payload!";
491 case MinorAltroErrType::CHANNEL_PAYLOAD_EXCEED:
492 return "Trying to access out-of-bound payload!";
493 case MinorAltroErrType::CHANNEL_ORDER:
494 return "Invalid FEC order";
495 case MinorAltroErrType::CHANNEL_HEADER:
496 return "Invalid channel header";
497 case MinorAltroErrType::BUNCH_HEADER_NULL:
498 return "Bunch header 0 or not configured!";
499 case MinorAltroErrType::BUNCH_LENGTH_EXCEED:
500 return "Bunch length exceeding channel payload size!";
501 case MinorAltroErrType::BUNCH_LENGTH_ALLOW_EXCEED:
502 return "Bunch length exceeding max. possible bunch size!";
503 case MinorAltroErrType::BUNCH_STARTTIME:
504 return "Bunch start time outside range!";
Error handling of the ALTRO Decoder.
ErrorType_t
Error codes connected with the ALTRO decoding.
@ RCU_TRAILER_SIZE_ERROR
RCU trailer size length.
@ CHANNEL_ERROR
Channels not initialized.
@ RCU_TRAILER_ERROR
RCU trailer cannot be decoded or invalid.
static int errorTypeToInt(ErrorType_t errortype)
convert the error type from symoblic constant into int
static ErrorType_t intToErrorType(int errornumber)
convert the error from number into a type (symbolic constant)
static constexpr int getNumberOfErrorTypes() noexcept
Get the number of error types handled by the AltroDecoderError.
static const char * getErrorTypeTitle(ErrorType_t errortype)
Get the title connected to the error type.
const char * what() const noexcept override
Access to error message cnnected to the error.
static const char * getErrorTypeDescription(ErrorType_t errortype)
Get the description connected to the error type.
static const char * getErrorTypeName(ErrorType_t errortype)
Get the name connected to the error type.
void decode()
Decode the ALTRO stream.
const RCUTrailer & getRCUTrailer() const
Get reference to the RCU trailer object.
void readRCUTrailer()
Read RCU trailer for the current event in the raw buffer.
const std::vector< Channel > & getChannels() const
Get the reference to the channel container.
AltroDecoder(RawReaderMemory &reader)
Constructor.
void readChannels()
Read channels for the current event in the raw buffer.
static int getAltroIndexFromHwAddress(int hwaddress)
Extracting ALTRO index from the hardware address.
static int getFecIndexFromHwAddress(int hwaddress)
Extracting FEC index in branch from the hardware address.
static int getBranchIndexFromHwAddress(int hwaddress)
Extracting branch index from the hardware address.
Error handling for the ALTRO decoder for non-crashing errors.
static const char * getErrorTypeTitle(ErrorType_t errortype)
Get the title connected to the error type.
ErrorType_t
Error codes connected with the ALTRO decoding.
@ CHANNEL_ORDER
Channels not in increasing order.
@ BUNCH_LENGTH_ALLOW_EXCEED
Exceeds maximum allowed bunch length.
@ BUNCH_STARTTIME
Bunch start time exceeding.
@ BUNCH_LENGTH_EXCEED
Bunch length exceeding channel payload size.
@ CHANNEL_END_PAYLOAD_UNEXPECT
Unexpected end of payload (channel or trailer word in bunch words)
@ CHANNEL_PAYLOAD_EXCEED
Exceeding channel payload block.
@ BUNCH_HEADER_NULL
Bunch header is 0.
static ErrorType_t intToErrorType(int errornumber)
convert the error from number into a type (symbolic constant)
static int errorTypeToInt(ErrorType_t errortype)
convert the error type from symoblic constant into int
static const char * getErrorTypeDescription(ErrorType_t errortype)
Get the description connected to the error type.
std::string what() const noexcept
Create and return error message for different error types.
static const char * getErrorTypeName(ErrorType_t errortype)
Get the name connected to the error type.
static constexpr int getNumberOfErrorTypes() noexcept
Get the number of error types handled by the AltroDecoderError.
Error handling of the RCU trailer.
const char * what() const noexcept override
Access to the error message.
Information stored in the RCU trailer.
void constructFromRawPayload(const gsl::span< const uint32_t > payloadwords)
Decode RCU trailer from the 32-bit words in the raw buffer.
uint32_t getTrailerSize() const
Get the trailer size in number of DDL (32 bit) words.
bool isInitialized() const
checlks whether the RCU trailer is initialzied
const std::vector< uint32_t > & getPayloadWords() const
Get the payload words (as 32 bit words) contributing to the current payload.
Reader for raw data produced by the Readout application in in-memory format.
const RawPayload & getPayload() const
access to the full raw payload (single or multiple DMA pages)
GLuint GLuint64EXT address
std::ostream & operator<<(std::ostream &stream, const Cell &cell)
Stream operator for EMCAL cell.