DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
Fragment.hpp
Go to the documentation of this file.
1
14
15#ifndef DAQDATAFORMATS_INCLUDE_DAQDATAFORMATS_FRAGMENT_HPP_
16#define DAQDATAFORMATS_INCLUDE_DAQDATAFORMATS_FRAGMENT_HPP_
17
21
22#include <bitset>
23#include <cstdint>
24#include <cstdlib>
25#include <cstring>
26#include <new>
27#include <numeric>
28#include <stdexcept>
29#include <utility>
30#include <vector>
31
33
38{
39public:
46
51 explicit Fragment(const std::vector<std::pair<void*, size_t>>& pieces);
57 Fragment(void* buffer, size_t size);
63 explicit Fragment(void* existing_fragment_buffer, BufferAdoptionMode adoption_mode);
64
65 FragmentHeader get_header() const { return *header_(); }
66
68 void set_header_fields(const FragmentHeader& header);
69
71 const void* get_storage_location() const { return m_data_arr; }
72
74 void set_trigger_number(trigger_number_t trigger_number) { header_()->trigger_number = trigger_number; }
75
77 void set_run_number(run_number_t run_number) { header_()->run_number = run_number; }
78
80 void set_trigger_timestamp(timestamp_t trigger_timestamp) { header_()->trigger_timestamp = trigger_timestamp; }
81
83 void set_window_begin(timestamp_t window_begin) { header_()->window_begin = window_begin; }
84
86 void set_window_end(timestamp_t window_end) { header_()->window_end = window_end; }
87
93
98 void set_element_id(SourceID element_id) { header_()->element_id = element_id; }
99
100 uint16_t get_detector_id() const noexcept { return header_()->detector_id; } // NOLINT
101 void set_detector_id(const uint16_t& detector_id) noexcept { header_()->detector_id = detector_id; } // NOLINT
102
107 std::bitset<32> get_status_bits() const { return header_()->status_bits; }
112 void set_status_bits(std::bitset<32> status_bits) { header_()->status_bits = status_bits.to_ulong(); }
118 bool get_status_bit(FragmentStatusBits bit) const { return get_status_bits()[static_cast<size_t>(bit)]; }
119
125 void set_status_bit(FragmentStatusBits bit, bool value);
126
141 void set_type(FragmentType fragment_type) { header_()->fragment_type = static_cast<fragment_type_t>(fragment_type); }
142
145
147 fragment_size_t get_size() const { return header_()->size; }
148
150 fragment_size_t get_data_size() const { return header_()->size - sizeof(FragmentHeader); }
151
153 void* get_data() const
154 {
155 // Increment header pointer by one to skip header
156 return static_cast<void*>(header_() + 1); // NOLINT
157 }
158
159 Fragment(Fragment const&) = delete;
160 Fragment& operator=(Fragment const&) = delete;
162 {
163 m_alloc = other.m_alloc;
164 other.m_alloc = false;
165 m_data_arr = other.m_data_arr;
166 }
168 {
169 m_alloc = other.m_alloc;
170 other.m_alloc = false;
171 m_data_arr = other.m_data_arr;
172 return *this;
173 }
174
175 ~Fragment();
176
177private:
178 FragmentHeader* header_() const { return static_cast<FragmentHeader*>(m_data_arr); }
179 void* m_data_arr{ nullptr };
180 bool m_alloc{ false };
181};
182
183inline Fragment::Fragment(const std::vector<std::pair<void*, size_t>>& pieces)
184{
185
186 size_t size =
187 sizeof(FragmentHeader) +
188 std::accumulate(pieces.begin(), pieces.end(), 0ULL, [](const size_t& a, const std::pair<void*, size_t>& b) {
189 return a + b.second;
190 });
191
192 m_data_arr = malloc(size); // NOLINT
193 if (m_data_arr == nullptr) {
194 throw std::bad_alloc();
195 }
196 m_alloc = true;
197
198 FragmentHeader header;
199 header.size = size;
200 memcpy(m_data_arr, &header, sizeof(header));
201
202 size_t offset = sizeof(header);
203 for (auto& piece : pieces) {
204 if (piece.first == nullptr) {
205 free(m_data_arr); // NOLINT
206 throw std::invalid_argument("The Fragment buffer points to NULL.");
207 }
208 memcpy(static_cast<uint8_t*>(m_data_arr) + offset, piece.first, piece.second); // NOLINT
209 offset += piece.second;
210 }
211}
212
213inline Fragment::Fragment(void* buffer, size_t size)
214 : Fragment({ std::make_pair(buffer, size) })
215{
216}
217
218inline Fragment::Fragment(void* existing_fragment_buffer, BufferAdoptionMode adoption_mode)
219{
220 if (adoption_mode == BufferAdoptionMode::kTakeOverBuffer) {
221 m_data_arr = existing_fragment_buffer;
222 m_alloc = true;
223 } else if (adoption_mode == BufferAdoptionMode::kCopyFromBuffer) {
224 auto header = reinterpret_cast<FragmentHeader*>(existing_fragment_buffer); // NOLINT
225 m_data_arr = malloc(header->size); // NOLINT
226 if (m_data_arr == nullptr) {
227 throw std::bad_alloc();
228 }
229 m_alloc = true;
230 memcpy(m_data_arr, existing_fragment_buffer, header->size);
231 }
232}
233
235{
236 if (m_alloc)
237 free(m_data_arr); // NOLINT
238}
239
240inline void
242{
243 FragmentHeader* header_ptr{ header_() };
244 fragment_size_t orig_size{ header_ptr->size };
245
246 *header_ptr = header;
247 header_ptr->size = orig_size;
248}
249
250inline void
252
253{
254 auto bits = get_status_bits();
255 bits[static_cast<size_t>(bit)] = value;
256 set_status_bits(bits);
257}
258
259} // namespace dunedaq::daqdataformats
260
261#endif // DAQDATAFORMATS_INCLUDE_DAQDATAFORMATS_FRAGMENT_HPP_
timestamp_t get_trigger_timestamp() const
Definition Fragment.hpp:79
bool get_status_bit(FragmentStatusBits bit) const
Get the value of a designated status bit.
Definition Fragment.hpp:118
sequence_number_t get_sequence_number() const
Definition Fragment.hpp:143
void set_status_bit(FragmentStatusBits bit, bool value)
Set the designated status bit.
Definition Fragment.hpp:251
void set_run_number(run_number_t run_number)
Definition Fragment.hpp:77
fragment_type_t get_fragment_type_code() const
Get the fragment_type_t value stored in the header.
Definition Fragment.hpp:131
void set_status_bits(std::bitset< 32 > status_bits)
Overwrite the status_bits header field.
Definition Fragment.hpp:112
timestamp_t get_window_begin() const
Definition Fragment.hpp:82
timestamp_t get_window_end() const
Definition Fragment.hpp:85
void set_window_begin(timestamp_t window_begin)
Definition Fragment.hpp:83
run_number_t get_run_number() const
Definition Fragment.hpp:76
BufferAdoptionMode
Describes how the "existing Fragment buffer" constructor should treat the given buffer.
Definition Fragment.hpp:42
@ kCopyFromBuffer
Copy the contents of the buffer into a new Fragment array.
Definition Fragment.hpp:44
@ kTakeOverBuffer
Take over control of the buffer.
Definition Fragment.hpp:43
SourceID get_element_id() const
Get the SourceID for the Fragment.
Definition Fragment.hpp:92
FragmentType get_fragment_type() const
Get the fragment_type header field.
Definition Fragment.hpp:136
void set_header_fields(const FragmentHeader &header)
Fields from the provided header overwrite this Fragment's header, except for the size field.
Definition Fragment.hpp:241
Fragment & operator=(Fragment const &)=delete
void set_trigger_timestamp(timestamp_t trigger_timestamp)
Definition Fragment.hpp:80
void set_sequence_number(sequence_number_t number)
Definition Fragment.hpp:144
void set_window_end(timestamp_t window_end)
Definition Fragment.hpp:86
Fragment(Fragment const &)=delete
FragmentHeader * header_() const
Definition Fragment.hpp:178
void set_trigger_number(trigger_number_t trigger_number)
Definition Fragment.hpp:74
FragmentHeader get_header() const
Definition Fragment.hpp:65
uint16_t get_detector_id() const noexcept
Definition Fragment.hpp:100
void set_element_id(SourceID element_id)
Set the SourceID for the Fragment.
Definition Fragment.hpp:98
void * get_data() const
Get a pointer to the data payload in the Fragmnet.
Definition Fragment.hpp:153
Fragment(const std::vector< std::pair< void *, size_t > > &pieces)
Fragment constructor using a vector of buffer pointers.
Definition Fragment.hpp:183
Fragment & operator=(Fragment &&other)
Definition Fragment.hpp:167
fragment_size_t get_data_size() const
Get the size of the Fragment payload in bytes (total size minus FragmentHeader).
Definition Fragment.hpp:150
bool m_alloc
Whether the Fragment owns the memory pointed by m_data_arr.
Definition Fragment.hpp:180
std::bitset< 32 > get_status_bits() const
Get the status_bits header field.
Definition Fragment.hpp:107
fragment_size_t get_size() const
Get the total size of the Fragment in bytes, including header and all payload pieces.
Definition Fragment.hpp:147
void set_type(FragmentType fragment_type)
Set the fragment_type header field.
Definition Fragment.hpp:141
const void * get_storage_location() const
Get read-only access to the Fragment's underlying data array via a pointer.
Definition Fragment.hpp:71
trigger_number_t get_trigger_number() const
Definition Fragment.hpp:73
void set_detector_id(const uint16_t &detector_id) noexcept
Definition Fragment.hpp:101
void * m_data_arr
Points to flat memory containing a FragmentHeader and the data payload.
Definition Fragment.hpp:179
double offset
FragmentType
All defined Fragment types.
uint64_t trigger_number_t
Definition Types.hpp:18
uint16_t sequence_number_t
Type used to represent sequence within a trigger record.
Definition Types.hpp:38
uint64_t timestamp_t
Type used to represent DUNE timing system timestamps.
Definition Types.hpp:26
uint32_t fragment_type_t
Type used to represent Fragment type ID.
Definition Types.hpp:21
uint64_t fragment_size_t
Definition Types.hpp:23
FragmentStatusBits
All defined status bits, with a short documentation of their meaning if non-obvious.
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
The header for a DUNE Fragment.
timestamp_t trigger_timestamp
Timestamp of the TriggerDecision.
fragment_type_t fragment_type
Type of the Fragment, indicating the format of the contained payload.
SourceID element_id
Component that generated the data in this Fragment.
uint16_t detector_id
Identifier for the subdetector that produced the raw data in the Fragment payload.
sequence_number_t sequence_number
Sequence number of this Fragment within a trigger record.
uint32_t status_bits
Status bits set by the Upstream DAQ.
trigger_number_t trigger_number
Trigger Number this Fragment is associated with.
timestamp_t window_end
Window end of data in the Fragment.
timestamp_t window_begin
Window begin of data in the Fragment.
fragment_size_t size
Size of the Fragment (including header and payload).
SourceID is a generalized representation of the source of a piece of data in the DAQ....
Definition SourceID.hpp:32