DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DAPHNEFrame.hpp
Go to the documentation of this file.
1
13
14#ifndef FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_DAPHNEFRAME_HPP_
15#define FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_DAPHNEFRAME_HPP_
16
17#include "Utils.hpp"
18
20#include <algorithm> // For std::min
21#include <cassert> // For assert()
22#include <cstdint> // For uint32_t etc
23#include <cstdio>
24#include <cstdlib>
25#include <stdexcept> // For std::out_of_range
26
28
29// NOLINTBEGIN(build/unsigned)
30
32{
33public:
34 // The definition of the format is in terms of 32-bit words
35 using word_t = uint32_t;
36
37 // Dataframe format version
38 static constexpr uint8_t version = 2;
39
40 static constexpr int s_bits_per_adc = 14;
41 static constexpr int s_bits_per_word = 8 * sizeof(word_t);
42 static constexpr int s_num_adcs = 1024;
44
45 struct Header
46 {
50 };
51 static_assert(sizeof(Header) == 8);
52
54 {
55
56 // Word 1: peak 0 odd
57 // Declared in reverse order (LSB first) so that:
58 // - num_subpeaks_0 occupies bits [3:0]
59 // - reserved_0 occupies bits [7:4]
60 // - adc_integral_0 occupies bits [30:8]
61 // - found_0 occupies bit [31]
62 word_t num_subpeaks_0 : 4; // Num_SubPeaks [3:0]
63 word_t reserved_0 : 4; // Reserved [7:4]
64 word_t adc_integral_0 : 23; // ADC_Integral [30:8]
65 word_t found_0 : 1; // Found [31]
66
67 // Word 2: peak 0 even
68 // Declared (LSB first) so that:
69 // - adc_max_0 occupies bits [13:0]
70 // - sample_max_0 occupies bits [22:14]
71 // - samples_over_baseline_0 occupies bits [31:23]
72 word_t adc_max_0 : 14; // ADC Max [13:0]
73 word_t sample_max_0 : 9; // Time_Peak [22:14]
74 word_t samples_over_baseline_0 : 9; // Time_Over_Baseline [31:23]
75
76 // Word 3: peak 1 odd
77 word_t num_subpeaks_1 : 4; // Num_SubPeaks [3:0]
78 word_t reserved_1 : 4; // Reserved [7:4]
79 word_t adc_integral_1 : 23; // ADC_Integral [30:8]
80 word_t found_1 : 1; // Found [31]
81
82 // Word 4: peak 1 even
83 word_t adc_max_1 : 14; // ADC Max [13:0]
84 word_t sample_max_1 : 9; // Time_Peak [22:14]
85 word_t samples_over_baseline_1 : 9; // Time_Over_Baseline [31:23]
86
87 // Word 5: peak 2 odd
88 word_t num_subpeaks_2 : 4; // Num_SubPeaks [3:0]
89 word_t reserved_2 : 4; // Reserved [7:4]
90 word_t adc_integral_2 : 23; // ADC_Integral [30:8]
91 word_t found_2 : 1; // Found [31]
92
93 // Word 6: peak 2 even
94 word_t adc_max_2 : 14; // ADC Max [13:0]
95 word_t sample_max_2 : 9; // Time_Peak [22:14]
96 word_t samples_over_baseline_2 : 9; // Time_Over_Baseline [31:23]
97
98 // Word 7: peak 3 odd
99 word_t num_subpeaks_3 : 4; // Num_SubPeaks [3:0]
100 word_t reserved_3 : 4; // Reserved [7:4]
101 word_t adc_integral_3 : 23; // ADC_Integral [30:8]
102 word_t found_3 : 1; // Found [31]
103
104 // Word 8: peak 3 even
105 word_t adc_max_3 : 14; // ADC Max [13:0]
106 word_t sample_max_3 : 9; // Time_Peak [22:14]
107 word_t samples_over_baseline_3 : 9; // Time_Over_Baseline [31:23]
108
109 // Word 9: peak 4 odd
110 word_t num_subpeaks_4 : 4; // Num_SubPeaks [3:0]
111 word_t reserved_4 : 4; // Reserved [7:4]
112 word_t adc_integral_4 : 23; // ADC_Integral [30:8]
113 word_t found_4 : 1; // Found [31]
114
115 // Word 10: peak 4 even
116 word_t adc_max_4 : 14; // ADC Max [13:0]
117 word_t sample_max_4 : 9; // Time_Peak [22:14]
118 word_t samples_over_baseline_4 : 9; // Time_Over_Baseline [31:23]
119
120 // Word 11: Time_Start fields for indices 0,1,2 and Reserved
121 // Declared in LSB-first order:
122 // - samples_start_2 occupies bits [11:2]
123 // - samples_start_1 occupies bits [21:12]
124 // - samples_start_0 occupies bits [31:22]
125 // - reserved_5 occupies bits [1:0]
126 word_t samples_start_2 : 10; // Time_Start(2) [11:2]
127 word_t samples_start_1 : 10; // Time_Start(1) [21:12]
128 word_t samples_start_0 : 10; // Time_Start(0) [31:22]
129 word_t reserved_5 : 2; // Reserved [1:0]
130
131 // Word 12: Time_Start fields for indices 3,4 and Reserved
132 // Declared in LSB-first order:
133 // - reserved_6 occupies bits [11:0]
134 // - samples_start_4 occupies bits [21:12]
135 // - samples_start_3 occupies bits [31:22]
136 word_t reserved_6 : 12; // Reserved [11:0]
137 word_t samples_start_4 : 10; // Time_Start(4) [21:12]
138 word_t samples_start_3 : 10; // Time_Start(3) [31:22]
139
140 // Word 13: Trailer word (all 32 bits), typically 0xFFFFFFFF.
142
143 static const uint8_t max_peaks = 5;
144
149 bool is_found(int idx) const;
150
152 void set_found(uint8_t val, int idx);
153
158 uint32_t get_adc_integral(int idx) const;
159
161 void set_adc_integral(uint32_t val, int idx);
162
167 uint8_t get_num_subpeaks(int idx) const;
168
170 void set_num_subpeaks(uint8_t val, int idx);
171
176 uint16_t get_samples_over_baseline(int idx) const;
177
178 // @brief Set the Time_Over_Baseline value for a specific peak.
179 void set_samples_over_baseline(uint16_t val, int idx);
180
185 uint16_t get_sample_max(int idx) const;
186
188 void set_sample_max(uint16_t val, int idx);
189
194 uint16_t get_adc_max(int idx) const;
195
197 void set_adc_max(uint16_t val, int idx);
198
211
212 uint16_t get_sample_start(int idx) const;
213
225 void set_sample_start(uint16_t val, int idx);
226
227 // ===============================================================
228 // Helper: Reinterpret Trailer as an array of word_t
229 // ===============================================================
230 const word_t* as_words() const
231 {
232 return reinterpret_cast<const word_t*>(this); // NOLINT
233 }
235 {
236 return reinterpret_cast<word_t*>(this); // NOLINT
237 }
238 };
239 static_assert(sizeof(PeakDescriptorData) == 13 * sizeof(uint32_t));
240
245
253 uint16_t get_adc(int i) const;
254
256 void set_adc(int i, uint16_t val);
257
258 uint8_t get_channel() const { return header.channel; }
259 void set_channel(uint8_t val) { header.channel = val & 0x3Fu; }
260
262 uint64_t get_timestamp() const { return daq_header.get_timestamp(); }
263};
264static_assert(sizeof(DAPHNEFrame) == sizeof(detdataformats::DAQHeader) + sizeof(DAPHNEFrame::Header) +
266 sizeof(DAPHNEFrame::PeakDescriptorData));
267
268static_assert(std::endian::native == std::endian::little,
269 "The DAPHNEFrame bitfield layout assumes little-endian architecture");
270static_assert(std::is_trivially_copyable_v<DAPHNEFrame>,
271 "DAPHNEFrame isn't trivially copyable and can't be safely std::memcpy'd");
272static_assert(std::is_standard_layout_v<DAPHNEFrame>,
273 "DAPHNEFrame isn't standard layout; reinterpret_cast and offsetof can't safely be used with it");
274
275} // namespace dunedaq::fddetdataformats
276
277#include "detail/DAPHNEFrame.hxx"
278
279// NOLINTEND(build/unsigned)
280
281#endif // FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_DAPHNEFRAME_HPP_
detdataformats::DAQHeader daq_header
void set_adc(int i, uint16_t val)
Set the ith ADC value in the frame to val.
uint64_t get_timestamp() const
Get the 64-bit timestamp of the frame.
uint16_t get_adc(int i) const
Get the ith ADC value in the frame.
DAQHeader is a versioned and unified structure for every FE electronics.
Definition DAQHeader.hpp:23
bool is_found(int idx) const
Get the Found value for a specific peak (channel) from the trailer. (Word 2*idx, bit 31).
void set_adc_integral(uint32_t val, int idx)
Set the ADC_Integral value for a specific peak.
uint16_t get_adc_max(int idx) const
Get the ADC Max value for a specific peak. (Word 2*idx+1, bits [31:18]).
void set_num_subpeaks(uint8_t val, int idx)
Set the Num_SubPeaks value for a specific peak.
uint16_t get_sample_start(int idx) const
Get the Time_Start value for a given index (0-4).
uint16_t get_sample_max(int idx) const
Get the Time_Peak value for a specific peak. (Word 2*idx+1, bits [17:9]).
void set_sample_max(uint16_t val, int idx)
Set the Time_Peak value for a specific peak.
void set_found(uint8_t val, int idx)
Set the Found value for a specific peak (channel) in the trailer.
uint32_t get_adc_integral(int idx) const
Get the ADC_Integral value for a specific peak. (Word 2*idx, bits [30:8]).
void set_sample_start(uint16_t val, int idx)
Set the time_start field for Peak index 0–4 using bit shifts.
void set_adc_max(uint16_t val, int idx)
Set the ADC Max value for a specific peak.
uint8_t get_num_subpeaks(int idx) const
Get the Num_SubPeaks value for a specific peak. (Word 2*idx, bits [3:0]).
uint16_t get_samples_over_baseline(int idx) const
Get the Time_Over_Baseline value for a specific peak. (Word 2*idx+1, bits [8:0]).