File indexing completed on 2026-04-07 08:15:51
0001
0002
0003
0004
0005 #ifndef MVTXDECODER_RDH_H
0006 #define MVTXDECODER_RDH_H
0007
0008 #include <cstdint>
0009 #include <type_traits>
0010
0011 namespace mvtx
0012 {
0013
0014 struct RDHv8
0015 {
0016 #pragma GCC diagnostic push
0017 #pragma GCC diagnostic ignored "-Wpedantic"
0018 union
0019 {
0020
0021 uint64_t word0 = 0x0;
0022 struct
0023 {
0024 uint64_t flxHdrCntr : 32;
0025 uint64_t zero0 : 32;
0026 };
0027 };
0028 union
0029 {
0030 uint64_t word1 = 0x0;
0031 struct
0032 {
0033 uint64_t zero1 : 64;
0034 };
0035 };
0036 union
0037 {
0038 uint64_t word2 = 0x0;
0039 struct
0040 {
0041 uint64_t zero2 : 56;
0042 uint64_t flxId : 8;
0043 };
0044 };
0045 union
0046 {
0047 uint64_t word3 = 0xab01200000000000;
0048 struct
0049 {
0050 uint64_t zero3 : 8;
0051 uint64_t pageSize : 12;
0052 uint64_t zero4 : 12;
0053 uint64_t gbtLink : 5;
0054 uint64_t zero5 : 3;
0055 uint64_t flxHdrSize : 8;
0056 uint64_t flxHdrVersion : 8;
0057 uint64_t flxHdrCode : 8;
0058 };
0059 };
0060
0061 union
0062 {
0063 struct __attribute__((packed))
0064 {
0065 uint64_t word4 = 0x000000ffff2008;
0066 uint16_t word5 = 0x0;
0067 };
0068 struct __attribute__((packed))
0069 {
0070 uint64_t rdhVersion : 8;
0071 uint64_t rdhSize : 8;
0072 uint64_t feeId : 16;
0073 uint64_t sourceId : 8;
0074 uint64_t detectorField : 32;
0075 uint64_t zero6 : 8;
0076 };
0077 };
0078 union
0079 {
0080 struct __attribute__((packed))
0081 {
0082 uint64_t word6 = 0x0;
0083 uint16_t word7 = 0x0;
0084 };
0085 struct __attribute__((packed))
0086 {
0087 uint64_t bc : 12;
0088 uint64_t zero7 : 20;
0089 uint64_t orbit : 40;
0090 uint64_t zero8 : 8;
0091 };
0092 };
0093 union
0094 {
0095 struct __attribute__((packed))
0096 {
0097 uint64_t word8 = 0x0;
0098 uint32_t word9 = 0x0;
0099 };
0100 struct __attribute__((packed))
0101 {
0102 uint64_t trgType : 32;
0103 uint64_t packetCounter : 16;
0104 uint64_t stopBit : 8;
0105 uint64_t priority : 8;
0106 uint64_t zero9 : 16;
0107 uint64_t rdhGBTcounter : 16;
0108 };
0109 };
0110 };
0111 #pragma GCC diagnostic pop
0112
0113 struct RDHAny
0114 {
0115 uint64_t word0 = 0x0;
0116 uint64_t word1 = 0x0;
0117 uint64_t word2 = 0x0;
0118 uint64_t word3 = 0x0;
0119 uint64_t word4 = 0x0;
0120 uint64_t word5 = 0x0;
0121 uint64_t word6 = 0x0;
0122 uint64_t word7 = 0x0;
0123
0124 RDHAny(int v = 0);
0125
0126 template <typename H>
0127 RDHAny(const H& rdh);
0128
0129 template <typename H>
0130 RDHAny& operator=(const H& rdh);
0131
0132
0133 using RDHv8 = mvtx::RDHv8;
0134
0135
0136 template <typename rdh>
0137 static constexpr void sanityCheckStrict()
0138 {
0139 static_assert(std::is_same<rdh, RDHv8>::value,
0140 "not an RDH");
0141 }
0142
0143
0144 template <typename rdh>
0145 static constexpr void sanityCheckLoose()
0146 {
0147 static_assert(std::is_same<rdh, RDHv8>::value || std::is_same<rdh, RDHAny>::value,
0148 "not an RDH or RDHAny");
0149 }
0150
0151 template <typename H>
0152 static const void* voidify(const H& rdh)
0153 {
0154 sanityCheckLoose<H>();
0155 return reinterpret_cast<const void*>(&rdh);
0156 }
0157
0158 template <typename H>
0159 static void* voidify(H& rdh)
0160 {
0161 sanityCheckLoose<H>();
0162 return reinterpret_cast<void*>(&rdh);
0163 }
0164
0165 const void* voidify() const { return voidify(*this); }
0166 void* voidify() { return voidify(*this); }
0167
0168 template <typename H>
0169 H* as_ptr()
0170 {
0171 sanityCheckLoose<H>();
0172 return reinterpret_cast<H*>(this);
0173 }
0174
0175 template <typename H>
0176 H& as_ref()
0177 {
0178 sanityCheckLoose<H>();
0179 return reinterpret_cast<H&>(this);
0180 }
0181
0182 protected:
0183 void copyFrom(const void* rdh);
0184 };
0185
0186 using RDH = RDHv8;
0187
0188 struct RDHUtils
0189 {
0190
0191 #define TOREF(DST, SRC) *reinterpret_cast<DST*>(SRC)
0192
0193 #define TOCREF(DST, SRC) *reinterpret_cast<const DST*>(SRC)
0194
0195 using RDHDef = mvtx::RDH;
0196 using RDHAny = mvtx::RDHAny;
0197
0198
0199 template <typename H>
0200 static constexpr int getVersion()
0201 {
0202 RDHAny::sanityCheckStrict<H>();
0203 if (std::is_same<H, RDHv8>::value)
0204 {
0205 return 8;
0206 }
0207 return -1;
0208 }
0209
0210
0211 template <typename H>
0212 static uint8_t getVersion(const H& rdh)
0213 {
0214 return rdh.rdhVersion;
0215 }
0216 static uint8_t getVersion(const RDHAny& rdh) { return getVersion(rdh.voidify()); }
0217 static uint8_t getVersion(const void* rdhP) { return getVersion(TOCREF(RDHDef, rdhP)); }
0218
0219
0220 static void printRDH(const RDHv8& rdh);
0221 static void printRDH(const RDHAny& rdh) { printRDH(rdh.voidify()); }
0222 static void printRDH(const void* rdhP);
0223
0224
0225 static bool checkRDH(const RDHv8& rdh, bool verbose = true, bool checkZeros = false);
0226 static bool checkRDH(const RDHAny& rdh, bool verbose = true, bool checkZeros = false)
0227 {
0228 return checkRDH(rdh.voidify(), verbose, checkZeros);
0229 }
0230 static bool checkRDH(const void* rdhP, bool verbose = true, bool checkZeros = false);
0231
0232
0233 template <typename H>
0234 static void dumpRDH(const H& rdh)
0235 {
0236 dumpRDH(reinterpret_cast<const void*>(&rdh));
0237 }
0238 static void dumpRDH(const void* rdhP);
0239 };
0240
0241
0242
0243 template <typename H>
0244 inline RDHAny::RDHAny(const H& rdh)
0245 {
0246 sanityCheckLoose<H>();
0247 copyFrom(&rdh);
0248 }
0249
0250
0251
0252 template <typename H>
0253 inline RDHAny& RDHAny::operator=(const H& rdh)
0254 {
0255 sanityCheckLoose<H>();
0256 if (this != voidify(rdh))
0257 {
0258 copyFrom(&rdh);
0259 }
0260 return *this;
0261 }
0262
0263 }
0264
0265 #endif