File indexing completed on 2025-08-05 08:16:14
0001 #include "mvtx_pool.h"
0002
0003 #include <string>
0004 #include <cstdint>
0005
0006 #include <Event/packet.h>
0007 #include "mvtx_decoder/RDH.h"
0008
0009 using namespace std;
0010
0011
0012 mvtx_pool::~mvtx_pool()
0013 {
0014 if (get_verbosity() > 1)
0015 {
0016 std::cout << "LOG mvtx_pool::~mvtx_pool() called." << std::endl;
0017 }
0018
0019 for (auto& link : mGBTLinks)
0020 {
0021
0022 link.clear(true, true);
0023 }
0024
0025 feeid_set.clear();
0026 }
0027
0028
0029
0030 int mvtx_pool::addPacket(Packet* p)
0031 {
0032 if (get_verbosity() > 1)
0033 {
0034 std::cout << "LOG mvtx_pool::addPacket(Packet *p) called." << std::endl;
0035 }
0036
0037 if (! p)
0038 {
0039 return 0;
0040 }
0041
0042 m_is_decoded = false;
0043
0044 for (auto& link : mGBTLinks)
0045 {
0046
0047 link.clear(false, true);
0048 }
0049 feeid_set.clear();
0050
0051 loadInput(p);
0052 setupLinks();
0053
0054 mBuffer.movePtr(payload_position);
0055
0056 if (mBuffer.isEmpty())
0057 {
0058 mBuffer.clear();
0059 }
0060 else
0061 {
0062 mBuffer.moveUnusedToHead();
0063 }
0064
0065 return 0;
0066 }
0067
0068
0069
0070 void mvtx_pool::loadInput(Packet* p)
0071 {
0072
0073 uint8_t* payload_start = reinterpret_cast<uint8_t*>(p->pValue(p->getIdentifier()));
0074
0075 unsigned int dlength = p->getDataLength() - p->getPadding();
0076 dlength *= 4;
0077
0078 if ((dlength < mvtx_utils::FLXWordLength) || (dlength % mvtx_utils::FLXWordLength))
0079 {
0080 COUT << ENDL
0081 << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
0082 << "DMA packet has incomplete FLX words, only "
0083 << dlength << " bytes(" << (dlength / mvtx_utils::FLXWordLength)
0084 << " FLX words), will be decoded. \n"
0085 << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
0086 << ENDL;
0087 dlength -= (dlength % mvtx_utils::FLXWordLength);
0088 }
0089
0090
0091 mBuffer.add(payload_start, dlength);
0092
0093
0094 payload = mBuffer.getPtr();
0095 payload_position = 0;
0096
0097 return;
0098 }
0099
0100
0101 void mvtx_pool::setupLinks()
0102 {
0103 size_t dlength = mBuffer.getUnusedSize();
0104 do
0105 {
0106
0107 if (*(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xFFFF)
0108 {
0109 payload_position += mvtx_utils::FLXWordLength;
0110 }
0111
0112 else if ((dlength - payload_position) >= static_cast<uint64_t>(2 * mvtx_utils::FLXWordLength))
0113 {
0114 if (*(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xAB01)
0115 {
0116 const auto* rdhP = reinterpret_cast<const mvtx::RDH*>(&payload[payload_position]);
0117 if (get_verbosity() > 3)
0118 {
0119 mvtx::RDHUtils::printRDH(mvtx::RDHAny::voidify(*rdhP));
0120 }
0121 if (! mvtx::RDHUtils::checkRDH(mvtx::RDHAny::voidify(*rdhP), true, true))
0122 {
0123
0124 payload_position += mvtx_utils::FLXWordLength;
0125 continue;
0126 }
0127 const size_t pageSizeInBytes = ((*rdhP).pageSize + 1ULL ) * mvtx_utils::FLXWordLength;
0128 if (pageSizeInBytes > (dlength - payload_position))
0129 {
0130 if (get_verbosity() > 1)
0131 {
0132 std::cout << "WARNING: "
0133 << "Skipping Incomplete FELIX packet" << std::endl;
0134 }
0135
0136 break;
0137 }
0138 else
0139 {
0140 feeid_set.insert((*rdhP).feeId);
0141 auto& lnkref = mFeeId2LinkID[(*rdhP).feeId];
0142 if (lnkref.entry == -1)
0143 {
0144 lnkref.entry = mGBTLinks.size();
0145 mGBTLinks.emplace_back((*rdhP).flxId, (*rdhP).feeId);
0146 }
0147 auto& gbtLink = mGBTLinks[lnkref.entry];
0148
0149 if (! (*rdhP).packetCounter)
0150 {
0151
0152 if (gbtLink.hbf_length)
0153 {
0154 log_error << "FLX: " << gbtLink.flxId << ", FeeId: " << gbtLink.feeId \
0155 << ". Found new HBF before stop previous HBF. Previous HBF will be ignored." << std::endl;
0156 gbtLink.cacheData(gbtLink.hbf_length, (gbtLink.hbf_error |= mvtx::PayLoadSG::HBF_ERRORS::Incomplete));
0157 }
0158 gbtLink.hbf_length = pageSizeInBytes;
0159 gbtLink.hbf_error = mvtx::PayLoadSG::HBF_ERRORS::NoError;
0160 }
0161 else
0162 {
0163 if ((*rdhP).packetCounter != gbtLink.prev_pck_cnt + 1)
0164 {
0165 log_error << "Incorrect pages count " << (*rdhP).packetCounter <<", previous page count was " \
0166 << gbtLink.prev_pck_cnt << std::endl;
0167 gbtLink.hbf_length += pageSizeInBytes;
0168 gbtLink.hbf_error |= mvtx::PayLoadSG::HBF_ERRORS::Incomplete;
0169 }
0170 else
0171 {
0172 if (! gbtLink.hbf_length)
0173 {
0174 log_error << "FLX: " << gbtLink.flxId << ", FeeId: " << gbtLink.feeId
0175 << ". Found continuous HBF before start new HBF. data will be ignored." << std::endl;
0176 gbtLink.hbf_error |= mvtx::PayLoadSG::HBF_ERRORS::Incomplete;
0177 }
0178 gbtLink.hbf_length += pageSizeInBytes;
0179
0180 if ((*rdhP).stopBit)
0181 {
0182 gbtLink.cacheData(gbtLink.hbf_length, gbtLink.hbf_error);
0183 gbtLink.hbf_length = 0;
0184 }
0185 }
0186 }
0187 gbtLink.prev_pck_cnt = (*rdhP).packetCounter;
0188
0189
0190 gbtLink.data.add((payload + payload_position), pageSizeInBytes);
0191 payload_position += pageSizeInBytes;
0192 }
0193 }
0194 else
0195 {
0196
0197
0198 if (get_verbosity() > 0)
0199 {
0200 std::cout << "Felix header: " << std::hex << "0x" << std::setfill('0') << std::setw(4);
0201 std::cout << *(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) << std::dec <<std::endl;
0202 }
0203
0204 payload_position += mvtx_utils::FLXWordLength;
0205 continue;
0206 }
0207 }
0208 else
0209 {
0210 break;
0211 }
0212 } while (payload_position < dlength);
0213
0214 return;
0215 }
0216
0217
0218
0219 int mvtx_pool::mvtx_decode()
0220 {
0221 if (m_is_decoded)
0222 {
0223 return 0;
0224 }
0225 m_is_decoded = true;
0226
0227 for (auto& link : mGBTLinks)
0228 {
0229 link.collectROFCableData();
0230 }
0231
0232 return 0;
0233 }
0234
0235
0236 uint32_t mvtx_pool::get_linkId(const uint16_t iLnk)
0237 {
0238 if (mFeeId2LinkID.find(iLnk) == mFeeId2LinkID.cend())
0239 {
0240 log_error << "FeeId " << iLnk
0241 << " was not found in the feeId mapping for this packet"
0242 << std::endl;
0243 return std::numeric_limits<uint32_t>::quiet_NaN();
0244 }
0245 return mFeeId2LinkID[iLnk].entry;
0246 }
0247
0248
0249 size_t mvtx_pool::get_feeidSet_size()
0250 {
0251 mvtx_decode();
0252 return feeid_set.size();
0253 }
0254
0255
0256 int mvtx_pool::get_feeid(const uint16_t iLnk)
0257 {
0258 return (iLnk < feeid_set.size()) ? *(next(feeid_set.begin(), iLnk)) : -1;
0259 }
0260
0261
0262 int mvtx_pool::get_hbfSet_size(const uint16_t iLnk)
0263 {
0264 mvtx_decode();
0265 auto lnkId = get_linkId(iLnk);
0266 if (mGBTLinks[lnkId].rawData.getNPieces() != mGBTLinks[lnkId].hbf_count)
0267 {
0268 log_error << "Mismatch size for HBF from hbfData: "
0269 << mGBTLinks[lnkId].hbf_count << " and link rawData Pieces: "
0270 << mGBTLinks[lnkId].rawData.getNPieces() << std::endl;
0271 return -1;
0272 }
0273 return mGBTLinks[lnkId].hbf_count;
0274 }
0275
0276
0277 int mvtx_pool::get_trgSet_size(const uint16_t iLnk)
0278 {
0279
0280
0281 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mL1TrgTime.size();
0282 }
0283
0284
0285 int mvtx_pool::get_strbSet_size(const uint16_t iLnk)
0286 {
0287
0288
0289 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mTrgData.size();
0290 }
0291
0292
0293 int mvtx_pool::get_L1_IR_BC(const uint16_t iLnk, const uint32_t index)
0294 {
0295
0296
0297
0298
0299 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mL1TrgTime[index].bc;
0300 }
0301
0302
0303 int mvtx_pool::get_TRG_IR_BC(const uint16_t iLnk, const uint32_t index)
0304 {
0305
0306
0307
0308
0309 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mTrgData[index].ir.bc;
0310 }
0311
0312
0313 int mvtx_pool::get_TRG_DET_FIELD(const uint16_t iLnk, const uint32_t index)
0314 {
0315
0316
0317
0318
0319 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mTrgData[index].detectorField;
0320 }
0321
0322
0323 int mvtx_pool::get_TRG_NR_HITS(const uint16_t iLnk, const uint32_t index)
0324 {
0325
0326
0327
0328
0329 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mTrgData[index].hit_vector.size();
0330 }
0331
0332
0333 long long int mvtx_pool::get_L1_IR_BCO(const uint16_t iLnk, const uint32_t index)
0334 {
0335
0336
0337
0338
0339 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mL1TrgTime[index].orbit;
0340 }
0341
0342
0343 long long int mvtx_pool::get_TRG_IR_BCO(const uint16_t iLnk, const uint32_t index)
0344 {
0345
0346
0347
0348
0349 return mGBTLinks[mFeeId2LinkID[iLnk].entry].mTrgData[index].ir.orbit;
0350 }
0351
0352
0353 std::vector<mvtx::mvtx_hit *>& mvtx_pool::get_hits(const int feeId, const int i_strb)
0354 {
0355 return mGBTLinks[mFeeId2LinkID[feeId].entry].mTrgData[i_strb].hit_vector;
0356 }
0357
0358
0359 int mvtx_pool::iValue(const int n, const char *what)
0360 {
0361 mvtx_decode();
0362 if (n == -1)
0363 {
0364 if (strcmp(what, "NR_LINKS") == 0)
0365 {
0366 return get_feeidSet_size();
0367 }
0368 else
0369 {
0370 std::cout << "Unknow option " << what << std::endl;
0371 return -1;
0372 }
0373 }
0374
0375 unsigned int i = n;
0376 if (strcmp(what, "FEEID") == 0)
0377 {
0378 return get_feeid(i);
0379 }
0380 else
0381 {
0382 if ( strcmp(what, "NR_HBF") == 0 )
0383 {
0384 return get_hbfSet_size(i);
0385 }
0386 else if ( strcmp(what, "NR_PHYS_TRG") == 0 )
0387 {
0388 return get_trgSet_size(i);
0389 }
0390 else if ( strcmp(what, "NR_STROBES") == 0 )
0391 {
0392 return get_strbSet_size(i);
0393 }
0394 else if ( strcmp(what, "NR_HITS") == 0 )
0395 {
0396 return -1;
0397 }
0398 else
0399 {
0400 std::cout << "Unknow option " << what << std::endl;
0401 return -1;
0402 }
0403 }
0404 return 0;
0405 }
0406
0407
0408 int mvtx_pool::iValue(const int i_feeid, const int idx, const char *what)
0409 {
0410 mvtx_decode();
0411 uint32_t feeId = i_feeid;
0412 uint32_t index = idx;
0413
0414 if ( strcmp(what, "L1_IR_BC") == 0 )
0415 {
0416 return get_L1_IR_BC(feeId, index);
0417 }
0418 else if ( strcmp(what, "TRG_IR_BC") == 0 )
0419 {
0420 return get_TRG_IR_BC(feeId, index);
0421 }
0422 else if ( strcmp(what, "TRG_DET_FIELD") == 0 )
0423 {
0424 return get_TRG_DET_FIELD(feeId, index);
0425 }
0426 else if ( strcmp(what, "TRG_NR_HITS") == 0)
0427 {
0428 return get_TRG_NR_HITS(feeId, index);
0429 }
0430 else
0431 {
0432 std::cout << "Unknow option " << what << std::endl;
0433 return -1;
0434 }
0435 return 0;
0436 }
0437
0438
0439
0440 int mvtx_pool::iValue(const int i_feeid, const int i_trg, const int i_hit, const char *what)
0441 {
0442 mvtx_decode();
0443
0444 uint32_t feeId = i_feeid;
0445 uint32_t trg = i_trg;
0446 uint32_t hit = i_hit;
0447
0448 if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
0449 {
0450 log_error << "FeeId " << feeId << "was not found in the feeId mapping for this packet" << std::endl;
0451 assert(false);
0452 }
0453 uint32_t lnkId = mFeeId2LinkID[feeId].entry;
0454
0455 if ( strcmp(what, "HIT_CHIP_ID") == 0 )
0456 {
0457 return ( (i_hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].hit_vector.size()) ) ? \
0458 mGBTLinks[lnkId].mTrgData[trg].hit_vector[hit]->chip_id : -1;
0459 }
0460 else if ( strcmp(what, "HIT_BC") == 0 )
0461 {
0462 return ( (i_hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].hit_vector.size()) ) ? \
0463 mGBTLinks[lnkId].mTrgData[trg].hit_vector[hit]->bunchcounter : -1;
0464 }
0465 else if ( strcmp(what, "HIT_ROW") == 0 )
0466 {
0467 return ( (i_hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].hit_vector.size()) ) ? \
0468 mGBTLinks[lnkId].mTrgData[trg].hit_vector[hit]->row_pos : -1;
0469 }
0470 else if ( strcmp(what, "HIT_COL") == 0 )
0471 {
0472 return ( (i_hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].hit_vector.size()) ) ? \
0473 mGBTLinks[lnkId].mTrgData[trg].hit_vector[hit]->col_pos : -1;
0474 }
0475 else
0476 {
0477 std::cout << "Unknow option " << what << std::endl;
0478 return -1;
0479 }
0480 return 0;
0481 }
0482
0483
0484 long long int mvtx_pool::lValue(const int i_feeid, const int idx, const char *what)
0485 {
0486 mvtx_decode();
0487
0488 uint32_t feeId = i_feeid;
0489 uint32_t index = idx;
0490
0491 if ( strcmp(what, "L1_IR_BCO") == 0 )
0492 {
0493 return get_L1_IR_BCO(feeId, index);
0494 }
0495 else if ( strcmp(what, "TRG_IR_BCO") == 0 )
0496 {
0497 return get_TRG_IR_BCO(feeId, index);
0498 }
0499 else
0500 {
0501 std::cout << "Unknow option " << what << std::endl;
0502 return -1;
0503 }
0504
0505 return 0;
0506 }