19 channelData_(config_.channelMax),
20 commonModeIndex_(config_.channelMax),
21 commonModeData_(config_.commonModeMax) {}
25 const std::vector<uint32_t>& inputArray,
26 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
31 commonModeDataSize_ = 0;
34 for (uint32_t iword = 0; iword < inputArray.size();) {
36 if (((inputArray[iword] >> kSLinkBOEShift) & kSLinkBOEMask) != config_.sLinkBOE)
38 <<
"Expected a S-Link header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword <<
" (BOE: 0x" 39 << config_.sLinkBOE <<
"), got 0x" << inputArray[iword] <<
".";
43 LogDebug(
"HGCalUnpack") <<
"SLink=" << sLink;
46 for (uint8_t captureBlock = 0; captureBlock < config_.sLinkCaptureBlockMax;
49 if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) !=
50 config_.captureBlockReserved)
52 <<
"Expected a capture block header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword
53 <<
" (reserved word: 0x" << config_.captureBlockReserved <<
"), got 0x" << inputArray[iword] <<
".";
58 LogDebug(
"HGCalUnpack") <<
"Capture block=" << (
int)captureBlock <<
", capture block header=0x" << std::hex
59 << captureBlockHeader;
62 for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) {
63 if (((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) >= 0b100)
68 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
70 <<
"Expected a ECON-D header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword
71 <<
" (marker: 0x" << config_.econdHeaderMarker <<
"), got 0x" << inputArray[iword] <<
".";
73 const auto& econdHeader = inputArray[iword];
76 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", first word of ECON-D header=0x" << std::hex
80 const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask;
81 if (payloadLength > config_.payloadLengthMax)
82 throw cms::Exception(
"CorruptData") <<
"Unpacked payload length=" << payloadLength
83 <<
" exceeds the maximal length=" << config_.payloadLengthMax;
85 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", payload length=" << payloadLength;
87 if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) ||
88 (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) ||
89 (((econdHeader >> kMatchShift) & kMatchMask) == 0) ||
90 (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) {
91 LogDebug(
"HGCalUnpack") <<
"ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
92 <<
", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
93 <<
", M=" << (econdHeader >> kMatchShift & kMatchMask)
94 <<
", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
95 badECOND_.emplace_back(iword - 2);
96 iword += payloadLength;
99 LogDebug(
"HGCalUnpacker") <<
"Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) <<
").";
104 const uint32_t econdBodyStart = iword;
106 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
108 LogDebug(
"HGCalUnpack") <<
"Standard ECON-D";
109 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
110 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
113 if ((enabledERX >> erx & 1) == 0)
118 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx
119 <<
", first word of the eRx header=0x" << std::hex << inputArray[iword] <<
"\n" 120 <<
" extracted common mode 0=0x" << std::hex
121 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec 122 <<
", saved at " << commonModeDataSize_ <<
"\n" 123 <<
" extracted common mode 1=0x" << std::hex
124 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec 125 <<
", saved at " << (commonModeDataSize_ + 1);
126 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
127 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
128 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
129 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
130 commonModeDataSize_ += 2;
131 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
132 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
133 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 134 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 135 <<
" saved at " << commonModeDataSize_ <<
"\n" 136 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 137 <<
" saved at " << commonModeDataSize_ + 1;
140 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
141 LogDebug(
"HGCalUnpack") <<
"eRx empty";
148 LogDebug(
"HGCalUnpack") <<
"whole eRx header=0x" << std::hex << erxHeader;
151 uint32_t bitCounter = 0;
152 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
153 if (((erxHeader >> channel) & 1) == 0)
156 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
157 const uint32_t tempIndex = bitCounter / 32 + iword;
158 const uint8_t tempBit = bitCounter % 32;
159 const uint32_t
temp =
160 (tempBit == 0) ? inputArray[tempIndex]
161 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
162 const uint8_t code =
temp >> 28;
166 ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
167 bitCounter += erxBodyBits_[code];
169 channelData_[channelDataSize_].fillFlag1(1);
170 LogDebug(
"HGCalUnpack") <<
"Word " << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 171 << (
int)erx <<
":" << (
int)channel <<
"\n" 172 <<
" assigned common mode index=" << commonModeIndex_.at(channelDataSize_)
174 <<
" full word readout=0x" << std::hex <<
temp <<
std::dec <<
", code=0x" 176 <<
" extracted channel data=0x" << std::hex
177 << channelData_[channelDataSize_].raw();
181 iword += bitCounter / 32;
182 if (bitCounter % 32 != 0)
185 if (commonModeDataSize_ + 1 > config_.commonModeMax)
186 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
187 <<
" >= " << config_.commonModeMax <<
".";
188 commonModeDataSize_ += 2;
193 LogDebug(
"HGCalUnpack") <<
"Passthrough ECON-D";
194 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
195 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
196 if ((enabledERX >> erx & 1) == 0)
201 uint32_t
temp = inputArray[iword];
202 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx
203 <<
", first word of the eRx header=0x" << std::hex <<
temp <<
std::dec <<
"\n" 204 <<
" extracted common mode 0=0x" << std::hex
205 << ((
temp >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec <<
", saved at " 206 << commonModeDataSize_ <<
"\n" 207 <<
" extracted common mode 1=0x" << std::hex
208 << ((
temp >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec <<
", saved at " 209 << (commonModeDataSize_ + 1);
210 commonModeData_[commonModeDataSize_] = (
temp >> kCommonmode0Shift) & kCommonmode0Mask;
211 commonModeData_[commonModeDataSize_ + 1] = (
temp >> kCommonmode1Shift) & kCommonmode1Mask;
212 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
213 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
214 commonModeDataSize_ += 2;
215 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
216 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
217 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 218 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 219 <<
" saved at " << commonModeDataSize_ <<
"\n" 220 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 221 <<
" saved at " << commonModeDataSize_ + 1;
224 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
226 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
227 channelData_[channelDataSize_] =
229 LogDebug(
"HGCalUnpack") <<
"Word " << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 230 << (
int)erx <<
":" << (
int)channel <<
", HGCalElectronicsId=" <<
id.raw()
231 <<
", assigned common mode index=" << commonModeIndex_.at(channelDataSize_)
233 <<
"extracted channel data=0x" << std::hex
234 << channelData_.at(channelDataSize_).raw();
238 if (commonModeDataSize_ + 1 > config_.commonModeMax)
239 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
240 <<
" >= " << config_.commonModeMax <<
".";
241 commonModeDataSize_ += 2;
248 if (iword - econdBodyStart != payloadLength)
250 <<
"Mismatch between unpacked and expected ECON-D #" << (
int)econd <<
" payload length\n" 251 <<
" unpacked payload length=" << iword - econdBodyStart <<
"\n" 252 <<
" expected payload length=" << payloadLength;
254 if (iword % 2 != 0) {
255 LogDebug(
"HGCalUnpacker") <<
"Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) <<
").";
261 if (iword % 4 != 0) {
262 LogDebug(
"HGCalUnpacker") <<
"Padding capture block to 4 32-bit words (remainder: " << (iword % 4) <<
").";
263 iword += 4 - (iword % 4);
272 channelData_.resize(channelDataSize_);
273 commonModeIndex_.resize(channelDataSize_);
274 commonModeData_.resize(commonModeDataSize_);
280 const std::vector<uint32_t>& inputArray,
281 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
284 uint8_t captureBlock = 0;
286 channelDataSize_ = 0;
287 commonModeDataSize_ = 0;
290 for (uint32_t iword = 0; iword < inputArray.size();) {
293 if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) != config_.captureBlockReserved)
295 <<
"Expected a capture block header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword
296 <<
" (reserved word: 0x" << config_.captureBlockReserved <<
"), got 0x" << inputArray[iword] <<
".";
299 LogDebug(
"HGCalUnpack") <<
"Capture block=" << (
int)captureBlock <<
", capture block header=0x" << std::hex
300 << captureBlockHeader;
304 for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) {
305 if ((captureBlockHeader >> (3 * econd) & kCaptureBlockECONDStatusMask) >= 0b100)
310 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
312 <<
"Expected a ECON-D header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword <<
" (marker: 0x" 313 << config_.econdHeaderMarker <<
"), got 0x" << inputArray[iword] <<
".";
315 const uint32_t econdHeader = inputArray[iword];
318 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", first word of ECON-D header=0x" << std::hex
322 const uint32_t payloadLength = ((econdHeader >> kPayloadLengthShift)) & kPayloadLengthMask;
323 if (payloadLength > config_.payloadLengthMax)
324 throw cms::Exception(
"CorruptData") <<
"Unpacked payload length=" << payloadLength
325 <<
" exceeds the maximal length=" << config_.payloadLengthMax;
326 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", payload length = " << payloadLength;
328 if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) ||
329 (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) ||
330 (((econdHeader >> kMatchShift) & kMatchMask) == 0) ||
331 (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) {
332 LogDebug(
"HGCalUnpack") <<
"ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
333 <<
", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
334 <<
", M=" << (econdHeader >> kMatchShift & kMatchMask)
335 <<
", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
336 badECOND_.emplace_back(iword - 2);
337 iword += payloadLength;
339 if (iword % 2 != 0) {
340 LogDebug(
"HGCalUnpacker") <<
"Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) <<
").";
347 const uint32_t econdBodyStart = iword;
348 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
350 LogDebug(
"HGCalUnpack") <<
"Standard ECON-D";
351 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
352 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
353 if ((enabledERX >> erx & 1) == 0)
358 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx
359 <<
", first word of the eRx header=0x" << std::hex << inputArray[iword] <<
std::dec 361 <<
" extracted common mode 0=0x" << std::hex
362 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec 363 <<
", saved at " << commonModeDataSize_ <<
"\n" 364 <<
" extracted common mode 1=0x" << std::hex
365 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec 366 <<
", saved at " << (commonModeDataSize_ + 1);
368 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
369 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
370 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
371 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
372 commonModeDataSize_ += 2;
373 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
374 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
375 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 376 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 377 <<
" saved at " << commonModeDataSize_ <<
"\n" 378 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 379 <<
" saved at " << commonModeDataSize_ + 1;
383 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
385 LogDebug(
"HGCalUnpack") <<
"eRx #" << (
int)erx <<
" is empty.";
391 LogDebug(
"HGCalUnpack") <<
"whole eRx header=0x" << std::hex << erxHeader;
394 uint32_t bitCounter = 0;
396 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
397 if (((erxHeader >> channel) & 1) == 0)
400 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
401 const uint32_t tempIndex = bitCounter / 32 + iword;
402 const uint8_t tempBit = bitCounter % 32;
403 const uint32_t
temp =
404 (tempBit == 0) ? inputArray[tempIndex]
405 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
406 const uint8_t code =
temp >> 28;
410 ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
411 bitCounter += erxBodyBits_[code];
413 channelData_[channelDataSize_].fillFlag1(1);
414 LogDebug(
"HGCalUnpack") <<
"Word " << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 415 << (
int)erx <<
":" << (
int)channel
416 <<
", assigned common mode index=" << commonModeIndex_[channelDataSize_] <<
"\n" 417 <<
" full word readout=0x" << std::hex <<
temp <<
std::dec <<
", code=0x" 418 << std::hex << (
int)code <<
std::dec <<
"\n" 419 <<
" extracted channel data=0x" << std::hex
420 << channelData_[channelDataSize_].raw();
424 iword += bitCounter / 32;
425 if (bitCounter % 32 != 0)
428 if (commonModeDataSize_ + 1 > config_.commonModeMax)
429 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
430 <<
" >= " << config_.commonModeMax <<
".";
431 commonModeDataSize_ += 2;
435 LogDebug(
"HGCalUnpack") <<
"Passthrough ECON-D";
436 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
437 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
438 if ((enabledERX >> erx & 1) == 0)
443 uint32_t
temp = inputArray[iword];
444 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx
445 <<
", first word of the eRx header=0x" << std::hex <<
temp <<
std::dec <<
"\n" 446 <<
" extracted common mode 0=0x" << std::hex
447 << ((
temp >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec <<
", saved at " 448 << commonModeDataSize_ <<
"\n" 449 <<
" extracted common mode 1=0x" << std::hex
450 << ((
temp >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec <<
", saved at " 451 << (commonModeDataSize_ + 1);
452 commonModeData_[commonModeDataSize_] = (
temp >> kCommonmode0Shift) & kCommonmode0Mask;
453 commonModeData_[commonModeDataSize_ + 1] = (
temp >> kCommonmode1Shift) & kCommonmode1Mask;
454 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
455 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
456 commonModeDataSize_ += 2;
457 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
458 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
459 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 460 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 461 <<
" saved at " << commonModeDataSize_ <<
"\n" 462 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 463 <<
" saved at " << commonModeDataSize_ + 1;
467 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
469 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
470 channelData_[channelDataSize_] =
472 LogDebug(
"HGCalUnpack") <<
"Word" << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 473 << (
int)erx <<
":" << (
int)channel <<
", HGCalElectronicsId=" <<
id.raw()
474 <<
", assigned common mode index=" << commonModeIndex_[channelDataSize_] <<
"\n" 475 <<
"extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw();
479 if (commonModeDataSize_ + 1 > config_.commonModeMax)
480 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
481 <<
" >= " << config_.commonModeMax <<
".";
482 commonModeDataSize_ += 2;
490 if (iword - econdBodyStart != payloadLength)
492 <<
"Mismatch between unpacked and expected ECON-D #" << (
int)econd <<
" payload length\n" 493 <<
" unpacked payload length=" << iword - econdBodyStart <<
"\n" 494 <<
" expected payload length=" << payloadLength;
496 if (iword % 2 != 0) {
497 LogDebug(
"HGCalUnpacker") <<
"Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) <<
").";
503 channelData_.resize(channelDataSize_);
504 commonModeIndex_.resize(channelDataSize_);
505 commonModeData_.resize(commonModeDataSize_);
511 const std::vector<uint32_t>& inputArray,
512 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
515 uint8_t captureBlock = 0;
518 channelDataSize_ = 0;
519 commonModeDataSize_ = 0;
522 for (uint32_t iword = 0; iword < inputArray.size();) {
525 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
527 <<
"Expected a ECON-D header at word " <<
std::dec << iword <<
"/0x" << std::hex << iword <<
" (marker: 0x" 528 << config_.econdHeaderMarker <<
"), got 0x" << inputArray[iword] <<
".";
530 const uint32_t econdHeader = inputArray[iword];
533 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", first word of ECON-D header=0x" << std::hex
537 const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask;
538 if (payloadLength > config_.payloadLengthMax)
540 <<
"Unpacked payload length=" << payloadLength <<
" exceeds the maximal length=" << config_.payloadLengthMax;
542 LogDebug(
"HGCalUnpack") <<
"ECON-D #" << (
int)econd <<
", payload length = " << payloadLength;
544 if (((econdHeader >> kHTShift & kHTMask) >= 0b10) || ((econdHeader >> kEBOShift & kEBOMask) >= 0b10) ||
545 ((econdHeader >> kMatchShift & kMatchMask) == 0) ||
546 ((econdHeader >> kTruncatedShift & kTruncatedMask) == 1)) {
547 LogDebug(
"HGCalUnpack") <<
"ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
548 <<
", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
549 <<
", M=" << (econdHeader >> kMatchShift & kMatchMask)
550 <<
", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
551 badECOND_.emplace_back(iword - 2);
552 iword += payloadLength;
558 const uint32_t econdBodyStart = iword;
559 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
561 LogDebug(
"HGCalUnpack") <<
"Standard ECON-D";
562 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
563 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
564 if ((enabledERX >> erx & 1) == 0)
569 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx <<
", first word of the eRx header=0x" 570 << std::hex << inputArray[iword] <<
std::dec <<
"\n" 571 <<
" extracted common mode 0=0x" << std::hex
572 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec 573 <<
", saved at " << commonModeDataSize_ <<
"\n" 574 <<
" extracted common mode 1=0x" << std::hex
575 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec 576 <<
", saved at " << (commonModeDataSize_ + 1);
577 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
578 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
579 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
580 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
581 commonModeDataSize_ += 2;
582 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
583 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
584 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 585 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 586 <<
" saved at " << commonModeDataSize_ <<
"\n" 587 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 588 <<
" saved at " << commonModeDataSize_ + 1;
590 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
591 LogDebug(
"HGCalUnpack") <<
"eRx empty";
600 LogDebug(
"HGCalUnpack") <<
"whole eRx header=0x" << std::hex << erxHeader;
603 uint32_t bitCounter = 0;
604 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
605 if (((erxHeader >> channel) & 1) == 0)
608 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
609 const uint32_t tempIndex = bitCounter / 32 + iword;
610 const uint8_t tempBit = bitCounter % 32;
611 const uint32_t
temp =
612 (tempBit == 0) ? inputArray[tempIndex]
613 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
614 const uint8_t code =
temp >> 28;
617 logicalMapping(
id), ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
618 bitCounter += erxBodyBits_[code];
620 channelData_[channelDataSize_].fillFlag1(1);
621 LogDebug(
"HGCalUnpack") <<
"Word " << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 622 << (
int)erx <<
":" << (
int)channel <<
"\n" 623 <<
" assigned common mode index=" << commonModeIndex_.at(channelDataSize_) <<
"\n" 624 <<
" full word readout=0x" << std::hex <<
temp <<
std::dec <<
", code=0x" << std::hex
626 <<
" extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw();
630 iword += bitCounter / 32;
631 if (bitCounter % 32 != 0)
634 if (commonModeDataSize_ + 1 > config_.commonModeMax)
635 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
636 <<
" >= " << config_.commonModeMax <<
".";
637 commonModeDataSize_ += 2;
642 LogDebug(
"HGCalUnpack") <<
"Passthrough ECON-D";
643 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
644 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
645 if ((enabledERX >> erx & 1) == 0)
649 uint32_t
temp = inputArray[iword];
650 LogDebug(
"HGCalUnpack") <<
"ECON-D:eRx=" << (
int)econd <<
":" << (
int)erx <<
", first word of the eRx header=0x" 652 <<
" extracted common mode 0=0x" << std::hex
653 << ((
temp >> kCommonmode0Shift) & kCommonmode0Mask) <<
std::dec <<
", saved at " 654 << commonModeDataSize_ <<
"\n" 655 <<
" extracted common mode 1=0x" << std::hex
656 << ((
temp >> kCommonmode1Shift) & kCommonmode1Mask) <<
std::dec <<
", saved at " 657 << (commonModeDataSize_ + 1);
658 commonModeData_[commonModeDataSize_] = (
temp >> kCommonmode0Shift) & kCommonmode0Mask;
659 commonModeData_[commonModeDataSize_ + 1] = (
temp >> kCommonmode1Shift) & kCommonmode1Mask;
660 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
661 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
662 commonModeDataSize_ += 2;
663 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
664 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
665 LogDebug(
"HGCalUnpack") <<
"half ROC turned on, padding to 4 common modes\n" 666 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] <<
std::dec 667 <<
" saved at " << commonModeDataSize_ <<
"\n" 668 <<
"0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] <<
std::dec 669 <<
" saved at " << commonModeDataSize_ + 1;
673 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
675 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
676 channelData_[channelDataSize_] =
678 LogDebug(
"HGCalUnpack") <<
"Word " << channelDataSize_ <<
", ECON-D:eRx:channel=" << (
int)econd <<
":" 679 << (
int)erx <<
":" << (
int)channel <<
", HGCalElectronicsId=" <<
id.raw() <<
"\n" 680 <<
" assigned common mode index=" << commonModeIndex_.at(channelDataSize_) <<
"\n" 681 <<
"extracted channel data=0x" << std::hex << channelData_.at(channelDataSize_).raw();
685 if (commonModeDataSize_ + 1 > config_.commonModeMax)
686 throw cms::Exception(
"HGCalUnpack") <<
"Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
687 <<
" >= " << config_.commonModeMax <<
".";
688 commonModeDataSize_ += 2;
695 if (iword - econdBodyStart != payloadLength)
697 <<
"Mismatch between unpacked and expected ECON-D #" << (
int)econd <<
" payload length\n" 698 <<
" unpacked payload length=" << iword - econdBodyStart <<
"\n" 699 <<
" expected payload length=" << payloadLength;
701 channelData_.resize(channelDataSize_);
702 commonModeIndex_.resize(channelDataSize_);
703 commonModeData_.resize(commonModeDataSize_);
void parseSLink(const std::vector< uint32_t > &inputArray, const std::function< uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)> &enabledERXMapping, const std::function< D(HGCalElectronicsId elecID)> &logicalMapping)
This class is designed to unpack raw data from HGCal, formatted as S-Links, capture blocks...
void parseECOND(const std::vector< uint32_t > &inputArray, const std::function< uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)> &enabledERXMapping, const std::function< D(HGCalElectronicsId elecID)> &logicalMapping)
wrapper for a 32b data word identifying a readout channel in the raw data The format is the following...
DecomposeProduct< arg, typename Div::arg > D
unsigned long long uint64_t
HGCalUnpacker(HGCalUnpackerConfig config)
void parseCaptureBlock(const std::vector< uint32_t > &inputArray, const std::function< uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)> &enabledERXMapping, const std::function< D(HGCalElectronicsId elecID)> &logicalMapping)
wrapper for a 32b data word from a single channel and its detid The format is always the same: |1b|1b...