CbmRoot
Loading...
Searching...
No Matches
CbmTrdFexMessageSpadic.h
Go to the documentation of this file.
1/* Copyright (C) 2024 Goethe-University Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: David Schledt [committer] */
4
5#ifndef CbmTrdFexMessageSpadic_H
6#define CbmTrdFexMessageSpadic_H
7
8#include "fmt/format.h"
9
10#include <array>
11#include <cstdint>
12#include <stdexcept>
13
14
15namespace Spadic
16{
17
18 template<uint8_t sys_ver>
19 constexpr uint8_t BytesPerWord()
20 {
21 switch (sys_ver) {
22 case 0x01: return 8;
23 case 0x10: return 8;
24 default: return 0;
25 }
26 }
27
28 template<size_t bytes>
30 uint8_t b[bytes];
31
32 operator uint64_t()
33 {
34 uint64_t r;
35 memcpy(&r, b, sizeof(long));
36 return r;
37 }
38
39 size_t range(uint8_t h, uint8_t l)
40 {
41
42 if (l > h) {
43 throw std::invalid_argument(fmt::format("Reverse ranges not supported : low={:#x} > high={:#x}", l, h));
44 }
45 // get high and low byte positions
46 uint16_t bh = h >> 3;
47 uint16_t bl = l >> 3;
48 // get number of bytes that need to be accessed
49 uint16_t rbytes = bh - bl;
50 if ((bh + 1) > bytes) {
51 throw std::invalid_argument(fmt::format("High value: out-of-range, got={:#x}, size={:#x}", h, (bytes * 8 - 1)));
52 }
53 if ((bl + 1) > bytes) {
54 throw std::invalid_argument(fmt::format("Low value: out-of-range, got={:#x}, size={:#x}", l, (bytes * 8 - 1)));
55 }
56 // calculate bit positions for high and low byte
57 uint16_t bits_in_h = h - (8 * bh - 1);
58 uint16_t bits_in_l = l - (8 * bl);
59 uint16_t mask_h = (1 << bits_in_h) - 1;
60
61 // assemble return value
62 size_t r = b[bl] >> bits_in_l;
63 if (bh != bl) r |= (b[bh] & mask_h) << (rbytes * 8);
64 for (int i = 1; i < rbytes; ++i)
65 r |= b[bl + i] << (i * 8);
66 return r;
67 }
68 };
69
70 // Define template specialisations for each system version
71 template<uint8_t sys_ver>
72 struct FexWord {
73 };
74
75
76 // sys_ver 0x10 (c.f.git.cbm.gsi.de/trd/reports/technical-notes/integrated-data-format)
77 template<>
78 struct FexWord<0x10> {
79 static constexpr int hts = 62;
80 static constexpr int els = hts - 8;
81 static constexpr int chs = els - 4;
82 static constexpr int maxs = chs - 9;
83 static constexpr int imas = maxs - 3;
84 static constexpr int trs = imas - 9;
85 static constexpr int mhs = trs - 3;
86 static constexpr int pts = mhs - 5;
87
88 static constexpr int m_el = 0xff;
89 static constexpr int m_ch = 0xf;
90 static constexpr int m_ts = 0x1fffff;
91 static constexpr int m_pt = 0x1f;
92 static constexpr int m_mA = 0x1ff;
93 static constexpr int m_tsample = 0x1ff;
94 static constexpr int m_iMA = 0x7;
95 static constexpr int m_ht = 0x3;
96 static constexpr int m_mh = 0x7;
97
98 uint8_t elink;
99 uint8_t channel;
100 uint64_t timestamp;
102 uint16_t maxAdc;
103 uint16_t timesample;
104 uint8_t iMA;
105 uint8_t ht;
106 uint8_t mh;
107
109 {
110
111 uint64_t w = word;
112
113 ht = (word >> 62) & 0x3; // TODO ext trigger
114 if (ht != 0) {
115 elink = (w >> els) & m_el;
116 channel = (w >> chs) & m_ch;
117 maxAdc = (w >> maxs) & m_mA;
118 iMA = (w >> imas) & m_iMA;
119 timesample = (w >> trs) & m_tsample;
120 mh = (w >> mhs) & m_mh;
121 prec_time = (float) ((w >> pts) & m_pt) / float(1 << 4);
122 timestamp = w & m_ts;
123 }
124 }
125
126 FexWord(uint8_t elink_v, uint8_t channel_v, uint64_t timestamp_v, uint8_t prec_time_v, uint16_t maxAdc_v,
127 uint16_t timesample_v, uint8_t iMA_v, uint8_t ht_v, uint8_t mh_v)
128 : elink(elink_v & m_el)
129 , channel(channel_v & m_ch)
130 , timestamp(timestamp_v & m_ts)
131 , prec_time((float) (prec_time_v & m_pt) / float(1 << 4))
132 , maxAdc(maxAdc_v & m_mA)
133 , timesample(timesample_v & m_tsample)
134 , iMA(iMA_v & m_iMA)
135 , ht(ht_v & m_ht)
136 , mh(mh_v & m_mh)
137 {
138 }
139
140 operator uint64_t()
141 {
142 uint8_t prec_time_fixed_point = prec_time * (1 << 4);
143 uint64_t fw = 0 | (uint64_t) ht << 62 | (uint64_t) elink << els | (uint64_t) channel << chs
144 | (uint64_t) maxAdc << maxs | (uint64_t) iMA << imas | (uint64_t) timesample << trs
145 | (uint64_t) mh << mhs | (uint64_t) prec_time_fixed_point << pts | timestamp;
146 return fw;
147 }
148
150 {
151
153 uint64_t fw = *this;
154 memcpy(&nbc.b, &fw, sizeof(long));
155 return nbc;
156 }
157 };
158
159} // namespace Spadic
160
161#endif // CbmTrdFexMessageSpadic_H
Data class with information on a STS local track.
constexpr uint8_t BytesPerWord()
FexWord(NByteContainer< BytesPerWord< 0x10 >()> word)
FexWord(uint8_t elink_v, uint8_t channel_v, uint64_t timestamp_v, uint8_t prec_time_v, uint16_t maxAdc_v, uint16_t timesample_v, uint8_t iMA_v, uint8_t ht_v, uint8_t mh_v)
static constexpr int m_tsample
size_t range(uint8_t h, uint8_t l)