15#include <fmt/format.h>
16#include <fmt/printf.h>
26constexpr uint64_t HAMMING_CODE_OFFSET = 0;
27constexpr uint64_t HEADER_PARITY_OFFSET = 6;
28constexpr uint64_t PACKET_TYPE_OFFSET = 7;
29constexpr uint64_t NUMBER_OF_1OBITS_WORDS_OFFSET = 10;
30constexpr uint64_t CHIP_ADDRESS_OFFSET = 20;
31constexpr uint64_t CHANNEL_ADDRESS_OFFSET = 24;
32constexpr uint64_t BUNCH_CROSSING_OFFSET = 29;
33constexpr uint64_t PARITY_OFFSET = 49;
35constexpr uint64_t HAMMING_CODE_NOFBITS = HEADER_PARITY_OFFSET - HAMMING_CODE_OFFSET;
36constexpr uint64_t HEADER_PARITY_NOFBITS = PACKET_TYPE_OFFSET - HEADER_PARITY_OFFSET;
37constexpr uint64_t PACKET_TYPE_NOFBITS = NUMBER_OF_1OBITS_WORDS_OFFSET - PACKET_TYPE_OFFSET;
38constexpr uint64_t NUMBER_OF_1OBITS_WORDS_NOFBITS = CHIP_ADDRESS_OFFSET - NUMBER_OF_1OBITS_WORDS_OFFSET;
39constexpr uint64_t CHIP_ADDRESS_NOFBITS = CHANNEL_ADDRESS_OFFSET - CHIP_ADDRESS_OFFSET;
40constexpr uint64_t CHANNEL_ADDRESS_NOFBITS = BUNCH_CROSSING_OFFSET - CHANNEL_ADDRESS_OFFSET;
41constexpr uint64_t BUNCH_CROSSING_NOFBITS = PARITY_OFFSET - BUNCH_CROSSING_OFFSET;
42constexpr uint64_t PARITY_NOFBITS = 50 - PARITY_OFFSET;
48 if (HAMMING_CODE_NOFBITS != 6) {
49 throw std::invalid_argument(fmt::format(
"HAMMING_CODE_NOFBITS is {0}. Should be 6", HAMMING_CODE_NOFBITS));
51 if (HEADER_PARITY_NOFBITS != 1) {
52 throw std::invalid_argument(fmt::format(
"HEADER_PARITY_NOFBITS is {0}. Should be 1", HEADER_PARITY_NOFBITS));
54 if (PACKET_TYPE_NOFBITS != 3) {
55 throw std::invalid_argument(fmt::format(
"PACKET_TYPE_NOFBITS is {0}. Should be 3", PACKET_TYPE_NOFBITS));
57 if (NUMBER_OF_1OBITS_WORDS_NOFBITS != 10) {
58 throw std::invalid_argument(fmt::format(
"NUMBER_OF_1OBITS_WORDS_NOFBITS is {0}. Should be 10", NUMBER_OF_1OBITS_WORDS_NOFBITS));
60 if (CHIP_ADDRESS_NOFBITS != 4) {
61 throw std::invalid_argument(fmt::format(
"CHIP_ADDRESS_NOFBITS is {0}. Should be 4", CHIP_ADDRESS_NOFBITS));
63 if (CHANNEL_ADDRESS_NOFBITS != 5) {
64 throw std::invalid_argument(fmt::format(
"CHANNEL_ADDRESS_NOFBITS is {0}. Should be 5", CHANNEL_ADDRESS_NOFBITS));
66 if (BUNCH_CROSSING_NOFBITS != 20) {
67 throw std::invalid_argument(fmt::format(
"BUNCH_CROSSING_NOFBITS is {0}. Should be 20", BUNCH_CROSSING_NOFBITS));
69 if (PARITY_NOFBITS != 1) {
70 throw std::invalid_argument(fmt::format(
"PARITY_NOFBITS is {0}. Should be 1", PARITY_NOFBITS));
75CHECKNOFBITS checknofbits;
77constexpr uint64_t HAMMING_CODE_MASK = 0x000000000003F;
78constexpr uint64_t HEADER_PARITY_MASK = 0x0000000000040;
79constexpr uint64_t PACKET_TYPE_MASK = 0x0000000000380;
80constexpr uint64_t NUMBER_OF_1OBITS_WORDS_MASK = 0x00000000FFC00;
81constexpr uint64_t CHIP_ADDRESS_MASK = 0x0000000F00000;
82constexpr uint64_t CHANNEL_ADDRESS_MASK = 0x000001F000000;
83constexpr uint64_t BUNCH_CROSSING_MASK = 0x1FFFFE0000000;
84constexpr uint64_t PARITY_MASK = 0x2000000000000;
88 return ((
header & HAMMING_CODE_MASK) >> HAMMING_CODE_OFFSET);
93 return ((
header & HEADER_PARITY_MASK) >> HEADER_PARITY_OFFSET);
97 return ((
header & PACKET_TYPE_MASK) >> PACKET_TYPE_OFFSET);
102 return ((
header & NUMBER_OF_1OBITS_WORDS_MASK) >> NUMBER_OF_1OBITS_WORDS_OFFSET);
107 return ((
header & CHIP_ADDRESS_MASK) >> CHIP_ADDRESS_OFFSET);
111 return ((
header & CHANNEL_ADDRESS_MASK) >> CHANNEL_ADDRESS_OFFSET);
116 return ((
header & BUNCH_CROSSING_MASK) >> BUNCH_CROSSING_OFFSET);
121 return ((
header & PARITY_MASK) >> PARITY_OFFSET);
126 return (
value >>
i & 1) ==
static_cast<int>(bitStatus);
136 for (
int i = 7;
i <= 9;
i++) {
137 if (!checkBit(
header,
i,
false)) {
141 for (
int i = 10;
i <= 19;
i++) {
142 if (!checkBit(
header,
i,
false)) {
146 if (!checkBit(
header, 24,
true) || !checkBit(
header, 26,
true) || !checkBit(
header, 28,
true) || !checkBit(
header, 25,
false) || !checkBit(
header, 27,
false) || !checkBit(
header, 49,
false)) {
167 return "DataTruncated";
173 return "DataTruncatedTriggerTooEarly";
179 return "DataNumWords";
182 return "DataTriggerTooEarl";
185 return "DataTriggerTooEarlyNumWords";
187 throw std::out_of_range(
"should not happen");
237 mValue &= ~HEADER_PARITY_MASK;
238 mValue += (
static_cast<uint64_t>(p) << HEADER_PARITY_OFFSET) & HEADER_PARITY_MASK;
243 mValue &= ~PARITY_MASK;
244 mValue += (
static_cast<uint64_t>(dp) << PARITY_OFFSET) & PARITY_MASK;
249 mValue &= ~CHIP_ADDRESS_MASK;
250 mValue += (
static_cast<uint64_t>(
h) << CHIP_ADDRESS_OFFSET) & CHIP_ADDRESS_MASK;
255 mValue &= ~CHANNEL_ADDRESS_MASK;
256 mValue += (
static_cast<uint64_t>(ch) << CHANNEL_ADDRESS_OFFSET) & CHANNEL_ADDRESS_MASK;
261 mValue &= ~BUNCH_CROSSING_MASK;
262 mValue += (
static_cast<uint64_t>(bx) << BUNCH_CROSSING_OFFSET) & BUNCH_CROSSING_MASK;
267 mValue &= ~HAMMING_CODE_MASK;
268 mValue += (
static_cast<uint64_t>(hamming) << HAMMING_CODE_OFFSET) & HAMMING_CODE_MASK;
273 mValue &= ~NUMBER_OF_1OBITS_WORDS_MASK;
274 mValue += (
static_cast<uint64_t>(nofwords) << NUMBER_OF_1OBITS_WORDS_OFFSET) & NUMBER_OF_1OBITS_WORDS_MASK;
279 mValue &= ~PACKET_TYPE_MASK;
280 mValue += (
static_cast<uint64_t>(pkt) << PACKET_TYPE_OFFSET) & PACKET_TYPE_MASK;
305 return mValue == rhs.mValue;
310 return !(*
this == rhs);
315 return ::isHeartbeat(mValue);
320 return ::hammingCode(mValue) & 0X3F;
325 return ::headerParity(mValue) == 1;
337 return ::nof10BitWords(mValue) & 0x3FF;
343 return ::chipAddress(mValue) & 0xF;
349 return ::channelAddress(mValue) & 0x1F;
355 return ::bunchCrossingCounter(mValue) & 0x1FFFFF;
360 return ::payloadParity(mValue) == 1;
391 std::stringstream os;
394 std::vector<int> sep = {5, 6, 9, 19, 23, 28, 48};
395 for (
int i = 0;
i < 50;
i++) {
396 os << ((sh.
uint64() & (
one <<
i)) ?
"1" :
"0");
397 if (std::find(begin(sep),
end(sep),
i) !=
end(sep)) {
402 os << fmt::sprintf(
"%6x %d %3x %10x %4x %5x %20x %d (0x%x) | HeaderType: %s %s",
428constexpr std::array<int, 49>
conv = {-1, -1, 7, -1, 8, 9, 10, -1, 11, 12, 13, 14, 15, 16, 17,
429 -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
430 29, 30, 31, 32, -1, 33, 34, 35, 36, 37, 38, 39,
431 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};
448 if ((
i + 1) &
test) {
454 return (
n + 1) % 2 == 0;
463 for (
int i = 0;
i < 6;
i++) {
475 for (
auto i = 0;
i <
pos.size();
i++) {
476 n += ((
value & (one << pos[i])) > 0);
478 return (
n + 1) % 2 == 0;
485 for (
auto i = 0;
i < masks.size();
i++) {
488 return (
n + 1) % 2 == 0;
491std::array<int, 24>
p0{7, 8, 10, 11, 13, 15, 17, 18, 20, 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 47, 49};
492std::array<int, 23>
p1{7, 9, 10, 12, 13, 16, 17, 19, 20, 23, 24, 27, 28, 31, 32, 34, 35, 38, 39, 42, 43, 46, 47};
493std::array<int, 23>
p2{8, 9, 10, 14, 15, 16, 17, 21, 22, 23, 24, 29, 30, 31, 32, 36, 37, 38, 39, 44, 45, 46, 47};
494std::array<int, 23>
p3{11, 12, 13, 14, 15, 16, 17, 25, 26, 27, 28, 29, 30, 31, 32, 40, 41, 42, 43, 44, 45, 46, 47};
495std::array<int, 17>
p4{18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 49};
496std::array<int, 17>
p5{33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};
509 return h0 + h1 * 2 + h2 * 4 + h3 * 8 + h4 * 16 + h5 * 32;
512std::array<uint64_t, 24>
m0 = {0x80, 0x100, 0x400, 0x800, 0x2000, 0x8000, 0x20000, 0x40000, 0x100000, 0x400000, 0x1000000, 0x4000000, 0x10000000, 0x40000000, 0x100000000, 0x200000000, 0x800000000, 0x2000000000, 0x8000000000, 0x20000000000, 0x80000000000, 0x200000000000, 0x800000000000, 0x2000000000000};
513std::array<uint64_t, 23>
m1 = {0x80, 0x200, 0x400, 0x1000, 0x2000, 0x10000, 0x20000, 0x80000, 0x100000, 0x800000, 0x1000000, 0x8000000, 0x10000000, 0x80000000, 0x100000000, 0x400000000, 0x800000000, 0x4000000000, 0x8000000000, 0x40000000000, 0x80000000000, 0x400000000000, 0x800000000000};
514std::array<uint64_t, 23>
m2 = {0x100, 0x200, 0x400, 0x4000, 0x8000, 0x10000, 0x20000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x20000000, 0x40000000, 0x80000000, 0x100000000, 0x1000000000, 0x2000000000, 0x4000000000, 0x8000000000, 0x100000000000, 0x200000000000, 0x400000000000, 0x800000000000};
515std::array<uint64_t, 23>
m3 = {0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x100000000, 0x10000000000, 0x20000000000, 0x40000000000, 0x80000000000, 0x100000000000, 0x200000000000, 0x400000000000, 0x800000000000};
516std::array<uint64_t, 17>
m4 = {0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x100000000, 0x1000000000000, 0x2000000000000};
517std::array<uint64_t, 17>
m5 = {0x200000000, 0x400000000, 0x800000000, 0x1000000000, 0x2000000000, 0x4000000000, 0x8000000000, 0x10000000000, 0x20000000000, 0x40000000000, 0x80000000000, 0x100000000000, 0x200000000000, 0x400000000000, 0x800000000000, 0x1000000000000, 0x2000000000000};
535 return h0 + h1 * 2 + h2 * 4 + h3 * 8 + h4 * 16 + h5 * 32;
542 for (
auto i = 0;
i < masks.size();
i++) {
545 std::cout << fmt::format(
"0x{:X},",
v);
554 constexpr std::array<uint64_t, 6> masks = {0x2AAAB5556AD80,
555 0xCCCD999B3680, 0xF0F1E1E3C700,
556 0xFF01FE03F800, 0x30001FFFC0000,
564 return h0 + h1 * 2 + h2 * 4 + h3 * 8 + h4 * 16 + h5 * 32;
579 for (
int i = 0;
i < 6;
i++) {
580 if (
v & (
one <<
i)) {
584 for (
int i = 7;
i < 50;
i++) {
585 if (
v & (
one <<
i)) {
589 return (
n + 1) % 2 == 0;
592constexpr std::array<uint64_t, 49>
parityMasks = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x100000000, 0x200000000, 0x400000000, 0x800000000, 0x1000000000, 0x2000000000, 0x4000000000, 0x8000000000, 0x10000000000, 0x20000000000, 0x40000000000, 0x80000000000, 0x100000000000, 0x200000000000, 0x400000000000, 0x800000000000, 0x1000000000000, 0x2000000000000};
603 return (
n + 1) % 2 == 0;
615 return (
short)(
result & 0x1);
626 return (
short)(no & 0x1);
unsigned short int uint16_t
std::vector< std::string > header
o2::raw::RawFileWriter * raw
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Class for time synchronization of RawReader instances.
GLsizei const GLfloat * value
void assertNofBits(std::string_view msg, T value, int n)
constexpr std::array< uint64_t, 49 > parityMasks
int computeHeaderParity(uint64_t value)
int computeHammingCode3(uint64_t value)
DualSampaChannelId getDualSampaChannelId(const SampaHeader &sh)
Return channel number (0..63)
std::string packetTypeName(SampaPacketType pkt)
packetTypeName returns a string representation of the given packet type.
int partialOddParity3(uint64_t value, int pos)
constexpr std::array< int, 49 > conv
int computeHeaderParity1(uint64_t value)
SampaHeader sampaHeartbeat(uint8_t elinkId, uint20_t bunchCrossing)
Heartbeat packet.
std::array< uint64_t, 24 > m0
SampaHeader sampaSync()
The 50-bits Sampa SYNC word.
int computeHammingCode2(uint64_t value)
std::array< uint64_t, 23 > m2
int computeHeaderParity4(uint64_t value)
@ DataTriggerTooEarlyNumWords
@ DataTruncatedTriggerTooEarly
int computeParity(uint64_t v)
int computeHammingCode1(uint64_t value)
int partialOddParity(uint64_t value, const std::array< uint64_t, N > &masks)
int computeHeaderParity2(uint64_t value)
std::array< uint64_t, 17 > m5
std::array< uint64_t, 17 > m4
int computeHeaderParity3(uint64_t value)
std::string asString(const SampaCluster &sc)
std::array< uint64_t, 23 > m3
int computeHammingCode4(uint64_t value)
uint64_t computeMask(const std::array< uint64_t, N > &masks)
int computeHammingCode(uint64_t value)
std::array< uint64_t, 23 > m1
int partialOddParity2(uint64_t value, const std::array< int, N > &pos)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::ostream & operator<<(std::ostream &stream, o2::InteractionRecord const &ir)
FIXME: do not use data model tables.