Back to home page

sPhenix code displayed by LXR

 
 

    


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     // clear data and the statistics
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   // force decode data after new packet
0042   m_is_decoded = false;
0043 
0044   for (auto& link : mGBTLinks)
0045   {
0046     // clear data but not the statistics
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   // here begins the payload
0073   uint8_t* payload_start = reinterpret_cast<uint8_t*>(p->pValue(p->getIdentifier()));
0074   //padding is supposed to be in units of dwords, this assumes dwords
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   // Add raw data from packet to buffer
0091   mBuffer.add(payload_start, dlength);
0092 
0093   // Repositioning pointer to unread data in the buffer
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     // Skip FLX padding
0107     if (*(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xFFFF)
0108     {
0109       payload_position += mvtx_utils::FLXWordLength;
0110     }
0111     // at least one combine FLX header and RDH words
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           // In case of corrupt RDH, skip felix word and continue to next
0124           payload_position += mvtx_utils::FLXWordLength;
0125           continue;
0126         }
0127         const size_t pageSizeInBytes = ((*rdhP).pageSize + 1ULL /*add Flx Hdr word*/) * 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           // skip incomplete felix packet, return to fetch more data
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) // start HB
0150           {
0151             // close previous HBF without stop Bit
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) // found HB end
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           // move packet to buffer
0190           gbtLink.data.add((payload + payload_position), pageSizeInBytes);
0191           payload_position += pageSizeInBytes;
0192         }
0193       }
0194       else
0195       {
0196         // skip raw data without a initial FLX header
0197         // (YCM)TODO: OK for OM but error otherwise
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         // move to next flx word and continue flx word loop
0204         payload_position += mvtx_utils::FLXWordLength;
0205         continue;
0206       }
0207     }
0208     else
0209     {
0210       break; // skip incomplete flx_header
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   // mvtx_decode();
0280   // auto lnkId = get_linkId(iLnk);
0281   return mGBTLinks[mFeeId2LinkID[iLnk].entry].mL1TrgTime.size();
0282 }
0283 
0284 //_________________________________________________
0285 int mvtx_pool::get_strbSet_size(const uint16_t iLnk)
0286 {
0287   // mvtx_decode();
0288   // auto lnkId = get_linkId(iLnk);
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   // mvtx_decode();
0296   // auto lnkId = get_linkId(iLnk);
0297   // return (index < mGBTLinks[lnkId].mL1TrgTime.size()) ?
0298   //         mGBTLinks[lnkId].mL1TrgTime[index].bc : -1;
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   // mvtx_decode();
0306   // auto lnkId = get_linkId(iLnk);
0307   // return (index < mGBTLinks[lnkId].mTrgData.size()) ?
0308   //         mGBTLinks[lnkId].mTrgData[index].ir.bc : -1;
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   // mvtx_decode();
0316   // auto lnkId = get_linkId(iLnk);
0317   // return (index < mGBTLinks[lnkId].mTrgData.size()) ?
0318   //         mGBTLinks[lnkId].mTrgData[index].detectorField : -1;
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   // mvtx_decode();
0326   // auto lnkId = get_linkId(iLnk);
0327   // return (index < mGBTLinks[lnkId].mTrgData.size()) ?
0328   //         mGBTLinks[lnkId].mTrgData[index].hit_vector.size() : -1;
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   // mvtx_decode();
0336   // auto lnkId = get_linkId(iLnk);
0337   // return (index < mGBTLinks[lnkId].mL1TrgTime.size()) ?
0338   //         mGBTLinks[lnkId].mL1TrgTime[index].orbit : -1;
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   // mvtx_decode();
0346   // auto lnkId = get_linkId(iLnk);
0347   // return (index < mGBTLinks[lnkId].mTrgData.size()) ?
0348   //         mGBTLinks[lnkId].mTrgData[index].ir.orbit : -1;
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) // Global Information.
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 )  // the number of datasets
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 }