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 <stdexcept>
12
13
14namespace Spadic
15{
16
17 template<std::uint8_t sys_ver>
18 constexpr std::uint8_t BytesPerWord()
19 {
20 switch (sys_ver) {
21 case 0x01: return 8;
22 case 0x10: return 8;
23 default: return 0;
24 }
25 }
26
27 template<size_t bytes>
29 std::uint8_t b[bytes];
30
31 operator std::uint64_t()
32 {
33 std::uint64_t r;
34 memcpy(&r, b, sizeof(long));
35 return r;
36 }
37
38 size_t range(std::uint8_t h, std::uint8_t l)
39 {
40
41 if (l > h) {
42 throw std::invalid_argument(fmt::format("Reverse ranges not supported : low={:#x} > high={:#x}", l, h));
43 }
44 // get high and low byte positions
45 std::uint16_t bh = h >> 3;
46 std::uint16_t bl = l >> 3;
47 // get number of bytes that need to be accessed
48 std::uint16_t rbytes = bh - bl;
49 if ((bh + 1) > bytes) {
50 throw std::invalid_argument(fmt::format("High value: out-of-range, got={:#x}, size={:#x}", h, (bytes * 8 - 1)));
51 }
52 if ((bl + 1) > bytes) {
53 throw std::invalid_argument(fmt::format("Low value: out-of-range, got={:#x}, size={:#x}", l, (bytes * 8 - 1)));
54 }
55 // calculate bit positions for high and low byte
56 std::uint16_t bits_in_h = h - (8 * bh - 1);
57 std::uint16_t bits_in_l = l - (8 * bl);
58 std::uint16_t mask_h = (1 << bits_in_h) - 1;
59
60 // assemble return value
61 size_t r = b[bl] >> bits_in_l;
62 if (bh != bl) r |= (b[bh] & mask_h) << (rbytes * 8);
63 for (int i = 1; i < rbytes; ++i)
64 r |= b[bl + i] << (i * 8);
65 return r;
66 }
67 };
68
69 // Define template specialisations for each system version
70 template<std::uint8_t sys_ver>
71 struct FexWord {
72 };
73
74
75 // sys_ver 0x10 (c.f.git.cbm.gsi.de/trd/reports/technical-notes/integrated-data-format)
76 template<>
77 struct FexWord<0x10> {
78 std::uint8_t elink;
79 std::uint8_t channel;
80 std::uint64_t timestamp;
81 float prec_time;
82 std::uint16_t maxAdc;
83 std::uint16_t timesample;
84 std::uint8_t iMA;
85 std::uint8_t ht;
86 std::uint8_t mh;
87
89 {
90 constexpr int hts = 62;
91 constexpr int els = hts - 8;
92 constexpr int chs = els - 4;
93 constexpr int maxs = chs - 9;
94 constexpr int imas = maxs - 3;
95 constexpr int trs = imas - 9;
96 constexpr int mhs = trs - 3;
97 constexpr int pts = mhs - 5;
98
99 std::uint64_t w = word;
100
101 ht = (word >> 62) & 0x3; // TODO ext trigger
102 if (ht != 0) {
103 elink = (w >> els) & 0xff;
104 channel = (w >> chs) & 0xf;
105 maxAdc = (w >> maxs) & 0x1ff;
106 iMA = (w >> imas) & 0x3;
107 timesample = (w >> trs) & 0x1ff;
108 mh = (w >> mhs) & 0x3;
109 prec_time = (float) ((w >> pts) & 0x1f) / float(1 << 4);
110 timestamp = w & 0x1fffff;
111 }
112 }
113 };
114
115} // namespace Spadic
116
117#endif // CbmTrdFexMessageSpadic_H
Data class with information on a STS local track.
constexpr std::uint8_t BytesPerWord()
FexWord(NByteContainer< BytesPerWord< 0x10 >()> word)
size_t range(std::uint8_t h, std::uint8_t l)