Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-04-05 08:15:49

0001 #include "oncsSub_idmvtxv3.h"
0002 #include "mvtx_decoder/RDH.h"
0003 #include "mvtx_decoder/mvtx_utils.h"
0004 
0005 // for memset
0006 #include <string>
0007 
0008 using namespace std;
0009 
0010 // define static references
0011 size_t oncsSub_idmvtxv3::mEventId = 0;
0012 std::unordered_map<uint16_t, oncsSub_idmvtxv3::dumpEntry>
0013     oncsSub_idmvtxv3::mFeeId2LinkID = {};
0014 std::vector<mvtx::GBTLink> oncsSub_idmvtxv3::mGBTLinks;
0015 
0016 oncsSub_idmvtxv3::oncsSub_idmvtxv3(subevtdata_ptr data)
0017   : oncsSubevent_w1(data)
0018 {
0019   m_is_decoded = false;
0020   m_decoding_failed = false;
0021 }
0022 
0023 //_________________________________________________
0024 int oncsSub_idmvtxv3::decode()
0025 {
0026   if (m_is_decoded)
0027   {
0028     return 0;
0029   }
0030   m_is_decoded = true;
0031 
0032   feeid_set.clear();
0033 
0034   for (auto &link : mGBTLinks)
0035   {
0036     link.clear(true, true);  // clear data but not the statistics
0037     link.RDHErrors = 0;
0038     link.hbf_length = 0;
0039     link.prev_pck_cnt = 0;
0040   }
0041 
0042   //  short pck_id = getIdentifier();
0043 
0044   payload_start = (uint8_t *) &SubeventHdr->data;  // here begins the payload
0045   payload_length =
0046       getDataLength() - getPadding();  // padding is supposed to be in units of
0047                                        // dwords, this assumes dwords
0048   payload_length *= 4;
0049 
0050   if (payload_length % mvtx_utils::FLXWordLength)
0051   {
0052     payload_length -= payload_length % mvtx_utils::FLXWordLength;
0053     COUT << ENDL << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
0054          << "DMA packet has incomplete FLX words, only " << payload_length
0055          << " bytes(" << (payload_length / mvtx_utils::FLXWordLength)
0056          << " FLX words), will be decoded. \n"
0057          << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
0058          << ENDL;
0059   }
0060   payload_position = 0;
0061 
0062   setupLinks();
0063 
0064   for (auto &link : mGBTLinks)
0065   {
0066     mvtx::GBTLink::CollectedDataStatus decoding_status =
0067         link.collectROFCableData();
0068     if (decoding_status == mvtx::GBTLink::CollectedDataStatus::AbortedOnError)
0069     {
0070       m_decoding_failed = true;
0071       link.clearCableData();
0072     }
0073   }
0074 
0075   ++mEventId;
0076   return 0;
0077 }
0078 
0079 void oncsSub_idmvtxv3::setupLinks()
0080 {
0081   do
0082   {
0083     // Skip FLX padding
0084     if (*(reinterpret_cast<uint16_t *>(&payload_start[payload_position] +
0085                                        30)) == 0xFFFF)
0086     {
0087       payload_position += mvtx_utils::FLXWordLength;
0088     }
0089     else if ((payload_length - payload_position) >=
0090              2 * mvtx_utils::FLXWordLength)  // at least FLX header and RDH
0091     {
0092       if (*(reinterpret_cast<uint16_t *>(&payload_start[payload_position] +
0093                                          30)) == 0xAB01)
0094       {
0095         const auto *rdhP = reinterpret_cast<const mvtx::RDH *>(&payload_start[payload_position]);
0096         if (!mvtx::RDHUtils::checkRDH(mvtx::RDHAny::voidify(*rdhP), true, true))
0097         {
0098           payload_position += mvtx_utils::FLXWordLength;
0099           continue;
0100         }
0101         const size_t pageSizeInBytes =
0102             ((*rdhP).pageSize + 1ULL /*add Flx Hdr word*/) * mvtx_utils::FLXWordLength;
0103         if (pageSizeInBytes > (payload_length - payload_position))
0104         {
0105           COUT << "Incomplete Felix packet, remaining data "
0106                << (payload_length - payload_position);
0107           COUT << " bytes less than " << pageSizeInBytes << " bytes"
0108                << ENDL;
0109           break;  // skip incomplete felix packet
0110         }
0111         else
0112         {
0113           feeid_set.insert((*rdhP).feeId);
0114           auto &lnkref = mFeeId2LinkID[(*rdhP).feeId];
0115           if (lnkref.entry == -1)
0116           {
0117             lnkref.entry = mGBTLinks.size();
0118             mGBTLinks.emplace_back((*rdhP).flxId, (*rdhP).feeId);
0119           }
0120           auto &gbtLink = mGBTLinks[lnkref.entry];
0121 
0122           if (((*rdhP).packetCounter) && (gbtLink.rawData.getNPieces()) &&
0123               ((*rdhP).packetCounter != gbtLink.prev_pck_cnt + 1))
0124           {
0125             log_error << "Incorrect pages count " << (*rdhP).packetCounter
0126                       << ", previous page count was " << gbtLink.prev_pck_cnt
0127                       << std::endl;
0128             payload_position += pageSizeInBytes;
0129             continue;
0130           }
0131           gbtLink.prev_pck_cnt = (*rdhP).packetCounter;
0132 
0133           gbtLink.data.add((payload_start + payload_position), pageSizeInBytes);
0134 
0135           if (!(*rdhP).packetCounter)  // start HB
0136           {
0137             if (gbtLink.hbf_length)
0138             {
0139               log_error << "FLX: " << gbtLink.flxId
0140                         << ", FeeId: " << gbtLink.feeId
0141                         << ". Found new HBF before stop previous HBF. Previous "
0142                            "HBF will be ignored."
0143                         << std::endl;
0144               gbtLink.cacheData(gbtLink.hbf_length, true);
0145             }
0146             gbtLink.hbf_length = pageSizeInBytes;
0147             gbtLink.hbf_error = false;
0148           }
0149           else
0150           {
0151             if ((!gbtLink.hbf_length) && (gbtLink.rawData.getNPieces()))
0152             {
0153               log_error << "FLX: " << gbtLink.flxId
0154                         << ", FeeId: " << gbtLink.feeId
0155                         << ". Found continuous HBF before start new HBF. data "
0156                            "will be ignored."
0157                         << std::endl;
0158               gbtLink.hbf_error = true;
0159             }
0160             gbtLink.hbf_length += pageSizeInBytes;
0161             if ((*rdhP).stopBit)  // found HB end
0162             {
0163               gbtLink.cacheData(gbtLink.hbf_length, gbtLink.hbf_error);
0164               gbtLink.hbf_length = 0;
0165             }
0166           }
0167           payload_position += pageSizeInBytes;
0168         }
0169       }
0170       else
0171       {
0172         // skip raw data without a initial FLX header
0173         // (YCM)TODO: OK for OM but error otherwise
0174         if (0)
0175         {
0176           COUT << "Felix header: " << std::hex << "0x" << std::setfill('0')
0177                << std::setw(4);
0178           COUT << *(reinterpret_cast<uint16_t *>(
0179                       &payload_start[payload_position] + 30))
0180                << std::dec << ENDL;
0181         }
0182         payload_position += mvtx_utils::FLXWordLength;
0183       }
0184     }
0185     else
0186     {
0187       COUT << "Incomplete Felix header, remaining data "
0188            << (payload_length - payload_position);
0189       COUT << " bytes less than " << (2 * mvtx_utils::FLXWordLength)
0190            << ENDL;
0191       break;  // skip incomplete flx_header
0192     }
0193   } while (payload_position < payload_length);
0194 
0195   return;
0196 }
0197 
0198 int oncsSub_idmvtxv3::iValue(const int n, const char *what)
0199 {
0200   decode();
0201   if (m_decoding_failed == true)
0202     return -1;
0203   if (n == -1)  // Global Information.
0204   {
0205     if (strcmp(what, "NR_LINKS") == 0)
0206     {
0207       return feeid_set.size();
0208     }
0209     else
0210     {
0211       COUT << "Unknow option " << what << ENDL;
0212       return -1;
0213     }
0214   }
0215 
0216   unsigned int i = n;
0217   if (strcmp(what, "FEEID") == 0)
0218   {
0219     return (i < feeid_set.size()) ? *(next(feeid_set.begin(), i)) : -1;
0220   }
0221   else
0222   {
0223     if (mFeeId2LinkID.find(i) == mFeeId2LinkID.cend())
0224     {
0225       log_error << "FeeId " << i
0226                 << " was not found in the feeId mapping for this packet"
0227                 << std::endl;
0228     }
0229     uint32_t lnkId = mFeeId2LinkID[i].entry;
0230     if (strcmp(what, "NR_HBF") == 0)
0231     {
0232       if (mGBTLinks[lnkId].rawData.getNPieces() != mGBTLinks[lnkId].hbf_count)
0233       {
0234         log_error << "Mismatch size for HBF from hbfData: "
0235                   << mGBTLinks[lnkId].hbf_count << " and link rawData Pieces: "
0236                   << mGBTLinks[lnkId].rawData.getNPieces() << std::endl;
0237       }
0238       return mGBTLinks[lnkId].hbf_count;
0239     }
0240     else if (strcmp(what, "NR_PHYS_TRG") == 0)
0241     {
0242       return mGBTLinks[lnkId].mL1TrgTime.size();
0243     }
0244     else if (strcmp(what, "NR_STROBES") == 0)
0245     {
0246       return mGBTLinks[lnkId].mTrgData.size();
0247     }
0248     else if (strcmp(what, "RDH_ERRORS") == 0)
0249     {
0250       return mGBTLinks[lnkId].RDHErrors;
0251     }
0252     else if (strcmp(what, "NR_HITS") == 0)  // the number of datasets
0253     {
0254       return mGBTLinks[lnkId].hit_vector.size();
0255     }
0256     else if (strcmp(what, "tdt_lanestatus_error") ==
0257              0)  // the number of datasets
0258     {
0259       int error = -1;
0260       if (!mGBTLinks[lnkId].tdt_lanestatus_error_vector.empty())
0261       {
0262         error = static_cast<int>(
0263             mGBTLinks[lnkId].tdt_lanestatus_error_vector.back());
0264         mGBTLinks[lnkId].tdt_lanestatus_error_vector.pop_back();
0265       }
0266       return error;
0267     }
0268     else
0269     {
0270       COUT << "Unknow option " << what << ENDL;
0271       return -1;
0272     }
0273   }
0274   return 0;
0275 }
0276 
0277 int oncsSub_idmvtxv3::iValue(const int i_feeid, const int idx,
0278                              const char *what)
0279 {
0280   decode();
0281   if (m_decoding_failed == true)
0282     return -1;
0283   uint32_t feeId = i_feeid;
0284   uint32_t index = idx;
0285 
0286   if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
0287   {
0288     log_error << "FeeId " << feeId
0289               << " was not found in the feeId mapping for this packet"
0290               << std::endl;
0291     return -1;
0292   }
0293   uint32_t lnkId = mFeeId2LinkID[feeId].entry;
0294 
0295   if (strcmp(what, "L1_IR_BC") == 0)
0296   {
0297     return (index < mGBTLinks[lnkId].mL1TrgTime.size())
0298                ? mGBTLinks[lnkId].mL1TrgTime[index].bc
0299                : -1;
0300   }
0301   else if (strcmp(what, "TRG_IR_BC") == 0)
0302   {
0303     return (index < mGBTLinks[lnkId].mTrgData.size())
0304                ? mGBTLinks[lnkId].mTrgData[index].ir.bc
0305                : -1;
0306   }
0307   else if (strcmp(what, "TRG_NR_HITS") == 0)
0308   {
0309     return (index < mGBTLinks[lnkId].mTrgData.size())
0310                ? mGBTLinks[lnkId].mTrgData[index].n_hits
0311                : -1;
0312   }
0313   else
0314   {
0315     COUT << "Unknow option " << what << ENDL;
0316     return -1;
0317   }
0318   return 0;
0319 }
0320 
0321 int oncsSub_idmvtxv3::iValue(const int i_feeid, const int i_trg,
0322                              const int i_hit, const char *what)
0323 {
0324   decode();
0325   if (m_decoding_failed == true)
0326     return -1;
0327 
0328   uint32_t feeId = i_feeid;
0329   uint32_t trg = i_trg;
0330   uint32_t hit = i_hit;
0331 
0332   if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
0333   {
0334     log_error << "FeeId " << feeId
0335               << "was not found in the feeId mapping for this packet"
0336               << std::endl;
0337     return -1;
0338   }
0339   uint32_t lnkId = mFeeId2LinkID[feeId].entry;
0340 
0341   uint32_t hit_global_id = mGBTLinks[lnkId].mTrgData[trg].first_hit_pos + hit;
0342 
0343   if (strcmp(what, "HIT_CHIP_ID") == 0)
0344   {
0345     return ((hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits))
0346                ? mGBTLinks[lnkId].hit_vector[hit_global_id]->chip_id
0347                : -1;
0348   }
0349   else if (strcmp(what, "HIT_BC") == 0)
0350   {
0351     return ((hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits))
0352                ? mGBTLinks[lnkId].hit_vector[hit_global_id]->bunchcounter
0353                : -1;
0354   }
0355   else if (strcmp(what, "HIT_ROW") == 0)
0356   {
0357     return ((hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits))
0358                ? mGBTLinks[lnkId].hit_vector[hit_global_id]->row_pos
0359                : -1;
0360   }
0361   else if (strcmp(what, "HIT_COL") == 0)
0362   {
0363     return ((hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits))
0364                ? mGBTLinks[lnkId].hit_vector[hit_global_id]->col_pos
0365                : -1;
0366   }
0367   else
0368   {
0369     COUT << "Unknow option " << what << ENDL;
0370     return -1;
0371   }
0372   return 0;
0373 }
0374 
0375 long long int oncsSub_idmvtxv3::lValue(const int i_feeid, const char *what)
0376 {
0377   decode();
0378   // if(m_decoding_failed == true) return -1; should be commented - decoder
0379   // errors are filled even when decoding failed
0380 
0381   uint32_t feeId = i_feeid;
0382 
0383   if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
0384   {
0385     log_error << "FeeId " << feeId
0386               << "was not found in the feeId mapping for this packet"
0387               << std::endl;
0388     return -1;
0389   }
0390   uint32_t lnkId = mFeeId2LinkID[feeId].entry;
0391 
0392   if (strcmp(what, "decoder_error") == 0)  // the number of datasets
0393   {
0394     long long int error = -1;
0395     if (!mGBTLinks[lnkId].decoder_error_vector.empty())
0396     {
0397       std::pair<int, int> pop = mGBTLinks[lnkId].decoder_error_vector.back();
0398       error = (long long int) pop.first << 32 | pop.second;
0399       mGBTLinks[lnkId].decoder_error_vector.pop_back();
0400     }
0401     return error;
0402   }
0403   else
0404   {
0405     COUT << "Unknow option " << what << ENDL;
0406     return -1;
0407   }
0408 
0409   return 0;
0410 }
0411 
0412 long long int oncsSub_idmvtxv3::lValue(const int i_feeid, const int idx,
0413                                        const char *what)
0414 {
0415   decode();
0416   if (m_decoding_failed == true)
0417     return -1;
0418 
0419   uint32_t feeId = i_feeid;
0420   uint32_t index = idx;
0421 
0422   if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
0423   {
0424     log_error << "FeeId " << feeId
0425               << "was not found in the feeId mapping for this packet"
0426               << std::endl;
0427     return -1;
0428   }
0429   uint32_t lnkId = mFeeId2LinkID[feeId].entry;
0430 
0431   if (strcmp(what, "L1_IR_BCO") == 0)
0432   {
0433     return (index < mGBTLinks[lnkId].mL1TrgTime.size())
0434                ? mGBTLinks[lnkId].mL1TrgTime[index].orbit
0435                : -1;
0436   }
0437   else if (strcmp(what, "TRG_IR_BCO") == 0)
0438   {
0439     return (index < mGBTLinks[lnkId].mTrgData.size())
0440                ? mGBTLinks[lnkId].mTrgData[index].ir.orbit
0441                : -1;
0442   }
0443   else
0444   {
0445     COUT << "Unknow option " << what << ENDL;
0446     return -1;
0447   }
0448 
0449   return 0;
0450 }
0451 
0452 //_________________________________________________
0453 void *oncsSub_idmvtxv3::pValue(const int channel)
0454 {
0455   if (channel == getIdentifier())
0456   {
0457     return &SubeventHdr->data;
0458   }
0459 
0460   return nullptr;
0461 }
0462 
0463 //_________________________________________________
0464 void oncsSub_idmvtxv3::dump(OSTREAM &os)
0465 {
0466   identify(os);
0467   decode();
0468 
0469   // Debug HB pooling
0470   int num_feeids = iValue(-1, "NR_LINKS");
0471   os << "Event: " << mEventId << " Number of feeid: " << num_feeids
0472      << std::endl;
0473   if (num_feeids > 0)
0474   {
0475     for (int i = 0; i < num_feeids; ++i)
0476     {
0477       auto feeId = iValue(i, "FEEID");
0478       auto hbfSize = iValue(feeId, "NR_HBF");
0479       int layer = feeId >> 12;
0480       int gbtx = (feeId >> 8) & 0x3;
0481       int stave = feeId & 0x3f;
0482       os << "FeeId " << hex << setw(4) << setfill('0') << feeId << dec << " (L"
0483          << layer << "_" << setw(2) << stave << " GBTx" << setw(1) << gbtx
0484          << ") has " << hbfSize << " HBs, ";
0485       os << iValue(feeId, "NR_STROBES") << " strobes and ";
0486       os << iValue(feeId, "NR_PHYS_TRG") << " L1 triggers" << std::endl;
0487 
0488       for (int iL1 = 0; iL1 < iValue(feeId, "NR_PHYS_TRG"); ++iL1)
0489       {
0490         os << "L1: " << iL1 << std::hex << " BCO: 0x"
0491            << lValue(feeId, iL1, "L1_IR_BCO");
0492         os << std::dec << " BC: " << iValue(feeId, iL1, "L1_IR_BC") << endl;
0493       }
0494 
0495       os << "Total number of hits: " << iValue(feeId, "NR_HITS") << endl;
0496       for (int i_trg = 0; i_trg < iValue(feeId, "NR_STROBES"); ++i_trg)
0497       {
0498         os << "-- Strobe: " << i_trg;
0499         os << ", BCO: 0x" << std::hex << lValue(feeId, i_trg, "TRG_IR_BCO")
0500            << std::dec;
0501         os << " BC: " << iValue(feeId, i_trg, "TRG_IR_BC");
0502         os << ", has " << iValue(feeId, i_trg, "TRG_NR_HITS") << " hits."
0503            << std::endl;
0504 
0505         if (iValue(feeId, i_trg, "TRG_NR_HITS"))
0506         {
0507           os << "   hit number chip_id  bc   row   col  " << endl;
0508         }
0509         for (int i_hit = 0; i_hit < iValue(feeId, i_trg, "TRG_NR_HITS");
0510              ++i_hit)
0511         {
0512           os << setw(4) << i_hit;
0513           os << "  " << setw(9) << iValue(feeId, i_trg, i_hit, "HIT_CHIP_ID");
0514           os << "  " << setw(8) << std::hex
0515              << iValue(feeId, i_trg, i_hit, "HIT_BC") << std::dec;
0516           os << "  " << setw(4) << iValue(feeId, i_trg, i_hit, "HIT_ROW");
0517           os << "  " << setw(4) << iValue(feeId, i_trg, i_hit, "HIT_COL");
0518           os << endl;
0519         }
0520       }
0521     }
0522   }
0523 
0524   return;
0525 }
0526 
0527 std::string interpretGbtPacket(const unsigned char packetCode)
0528 {
0529   std::string msg;
0530   switch (packetCode)
0531   {
0532   case 0x0:
0533     msg = " RDH     ";
0534     break;
0535   case 0xe0:
0536     msg = " IHW     ";
0537     break;
0538   case 0xe8:
0539     msg = " TDH     ";
0540     break;
0541   case 0xf0:
0542     msg = " TDT     ";
0543     break;
0544   case 0xe4:
0545     msg = " DDW     ";
0546     break;
0547   case 0xf8:
0548     msg = " CDW     ";
0549     break;
0550   case 0x20 ... 0x28:
0551     msg = " DTA     ";
0552     break;
0553   case 0xa0 ... 0xa8:
0554     msg = " Diag DTA";
0555     break;
0556   default:
0557     msg = " ...     ";
0558   }
0559   return msg;
0560 }
0561 
0562 //_________________________________________________
0563 void oncsSub_idmvtxv3::gdump(const int i, OSTREAM &out) const
0564 {
0565   uint8_t *SubeventData = reinterpret_cast<uint8_t *>(&SubeventHdr->data);
0566 
0567   if (i == EVT_RAW)
0568   {
0569     fwrite(SubeventData, sizeof(int), getDataLength(), stdout);
0570     return;
0571   }
0572 
0573   if (i == EVT_RAW_WH)
0574   {
0575     fwrite(SubeventHdr, sizeof(int), getLength(), stdout);
0576     return;
0577   }
0578 
0579   unsigned int j;
0580   int l;
0581   std::string msg;
0582   bool isFelixHeader;
0583   char cstring[20];
0584   char *c;
0585 
0586   identify(out);
0587 
0588   j = 0;
0589   switch (i)
0590   {
0591   case (EVT_HEXADECIMAL):
0592     while (1)
0593     {
0594       msg = "";
0595       isFelixHeader = false;
0596       out << std::hex << SETW(5) << j << " |  ";
0597       if (*reinterpret_cast<uint16_t *>(&SubeventData[j + 30]) == 0xab01)
0598       {
0599         msg = " | FELIX Header";
0600         isFelixHeader = true;
0601         msg += " GBT " + std::to_string(static_cast<int>(SubeventData[j + 28]));
0602         msg += " DMA Cnt " +
0603                std::to_string((static_cast<int>(SubeventData[j + 26])) * 256 +
0604                               static_cast<int>(SubeventData[j + 25]));
0605       }
0606       else
0607       {
0608         msg += " |";
0609         msg += interpretGbtPacket(SubeventData[j + 9]);
0610       }
0611       for (l = 0; l < 10; l++)
0612       {
0613         if (j < 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0614                      SubeventHdr->sub_padding))
0615         {
0616           out << std::hex << SETW(2) << static_cast<u_int>(SubeventData[j])
0617               << " ";
0618         }
0619         j++;
0620       }
0621       out << " ";
0622       if (!isFelixHeader)
0623       {
0624         if ((SubeventData[j + 20] % 3 == 2) ||
0625             (SubeventData[j + 20] % 3 == 0))
0626         {
0627           msg += " |";
0628           msg += interpretGbtPacket(SubeventData[j + 9]);
0629         }
0630       }
0631       for (l = 10; l < 20; l++)
0632       {
0633         if (j < 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0634                      SubeventHdr->sub_padding))
0635         {
0636           out << std::hex << SETW(2) << static_cast<u_int>(SubeventData[j])
0637               << " ";
0638         }
0639         j++;
0640       }
0641       out << " ";
0642       if (!isFelixHeader)
0643       {
0644         if (SubeventData[j + 10] % 3 == 0)
0645         {
0646           msg += " |";
0647           msg += interpretGbtPacket(SubeventData[j + 9]);
0648         }
0649       }
0650       for (l = 20; l < 30; l++)
0651       {
0652         if (j < 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0653                      SubeventHdr->sub_padding))
0654         {
0655           out << std::hex << SETW(2) << static_cast<u_int>(SubeventData[j])
0656               << " ";
0657         }
0658         j++;
0659       }
0660       out << " ";
0661       for (l = 30; l < 32; l++)
0662       {
0663         if (j < 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0664                      SubeventHdr->sub_padding))
0665         {
0666           out << std::hex << SETW(2) << static_cast<u_int>(SubeventData[j])
0667               << " ";
0668         }
0669         j++;
0670       }
0671       out << msg << std::endl;
0672       if (j >= 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0673                     SubeventHdr->sub_padding))
0674         break;
0675     }
0676     break;
0677 
0678   case (EVT_DECIMAL):
0679     while (1)
0680     {
0681       c = cstring;
0682       out << std::dec << SETW(5) << j << " |  ";
0683       for (l = 0; l < 16; l++)
0684       {
0685         if (j < 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0686                      SubeventHdr->sub_padding))
0687         {
0688           out << SETW(3) << static_cast<u_int>(SubeventData[j]) << " ";
0689           if (SubeventData[j] >= 32 && SubeventData[j] < 127)
0690           {
0691             *c++ = SubeventData[j];
0692           }
0693           else
0694           {
0695             *c++ = 0x20;
0696           }
0697           out << " ";
0698         }
0699         j++;
0700       }
0701       *c = 0;
0702       out << "  | " << cstring;
0703       out << std::endl;
0704       if (j >= 4 * (SubeventHdr->sub_length - SEVTHEADERLENGTH -
0705                     SubeventHdr->sub_padding))
0706         break;
0707     }
0708     break;
0709 
0710   default:
0711     break;
0712   }
0713   out << std::endl;
0714 }
0715 
0716 //_________________________________________________
0717 oncsSub_idmvtxv3::~oncsSub_idmvtxv3()
0718 {
0719   for (auto &&link : mGBTLinks)
0720   {
0721     link.clear(true, true);
0722   }
0723   feeid_set.clear();
0724 }