Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:20:48

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