24 constexpr
static auto START_DATA = std::size_t{2 * 32};
25 auto readPointer = std::size_t{START_DATA};
27 m_packet_version = parse_version_workaround(readPointer);
28 decode_header(readPointer, m_packet_version);
29 decode_data(readPointer, m_packet_version);
30 decode_trailer(readPointer);
54 m_head_fragID, m_head_sectID, m_head_EC, m_head_flags, m_head_BCID, m_head_orbit, m_head_spare, m_L1ID));
62 m_l1a_wdw_matching_engines_usage =
74 if (m_l1a_versionID == 1)
78 else if (m_l1a_versionID == 3)
111 if (anchor == anchor_value)
121 auto PADDING_BITS_END = std::size_t{16};
126 while (readPointer < endOfData) {
129 if (readPointer + SIZE_DATA_HEADER > endOfData) {
130 throw std::length_error(
131 Muon::nsw::format(
"Read pointer ({}) would excede memory dedicated to data chunks ({}) while parsing the header (size: {})",
132 readPointer, endOfData, SIZE_DATA_HEADER));
134 const auto header_data = decode_data_header_v3(readPointer,
version);
135 if (header_data.total_expected_size > m_wordCountFlx * WORD_SIZE - readPointer + 1) {
136 throw std::length_error(
Muon::nsw::format(
"STG TP stream size {} larger than expected packet size {}",
137 header_data.total_expected_size,
138 m_wordCountFlx * WORD_SIZE - readPointer + 1));
140 if (header_data.nwords * header_data.data_size + readPointer > endOfData) {
141 throw std::length_error(
Muon::nsw::format(
"Requested to decode {} bits but only {} bits are remaining",
142 header_data.nwords * header_data.data_size, endOfData - readPointer));
144 m_stream_data.push_back(decode_data_payload_v3(readPointer, header_data,
version));
152 return decode_data_v3(readPointer,
version);
154 auto PADDING_BITS_END = std::size_t{16};
157 while (readPointer < endOfData) {
160 if (readPointer + SIZE_DATA_HEADER > endOfData) {
161 throw std::length_error(
162 Muon::nsw::format(
"Read pointer ({}) would excede memory dedicated to data chunks ({}) while parsing the header (size: {})",
163 readPointer, endOfData, SIZE_DATA_HEADER));
165 const auto header_data = decode_data_header(readPointer,
version);
167 if (header_data.total_expected_size > m_wordCountFlx - ceil(readPointer / WORD_SIZE ) + 1) {
168 throw std::length_error(
Muon::nsw::format(
"STG TP stream size {} larger than expected packet size {}",
169 header_data.total_expected_size,
170 m_wordCountFlx - ceil(readPointer / WORD_SIZE ) + 1));
172 if (header_data.nwords * header_data.data_size + readPointer > endOfData) {
173 throw std::length_error(
Muon::nsw::format(
"Requested to decode {} bits but only {} bits are remaining",
174 header_data.nwords * header_data.data_size, endOfData - readPointer));
177 m_stream_data.push_back(decode_data_payload(readPointer, header_data,
version));
183 std::size_t& readPointer,
int version) {
187 throw std::invalid_argument(
"decode_data_header_v3 version should be exactly 3");
190 size_t felix_word_size = WORD_SIZE_DOUBLE;
191 auto PADDING_BITS_END = std::size_t{16};
196 const auto total_expected_size = stream_head_nbits * stream_head_nwords;
198 size_t current_stream_head_nbits = 0;
199 size_t current_stream_head_nwords = 0;
201 switch (current_stream_head_streamID)
216 if (current_stream_head_nbits == 0 )
218 throw std::runtime_error(
"Corrupted message - sTGC stream has an unrecognized stream header");
221 if (readPointer + total_expected_size > endOfData)
223 throw std::runtime_error(
"Corrupted message - sTGC expected size goes beyond the end of data");
226 current_stream_head_nwords = (stream_head_nwords == 0) ? 0 : total_expected_size / current_stream_head_nbits;
227 size_t data_size = std::ceil(total_expected_size / felix_word_size);
232 m_stream_head_nbits.push_back(current_stream_head_nbits);
233 m_stream_head_nwords.push_back(current_stream_head_nwords);
234 m_stream_head_fifo_size.push_back(current_stream_head_fifo_size);
235 m_stream_head_streamID.push_back(current_stream_head_streamID);
239 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nbits: {}", current_stream_head_nbits));
240 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nwords: {}", current_stream_head_nwords));
241 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_fifo_size: {}", current_stream_head_fifo_size));
242 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_streamID: {}", current_stream_head_streamID));
244 ERS_DEBUG(2,
Muon::nsw::format(
"m_wordCountFlx: {}, ceil(readPointer/{}): {}", m_wordCountFlx,felix_word_size,
245 ceil(readPointer / felix_word_size)));
248 return {current_stream_head_nbits, current_stream_head_nwords, current_stream_head_fifo_size,
249 current_stream_head_streamID, total_expected_size, data_size};
253 std::size_t& readPointer,
int version) {
255 return decode_data_header_v3(readPointer,
version);
264 const auto corrected_current_stream_head_nbits = correct_size_for_padding(current_stream_head_nbits);
266 m_stream_head_nbits.push_back(corrected_current_stream_head_nbits);
267 m_stream_head_nwords.push_back(current_stream_head_nwords);
268 m_stream_head_fifo_size.push_back(current_stream_head_fifo_size);
269 m_stream_head_streamID.push_back(current_stream_head_streamID);
271 size_t word_size = WORD_SIZE_DOUBLE;
272 const auto data_size =
static_cast<std::size_t
>(std::ceil(corrected_current_stream_head_nbits / word_size));
273 const auto total_expected_size = data_size * current_stream_head_nwords;
275 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nbits: {}", corrected_current_stream_head_nbits));
276 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nwords: {}", current_stream_head_nwords));
277 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_fifo_size: {}", current_stream_head_fifo_size));
278 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_streamID: {}", current_stream_head_streamID));
279 ERS_DEBUG(2,
Muon::nsw::format(
"total_expected_size: {}", data_size * current_stream_head_nwords));
280 ERS_DEBUG(2,
Muon::nsw::format(
"m_wordCountFlx: {}, ceil(readPointer/{}): {}", m_wordCountFlx, word_size,
281 ceil(readPointer / word_size)));
283 return {corrected_current_stream_head_nbits, current_stream_head_nwords, current_stream_head_fifo_size,
284 current_stream_head_streamID, total_expected_size, data_size};
289 std::vector<std::vector<std::uint32_t>> current_stream_data{};
292 throw std::invalid_argument(
"decode_data_header_v3 version should be at least 3");
295 size_t word_size = WORD_SIZE;
296 size_t felix_n_words = (
header.nwords == 0 ) ? 0 : std::ceil(
header.data_size /
header.nwords);
297 for (std::size_t
i = 0;
i <
header.nwords; ++
i) {
298 std::vector<std::uint32_t>
data{};
299 for (std::size_t j = 0; j < felix_n_words; ++j) {
300 data.push_back(
decode(readPointer, word_size));
302 current_stream_data.push_back(
data);
304 return current_stream_data;
308 std::vector<std::vector<std::uint32_t>> current_stream_data{};
311 return decode_data_payload_v3( readPointer,
header,
version);
312 size_t word_size = WORD_SIZE;
313 for (std::size_t
i = 0;
i <
header.nwords; ++
i) {
314 std::vector<std::uint32_t>
data{};
315 for (std::size_t j = 0; j <
header.data_size; ++j) {
316 data.push_back(
decode(readPointer, word_size));
318 current_stream_data.push_back(
data);
320 return current_stream_data;
330 return Muon::nsw::decode_and_advance<std::uint64_t, std::uint32_t>(
m_data, readPointer,
size);
335 size_t word_size = WORD_SIZE_DOUBLE;
336 auto counterChunk = std::size_t{0};
337 for (
const auto& dataChunk : m_stream_data) {
338 for (
const auto& dataWord : dataChunk) {
339 const auto expectedSize =
340 static_cast<std::size_t
>(std::ceil(m_stream_head_nbits.at(counterChunk) / word_size));
341 if (
std::size(dataWord) != expectedSize) {
342 throw std::length_error(
Muon::nsw::format(
"Stream data size {} does not match expected number of messages {}",
345 switch (m_stream_head_streamID.at(counterChunk)) {
347 m_pad_packets.emplace_back(dataWord,
version);
350 m_segment_packets.emplace_back(dataWord,
version);
353 m_mm_packets.emplace_back(dataWord,
version);
356 throw std::runtime_error(
Muon::nsw::format(
"Invalid stream type {}", m_stream_head_streamID.at(counterChunk)));
366 return analyze_data_v3(
version);
369 size_t word_size = WORD_SIZE_DOUBLE;
370 auto counterChunk = std::size_t{0};
371 for (
const auto& dataChunk : m_stream_data) {
372 for (
const auto& dataWord : dataChunk) {
373 const auto expectedSize =
374 static_cast<std::size_t
>(std::ceil(m_stream_head_nbits.at(counterChunk) / word_size));
375 if (
std::size(dataWord) != expectedSize) {
376 throw std::length_error(
Muon::nsw::format(
"Stream data size {} does not match expected number of messages {}",
379 switch (m_stream_head_streamID.at(counterChunk)) {
381 m_pad_packets.emplace_back(dataWord,
version);
384 m_segment_packets.emplace_back(dataWord,
version);
387 throw std::runtime_error(
Muon::nsw::format(
"Invalid stream type {}", m_stream_head_streamID.at(counterChunk)));
395 static constexpr
auto PADDING = 16;
396 if (initial % PADDING) {
397 return ((initial + PADDING - 1) / PADDING) * PADDING;