File indexing completed on 2024-05-04 04:04:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h"
0012
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/Utilities/interface/Exception.h"
0015
0016 template <class D>
0017 HGCalUnpacker<D>::HGCalUnpacker(HGCalUnpackerConfig config)
0018 : config_(config),
0019 channelData_(config_.channelMax),
0020 commonModeIndex_(config_.channelMax),
0021 commonModeData_(config_.commonModeMax) {}
0022
0023 template <class D>
0024 void HGCalUnpacker<D>::parseSLink(
0025 const std::vector<uint32_t>& inputArray,
0026 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
0027 const std::function<D(HGCalElectronicsId elecID)>& logicalMapping) {
0028 uint16_t sLink = 0;
0029
0030 channelDataSize_ = 0;
0031 commonModeDataSize_ = 0;
0032 badECOND_.clear();
0033
0034 for (uint32_t iword = 0; iword < inputArray.size();) {
0035
0036 if (((inputArray[iword] >> kSLinkBOEShift) & kSLinkBOEMask) != config_.sLinkBOE)
0037 throw cms::Exception("CorruptData")
0038 << "Expected a S-Link header at word " << std::dec << iword << "/0x" << std::hex << iword << " (BOE: 0x"
0039 << config_.sLinkBOE << "), got 0x" << inputArray[iword] << ".";
0040
0041 iword += 4;
0042
0043 LogDebug("HGCalUnpack") << "SLink=" << sLink;
0044
0045
0046 for (uint8_t captureBlock = 0; captureBlock < config_.sLinkCaptureBlockMax;
0047 captureBlock++) {
0048
0049 if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) !=
0050 config_.captureBlockReserved)
0051 throw cms::Exception("CorruptData")
0052 << "Expected a capture block header at word " << std::dec << iword << "/0x" << std::hex << iword
0053 << " (reserved word: 0x" << config_.captureBlockReserved << "), got 0x" << inputArray[iword] << ".";
0054
0055 const uint64_t captureBlockHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]);
0056 iword += 2;
0057
0058 LogDebug("HGCalUnpack") << "Capture block=" << (int)captureBlock << ", capture block header=0x" << std::hex
0059 << captureBlockHeader;
0060
0061
0062 for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) {
0063 if (((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) >= 0b100)
0064 continue;
0065
0066
0067
0068 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
0069 throw cms::Exception("CorruptData")
0070 << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword
0071 << " (marker: 0x" << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << ".";
0072
0073 const auto& econdHeader = inputArray[iword];
0074 iword += 2;
0075
0076 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex
0077 << econdHeader;
0078
0079
0080 const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask;
0081 if (payloadLength > config_.payloadLengthMax)
0082 throw cms::Exception("CorruptData") << "Unpacked payload length=" << payloadLength
0083 << " exceeds the maximal length=" << config_.payloadLengthMax;
0084
0085 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length=" << payloadLength;
0086
0087 if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) ||
0088 (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) ||
0089 (((econdHeader >> kMatchShift) & kMatchMask) == 0) ||
0090 (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) {
0091 LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
0092 << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
0093 << ", M=" << (econdHeader >> kMatchShift & kMatchMask)
0094 << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
0095 badECOND_.emplace_back(iword - 2);
0096 iword += payloadLength;
0097
0098 if (iword % 2 != 0) {
0099 LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ").";
0100 iword += 1;
0101 }
0102 continue;
0103 }
0104 const uint32_t econdBodyStart = iword;
0105
0106 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
0107
0108 LogDebug("HGCalUnpack") << "Standard ECON-D";
0109 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0110 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0111
0112
0113 if ((enabledERX >> erx & 1) == 0)
0114 continue;
0115
0116
0117
0118 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx
0119 << ", first word of the eRx header=0x" << std::hex << inputArray[iword] << "\n"
0120 << " extracted common mode 0=0x" << std::hex
0121 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec
0122 << ", saved at " << commonModeDataSize_ << "\n"
0123 << " extracted common mode 1=0x" << std::hex
0124 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec
0125 << ", saved at " << (commonModeDataSize_ + 1);
0126 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
0127 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
0128 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0129 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0130 commonModeDataSize_ += 2;
0131 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0132 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0133 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0134 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0135 << " saved at " << commonModeDataSize_ << "\n"
0136 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0137 << " saved at " << commonModeDataSize_ + 1;
0138 }
0139
0140 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
0141 LogDebug("HGCalUnpack") << "eRx empty";
0142 iword += 1;
0143 continue;
0144 }
0145
0146 const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]);
0147 iword += 2;
0148 LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader;
0149
0150
0151 uint32_t bitCounter = 0;
0152 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0153 if (((erxHeader >> channel) & 1) == 0)
0154 continue;
0155 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0156 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0157 const uint32_t tempIndex = bitCounter / 32 + iword;
0158 const uint8_t tempBit = bitCounter % 32;
0159 const uint32_t temp =
0160 (tempBit == 0) ? inputArray[tempIndex]
0161 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
0162 const uint8_t code = temp >> 28;
0163
0164 channelData_[channelDataSize_] = HGCROCChannelDataFrame<D>(
0165 logicalMapping(id),
0166 ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
0167 bitCounter += erxBodyBits_[code];
0168 if (code == 0b0010)
0169 channelData_[channelDataSize_].fillFlag1(1);
0170 LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0171 << (int)erx << ":" << (int)channel << "\n"
0172 << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_)
0173 << "\n"
0174 << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x"
0175 << std::hex << (int)code << std::dec << "\n"
0176 << " extracted channel data=0x" << std::hex
0177 << channelData_[channelDataSize_].raw();
0178 channelDataSize_++;
0179 }
0180
0181 iword += bitCounter / 32;
0182 if (bitCounter % 32 != 0)
0183 iword += 1;
0184
0185 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0186 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0187 << " >= " << config_.commonModeMax << ".";
0188 commonModeDataSize_ += 2;
0189
0190 }
0191 } else {
0192
0193 LogDebug("HGCalUnpack") << "Passthrough ECON-D";
0194 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0195 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0196 if ((enabledERX >> erx & 1) == 0)
0197 continue;
0198
0199
0200
0201 uint32_t temp = inputArray[iword];
0202 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx
0203 << ", first word of the eRx header=0x" << std::hex << temp << std::dec << "\n"
0204 << " extracted common mode 0=0x" << std::hex
0205 << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at "
0206 << commonModeDataSize_ << "\n"
0207 << " extracted common mode 1=0x" << std::hex
0208 << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at "
0209 << (commonModeDataSize_ + 1);
0210 commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask;
0211 commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask;
0212 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0213 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0214 commonModeDataSize_ += 2;
0215 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0216 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0217 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0218 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0219 << " saved at " << commonModeDataSize_ << "\n"
0220 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0221 << " saved at " << commonModeDataSize_ + 1;
0222 }
0223 iword += 2;
0224 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0225 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0226 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0227 channelData_[channelDataSize_] =
0228 HGCROCChannelDataFrame<HGCalElectronicsId>(logicalMapping(id), inputArray[iword]);
0229 LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0230 << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw()
0231 << ", assigned common mode index=" << commonModeIndex_.at(channelDataSize_)
0232 << "\n"
0233 << "extracted channel data=0x" << std::hex
0234 << channelData_.at(channelDataSize_).raw();
0235 channelDataSize_++;
0236 iword++;
0237 }
0238 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0239 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0240 << " >= " << config_.commonModeMax << ".";
0241 commonModeDataSize_ += 2;
0242 }
0243 }
0244
0245
0246 iword += 1;
0247
0248 if (iword - econdBodyStart != payloadLength)
0249 throw cms::Exception("CorruptData")
0250 << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n"
0251 << " unpacked payload length=" << iword - econdBodyStart << "\n"
0252 << " expected payload length=" << payloadLength;
0253
0254 if (iword % 2 != 0) {
0255 LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ").";
0256 iword += 1;
0257 }
0258 }
0259
0260
0261 if (iword % 4 != 0) {
0262 LogDebug("HGCalUnpacker") << "Padding capture block to 4 32-bit words (remainder: " << (iword % 4) << ").";
0263 iword += 4 - (iword % 4);
0264 }
0265 }
0266
0267
0268
0269 iword += 4;
0270 sLink++;
0271 }
0272 channelData_.resize(channelDataSize_);
0273 commonModeIndex_.resize(channelDataSize_);
0274 commonModeData_.resize(commonModeDataSize_);
0275 return;
0276 }
0277
0278 template <class D>
0279 void HGCalUnpacker<D>::parseCaptureBlock(
0280 const std::vector<uint32_t>& inputArray,
0281 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
0282 const std::function<D(HGCalElectronicsId elecID)>& logicalMapping) {
0283 uint16_t sLink = 0;
0284 uint8_t captureBlock = 0;
0285
0286 channelDataSize_ = 0;
0287 commonModeDataSize_ = 0;
0288 badECOND_.clear();
0289
0290 for (uint32_t iword = 0; iword < inputArray.size();) {
0291
0292
0293 if (((inputArray[iword] >> kCaptureBlockReservedShift) & kCaptureBlockReservedMask) != config_.captureBlockReserved)
0294 throw cms::Exception("CorruptData")
0295 << "Expected a capture block header at word " << std::dec << iword << "/0x" << std::hex << iword
0296 << " (reserved word: 0x" << config_.captureBlockReserved << "), got 0x" << inputArray[iword] << ".";
0297
0298 const uint64_t captureBlockHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]);
0299 LogDebug("HGCalUnpack") << "Capture block=" << (int)captureBlock << ", capture block header=0x" << std::hex
0300 << captureBlockHeader;
0301 iword += 2;
0302
0303
0304 for (uint8_t econd = 0; econd < config_.captureBlockECONDMax; econd++) {
0305 if ((captureBlockHeader >> (3 * econd) & kCaptureBlockECONDStatusMask) >= 0b100)
0306 continue;
0307
0308
0309
0310 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
0311 throw cms::Exception("CorruptData")
0312 << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword << " (marker: 0x"
0313 << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << ".";
0314
0315 const uint32_t econdHeader = inputArray[iword];
0316 iword += 2;
0317
0318 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex
0319 << econdHeader;
0320
0321
0322 const uint32_t payloadLength = ((econdHeader >> kPayloadLengthShift)) & kPayloadLengthMask;
0323 if (payloadLength > config_.payloadLengthMax)
0324 throw cms::Exception("CorruptData") << "Unpacked payload length=" << payloadLength
0325 << " exceeds the maximal length=" << config_.payloadLengthMax;
0326 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length = " << payloadLength;
0327
0328 if ((((captureBlockHeader >> (3 * econd)) & kCaptureBlockECONDStatusMask) != 0b000) ||
0329 (((econdHeader >> kHTShift) & kHTMask) >= 0b10) || (((econdHeader >> kEBOShift) & kEBOMask) >= 0b10) ||
0330 (((econdHeader >> kMatchShift) & kMatchMask) == 0) ||
0331 (((econdHeader >> kTruncatedShift) & kTruncatedMask) == 1)) {
0332 LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
0333 << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
0334 << ", M=" << (econdHeader >> kMatchShift & kMatchMask)
0335 << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
0336 badECOND_.emplace_back(iword - 2);
0337 iword += payloadLength;
0338
0339 if (iword % 2 != 0) {
0340 LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ").";
0341 iword += 1;
0342 }
0343 continue;
0344 }
0345
0346
0347 const uint32_t econdBodyStart = iword;
0348 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
0349
0350 LogDebug("HGCalUnpack") << "Standard ECON-D";
0351 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0352 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0353 if ((enabledERX >> erx & 1) == 0)
0354 continue;
0355
0356
0357
0358 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx
0359 << ", first word of the eRx header=0x" << std::hex << inputArray[iword] << std::dec
0360 << "\n"
0361 << " extracted common mode 0=0x" << std::hex
0362 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec
0363 << ", saved at " << commonModeDataSize_ << "\n"
0364 << " extracted common mode 1=0x" << std::hex
0365 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec
0366 << ", saved at " << (commonModeDataSize_ + 1);
0367
0368 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
0369 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
0370 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0371 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0372 commonModeDataSize_ += 2;
0373 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0374 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0375 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0376 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0377 << " saved at " << commonModeDataSize_ << "\n"
0378 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0379 << " saved at " << commonModeDataSize_ + 1;
0380 }
0381
0382
0383 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
0384 iword += 1;
0385 LogDebug("HGCalUnpack") << "eRx #" << (int)erx << " is empty.";
0386 continue;
0387 }
0388
0389
0390 const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | (uint64_t)inputArray[iword + 1];
0391 LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader;
0392 iword += 2;
0393
0394 uint32_t bitCounter = 0;
0395
0396 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0397 if (((erxHeader >> channel) & 1) == 0)
0398 continue;
0399 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0400 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0401 const uint32_t tempIndex = bitCounter / 32 + iword;
0402 const uint8_t tempBit = bitCounter % 32;
0403 const uint32_t temp =
0404 (tempBit == 0) ? inputArray[tempIndex]
0405 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
0406 const uint8_t code = temp >> 28;
0407
0408 channelData_[channelDataSize_] = HGCROCChannelDataFrame<D>(
0409 logicalMapping(id),
0410 ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
0411 bitCounter += erxBodyBits_[code];
0412 if (code == 0b0010)
0413 channelData_[channelDataSize_].fillFlag1(1);
0414 LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0415 << (int)erx << ":" << (int)channel
0416 << ", assigned common mode index=" << commonModeIndex_[channelDataSize_] << "\n"
0417 << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x"
0418 << std::hex << (int)code << std::dec << "\n"
0419 << " extracted channel data=0x" << std::hex
0420 << channelData_[channelDataSize_].raw();
0421 channelDataSize_++;
0422 }
0423
0424 iword += bitCounter / 32;
0425 if (bitCounter % 32 != 0)
0426 iword += 1;
0427
0428 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0429 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0430 << " >= " << config_.commonModeMax << ".";
0431 commonModeDataSize_ += 2;
0432
0433 }
0434 } else {
0435 LogDebug("HGCalUnpack") << "Passthrough ECON-D";
0436 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0437 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0438 if ((enabledERX >> erx & 1) == 0)
0439 continue;
0440
0441
0442
0443 uint32_t temp = inputArray[iword];
0444 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx
0445 << ", first word of the eRx header=0x" << std::hex << temp << std::dec << "\n"
0446 << " extracted common mode 0=0x" << std::hex
0447 << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at "
0448 << commonModeDataSize_ << "\n"
0449 << " extracted common mode 1=0x" << std::hex
0450 << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at "
0451 << (commonModeDataSize_ + 1);
0452 commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask;
0453 commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask;
0454 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0455 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0456 commonModeDataSize_ += 2;
0457 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0458 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0459 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0460 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0461 << " saved at " << commonModeDataSize_ << "\n"
0462 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0463 << " saved at " << commonModeDataSize_ + 1;
0464 }
0465 iword += 2;
0466
0467 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0468 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0469 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0470 channelData_[channelDataSize_] =
0471 HGCROCChannelDataFrame<HGCalElectronicsId>(logicalMapping(id), inputArray[iword]);
0472 LogDebug("HGCalUnpack") << "Word" << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0473 << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw()
0474 << ", assigned common mode index=" << commonModeIndex_[channelDataSize_] << "\n"
0475 << "extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw();
0476 channelDataSize_++;
0477 iword++;
0478 }
0479 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0480 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0481 << " >= " << config_.commonModeMax << ".";
0482 commonModeDataSize_ += 2;
0483 }
0484 }
0485
0486
0487
0488 iword += 1;
0489
0490 if (iword - econdBodyStart != payloadLength)
0491 throw cms::Exception("CorruptData")
0492 << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n"
0493 << " unpacked payload length=" << iword - econdBodyStart << "\n"
0494 << " expected payload length=" << payloadLength;
0495
0496 if (iword % 2 != 0) {
0497 LogDebug("HGCalUnpacker") << "Padding ECON-D payload to 2 32-bit words (remainder: " << (iword % 2) << ").";
0498 iword += 1;
0499 }
0500 }
0501 captureBlock++;
0502 }
0503 channelData_.resize(channelDataSize_);
0504 commonModeIndex_.resize(channelDataSize_);
0505 commonModeData_.resize(commonModeDataSize_);
0506 return;
0507 }
0508
0509 template <class D>
0510 void HGCalUnpacker<D>::parseECOND(
0511 const std::vector<uint32_t>& inputArray,
0512 const std::function<uint16_t(uint16_t sLink, uint8_t captureBlock, uint8_t econd)>& enabledERXMapping,
0513 const std::function<D(HGCalElectronicsId elecID)>& logicalMapping) {
0514 uint16_t sLink = 0;
0515 uint8_t captureBlock = 0;
0516 uint8_t econd = 0;
0517
0518 channelDataSize_ = 0;
0519 commonModeDataSize_ = 0;
0520 badECOND_.clear();
0521
0522 for (uint32_t iword = 0; iword < inputArray.size();) {
0523
0524
0525 if (((inputArray[iword] >> kHeaderShift) & kHeaderMask) != config_.econdHeaderMarker)
0526 throw cms::Exception("CorruptData")
0527 << "Expected a ECON-D header at word " << std::dec << iword << "/0x" << std::hex << iword << " (marker: 0x"
0528 << config_.econdHeaderMarker << "), got 0x" << inputArray[iword] << ".";
0529
0530 const uint32_t econdHeader = inputArray[iword];
0531 iword += 2;
0532
0533 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", first word of ECON-D header=0x" << std::hex
0534 << econdHeader;
0535
0536
0537 const uint32_t payloadLength = (econdHeader >> kPayloadLengthShift) & kPayloadLengthMask;
0538 if (payloadLength > config_.payloadLengthMax)
0539 throw cms::Exception("CorruptData")
0540 << "Unpacked payload length=" << payloadLength << " exceeds the maximal length=" << config_.payloadLengthMax;
0541
0542 LogDebug("HGCalUnpack") << "ECON-D #" << (int)econd << ", payload length = " << payloadLength;
0543
0544 if (((econdHeader >> kHTShift & kHTMask) >= 0b10) || ((econdHeader >> kEBOShift & kEBOMask) >= 0b10) ||
0545 ((econdHeader >> kMatchShift & kMatchMask) == 0) ||
0546 ((econdHeader >> kTruncatedShift & kTruncatedMask) == 1)) {
0547 LogDebug("HGCalUnpack") << "ECON-D failed quality check, HT=" << (econdHeader >> kHTShift & kHTMask)
0548 << ", EBO=" << (econdHeader >> kEBOShift & kEBOMask)
0549 << ", M=" << (econdHeader >> kMatchShift & kMatchMask)
0550 << ", T=" << (econdHeader >> kTruncatedShift & kTruncatedMask);
0551 badECOND_.emplace_back(iword - 2);
0552 iword += payloadLength;
0553
0554 continue;
0555 }
0556
0557
0558 const uint32_t econdBodyStart = iword;
0559 if (((econdHeader >> kPassThroughShift) & kPassThroughMask) == 0) {
0560
0561 LogDebug("HGCalUnpack") << "Standard ECON-D";
0562 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0563 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0564 if ((enabledERX >> erx & 1) == 0)
0565 continue;
0566
0567
0568
0569 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx << ", first word of the eRx header=0x"
0570 << std::hex << inputArray[iword] << std::dec << "\n"
0571 << " extracted common mode 0=0x" << std::hex
0572 << ((inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec
0573 << ", saved at " << commonModeDataSize_ << "\n"
0574 << " extracted common mode 1=0x" << std::hex
0575 << ((inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec
0576 << ", saved at " << (commonModeDataSize_ + 1);
0577 commonModeData_[commonModeDataSize_] = (inputArray[iword] >> kCommonmode0Shift) & kCommonmode0Mask;
0578 commonModeData_[commonModeDataSize_ + 1] = (inputArray[iword] >> kCommonmode1Shift) & kCommonmode1Mask;
0579 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0580 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0581 commonModeDataSize_ += 2;
0582 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0583 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0584 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0585 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0586 << " saved at " << commonModeDataSize_ << "\n"
0587 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0588 << " saved at " << commonModeDataSize_ + 1;
0589 }
0590 if (((inputArray[iword] >> kFormatShift) & kFormatMask) == 1) {
0591 LogDebug("HGCalUnpack") << "eRx empty";
0592 iword += 1;
0593
0594 continue;
0595 }
0596
0597
0598 const uint64_t erxHeader = ((uint64_t)inputArray[iword] << 32) | ((uint64_t)inputArray[iword + 1]);
0599 iword += 2;
0600 LogDebug("HGCalUnpack") << "whole eRx header=0x" << std::hex << erxHeader;
0601
0602
0603 uint32_t bitCounter = 0;
0604 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0605 if (((erxHeader >> channel) & 1) == 0)
0606 continue;
0607 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0608 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0609 const uint32_t tempIndex = bitCounter / 32 + iword;
0610 const uint8_t tempBit = bitCounter % 32;
0611 const uint32_t temp =
0612 (tempBit == 0) ? inputArray[tempIndex]
0613 : (inputArray[tempIndex] << tempBit) | (inputArray[tempIndex + 1] >> (32 - tempBit));
0614 const uint8_t code = temp >> 28;
0615
0616 channelData_[channelDataSize_] = HGCROCChannelDataFrame<D>(
0617 logicalMapping(id), ((temp << erxBodyLeftShift_[code]) >> erxBodyRightShift_[code]) & erxBodyMask_[code]);
0618 bitCounter += erxBodyBits_[code];
0619 if (code == 0b0010)
0620 channelData_[channelDataSize_].fillFlag1(1);
0621 LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0622 << (int)erx << ":" << (int)channel << "\n"
0623 << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_) << "\n"
0624 << " full word readout=0x" << std::hex << temp << std::dec << ", code=0x" << std::hex
0625 << (int)code << std::dec << "\n"
0626 << " extracted channel data=0x" << std::hex << channelData_[channelDataSize_].raw();
0627 channelDataSize_++;
0628 }
0629
0630 iword += bitCounter / 32;
0631 if (bitCounter % 32 != 0)
0632 iword += 1;
0633
0634 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0635 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0636 << " >= " << config_.commonModeMax << ".";
0637 commonModeDataSize_ += 2;
0638
0639 }
0640 } else {
0641
0642 LogDebug("HGCalUnpack") << "Passthrough ECON-D";
0643 const auto enabledERX = enabledERXMapping(sLink, captureBlock, econd);
0644 for (uint8_t erx = 0; erx < config_.econdERXMax; erx++) {
0645 if ((enabledERX >> erx & 1) == 0)
0646 continue;
0647
0648
0649 uint32_t temp = inputArray[iword];
0650 LogDebug("HGCalUnpack") << "ECON-D:eRx=" << (int)econd << ":" << (int)erx << ", first word of the eRx header=0x"
0651 << std::hex << temp << std::dec << "\n"
0652 << " extracted common mode 0=0x" << std::hex
0653 << ((temp >> kCommonmode0Shift) & kCommonmode0Mask) << std::dec << ", saved at "
0654 << commonModeDataSize_ << "\n"
0655 << " extracted common mode 1=0x" << std::hex
0656 << ((temp >> kCommonmode1Shift) & kCommonmode1Mask) << std::dec << ", saved at "
0657 << (commonModeDataSize_ + 1);
0658 commonModeData_[commonModeDataSize_] = (temp >> kCommonmode0Shift) & kCommonmode0Mask;
0659 commonModeData_[commonModeDataSize_ + 1] = (temp >> kCommonmode1Shift) & kCommonmode1Mask;
0660 if ((erx % 2 == 0 && (enabledERX >> (erx + 1) & 1) == 0) ||
0661 (erx % 2 == 1 && (enabledERX >> (erx - 1) & 1) == 0)) {
0662 commonModeDataSize_ += 2;
0663 commonModeData_[commonModeDataSize_] = commonModeData_[commonModeDataSize_ - 2];
0664 commonModeData_[commonModeDataSize_ + 1] = commonModeData_[commonModeDataSize_ - 1];
0665 LogDebug("HGCalUnpack") << "half ROC turned on, padding to 4 common modes\n"
0666 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 2] << std::dec
0667 << " saved at " << commonModeDataSize_ << "\n"
0668 << "0x" << std::hex << commonModeData_[commonModeDataSize_ - 1] << std::dec
0669 << " saved at " << commonModeDataSize_ + 1;
0670 }
0671 iword += 2;
0672
0673 for (uint8_t channel = 0; channel < config_.erxChannelMax; channel++) {
0674 const HGCalElectronicsId id(true, sLink, captureBlock, econd, erx, channel);
0675 commonModeIndex_[channelDataSize_] = commonModeDataSize_ / 4 * 4;
0676 channelData_[channelDataSize_] =
0677 HGCROCChannelDataFrame<HGCalElectronicsId>(logicalMapping(id), inputArray[iword]);
0678 LogDebug("HGCalUnpack") << "Word " << channelDataSize_ << ", ECON-D:eRx:channel=" << (int)econd << ":"
0679 << (int)erx << ":" << (int)channel << ", HGCalElectronicsId=" << id.raw() << "\n"
0680 << " assigned common mode index=" << commonModeIndex_.at(channelDataSize_) << "\n"
0681 << "extracted channel data=0x" << std::hex << channelData_.at(channelDataSize_).raw();
0682 channelDataSize_++;
0683 iword++;
0684 }
0685 if (commonModeDataSize_ + 1 > config_.commonModeMax)
0686 throw cms::Exception("HGCalUnpack") << "Too many common mode data unpacked: " << (commonModeDataSize_ + 1)
0687 << " >= " << config_.commonModeMax << ".";
0688 commonModeDataSize_ += 2;
0689 }
0690 }
0691
0692
0693 iword += 1;
0694
0695 if (iword - econdBodyStart != payloadLength)
0696 throw cms::Exception("CorruptData")
0697 << "Mismatch between unpacked and expected ECON-D #" << (int)econd << " payload length\n"
0698 << " unpacked payload length=" << iword - econdBodyStart << "\n"
0699 << " expected payload length=" << payloadLength;
0700 }
0701 channelData_.resize(channelDataSize_);
0702 commonModeIndex_.resize(channelDataSize_);
0703 commonModeData_.resize(commonModeDataSize_);
0704 return;
0705 }
0706
0707
0708 template class HGCalUnpacker<HGCalElectronicsId>;