File indexing completed on 2026-04-06 08:15:47
0001 #include "RDH.h"
0002
0003 #include <cstring>
0004 #include <iostream>
0005 #include <stdexcept>
0006
0007 #if __cplusplus >= 202002L
0008 #include <format>
0009 #endif
0010
0011 using namespace mvtx;
0012
0013
0014
0015 RDHAny::RDHAny(int v)
0016 {
0017 if (v == 0)
0018 {
0019 *this = RDH{};
0020 }
0021 else if (v == 8)
0022 {
0023 *this = RDHv8{};
0024 }
0025 else
0026 {
0027 throw std::runtime_error(std::string("unsupported RDH version ") + std::to_string(v));
0028 }
0029 }
0030
0031
0032 void RDHAny::copyFrom(const void* rdh)
0033 {
0034 std::memcpy(this, rdh, sizeof(RDHAny));
0035 }
0036
0037 #if __cplusplus >= 202002L
0038
0039 void RDHUtils::printRDH(const RDHv8& rdh)
0040 {
0041
0042 std::cout << std::format(
0043 "FlxHdrCntr:{:d} flxId:{:d} pageSize:0x{:03x} gbtLink:0x{:02x} ",
0044 (rdh.flxHdrCntr), (rdh.flxId), (rdh.pageSize), (rdh.gbtLink))
0045 .c_str();
0046 std::cout << std::format(
0047 "FlxHdrSize:0x{:02x} FlxHdrVersion:0x{:02x} FlxHdrCode:0x{:02x}",
0048 (rdh.flxHdrSize), (rdh.flxHdrVersion), (rdh.flxHdrCode))
0049 .c_str();
0050 std::cout << std::endl;
0051 std::cout << std::format(
0052 "RDHversion:0x{:02x} RDHsize:0x{:02x} FEEID:0x{:04x} SrcID:0x{:02x} ",
0053 (rdh.rdhVersion), (rdh.rdhSize), (rdh.feeId), (rdh.sourceId))
0054 .c_str();
0055 std::cout << std::endl;
0056 std::cout << std::format(
0057 "detField:0x{:08x} bc:0x{:03x} orbit:0x{:010x}",
0058 (rdh.detectorField), (rdh.bc), (rdh.orbit))
0059 .c_str();
0060 std::cout << std::endl;
0061 std::cout << std::format(
0062 "trgType:0x{:08x} packetCounter:0x{:04x} stopBit:0x{:01x} priority:0x{:01x} RDHGBTCntr:0x{:04X} ",
0063 (rdh.trgType), (rdh.packetCounter), (rdh.stopBit), (rdh.priority), (rdh.rdhGBTcounter))
0064 .c_str();
0065 std::cout << std::endl;
0066 }
0067 #else
0068 void RDHUtils::printRDH(const RDHv8& )
0069 {
0070 std::cerr << "RDHUtils::printRDH(const RDHv8&) only implemented in c++20." << std::endl;
0071 }
0072 #endif
0073
0074
0075 void RDHUtils::printRDH(const void* rdhP)
0076 {
0077 int version = getVersion(rdhP);
0078 if (version == 8)
0079 {
0080 printRDH(*reinterpret_cast<const RDHv8*>(rdhP));
0081 }
0082 else
0083 {
0084 std::cerr << "Unexpected RDH version " << version << " from";
0085 dumpRDH(rdhP);
0086 throw std::runtime_error("invalid RDH provided");
0087 }
0088 }
0089
0090
0091 #if __cplusplus >= 202002L
0092 void RDHUtils::dumpRDH(const void* rdhP)
0093 {
0094 const uint32_t* w32 = reinterpret_cast<const uint32_t*>(rdhP);
0095 for (int i = 0; i < 4; i++)
0096 {
0097 int l = 4 * i;
0098 std::cout << std::format(
0099 "[rdh{:d}] 0x{:08x} 0x{:08x} 0x{:08x} 0x{:08x}",
0100 i, w32[l + 3], w32[l + 2], w32[l + 1], w32[l])
0101 .c_str();
0102 std::cout << std::endl;
0103 }
0104 }
0105 #else
0106 void RDHUtils::dumpRDH(const void* )
0107 {
0108 std::cerr << "void RDHUtils::dumpRDH(const void*) only implemented in c++20." << std::endl;
0109 }
0110 #endif
0111
0112
0113 bool RDHUtils::checkRDH(const void* rdhP, bool verbose, bool checkZeros)
0114 {
0115 int version = getVersion(rdhP);
0116 bool ok = true;
0117
0118 if (version == 8)
0119 {
0120 ok = checkRDH(*reinterpret_cast<const RDHv8*>(rdhP), verbose, checkZeros);
0121 }
0122 else
0123 {
0124 ok = false;
0125 if (verbose)
0126 {
0127 std::cerr << "WARNING: "
0128 << "Unexpected RDH version " << version << " from" << std::endl;
0129 }
0130 }
0131 if (!ok && verbose)
0132 {
0133 dumpRDH(rdhP);
0134 }
0135 return ok;
0136 }
0137
0138
0139 bool RDHUtils::checkRDH(const RDHv8& rdh, bool verbose, bool checkZeros)
0140 {
0141
0142 bool ok = true;
0143 if (rdh.flxHdrSize != 0x20)
0144 {
0145 if (verbose)
0146 {
0147 std::cerr << "WARNING: "
0148 << "RDH FLX Header Size 0x20 is expected instead of "
0149 << int(rdh.flxHdrSize) << std::endl;
0150 }
0151 ok = false;
0152 }
0153 if (rdh.flxHdrVersion != 0x01)
0154 {
0155 if (verbose)
0156 {
0157 std::cerr << "WARNING: "
0158 << "RDH FLX Header version 0x01 is expected instead of "
0159 << int(rdh.flxHdrVersion) << std::endl;
0160 }
0161 ok = false;
0162 }
0163 if (rdh.flxHdrCode != 0xAB)
0164 {
0165 if (verbose)
0166 {
0167 std::cerr << "WARNING: "
0168 << "RDH FLX Header Code 0xAB is expected instead of "
0169 << int(rdh.flxHdrVersion) << std::endl;
0170 }
0171 ok = false;
0172 }
0173 if (rdh.rdhVersion != 8)
0174 {
0175 if (verbose)
0176 {
0177 std::cerr << "WARNING: "
0178 << "RDH version 7 is expected instead of "
0179 << int(rdh.rdhVersion) << std::endl;
0180 }
0181 ok = false;
0182 }
0183 if (rdh.rdhSize != 32)
0184 {
0185 if (verbose)
0186 {
0187 std::cerr << "WARNING: "
0188 << "RDH with header size of 32 B is expected instead of "
0189 << int(rdh.rdhSize) << std::endl;
0190 }
0191 ok = false;
0192 }
0193 if ((!rdh.packetCounter) && (rdh.stopBit))
0194 {
0195 if (verbose)
0196 {
0197 std::cerr << "WARNING: "
0198 << "RDH stopBit is not expected in packetCounter 0 "
0199 << int(rdh.packetCounter) << int(rdh.stopBit) << std::endl;
0200 }
0201 ok = false;
0202 }
0203 if (checkZeros && (rdh.zero0 || rdh.zero1 || rdh.zero2 || rdh.zero3 || rdh.zero4 || rdh.zero5))
0204 {
0205 if (verbose)
0206 {
0207 std::cerr << "WARNING: "
0208 << "Some reserved fields of RDH v7 are not empty"
0209 << std::endl;
0210 }
0211 ok = false;
0212 }
0213 if (!ok && verbose)
0214 {
0215 dumpRDH(rdh);
0216 }
0217 return ok;
0218 }