21 constexpr
static auto START_DATA = std::size_t{2 * 32};
22 auto readPointer = std::size_t{START_DATA};
24 m_packet_version = parse_version_workaround(readPointer);
25 decode_header(readPointer, m_packet_version);
26 decode_data(readPointer, m_packet_version);
27 decode_trailer(readPointer);
51 m_head_fragID, m_head_sectID, m_head_EC, m_head_flags, m_head_BCID, m_head_orbit, m_head_spare, m_L1ID));
59 m_l1a_wdw_matching_engines_usage =
71 if (m_l1a_versionID == 1)
75 else if (m_l1a_versionID == 3)
108 if (anchor == anchor_value)
118 auto PADDING_BITS_END = std::size_t{16};
123 while (readPointer < endOfData) {
126 if (readPointer + SIZE_DATA_HEADER > endOfData) {
127 throw std::length_error(
128 Muon::nsw::format(
"Read pointer ({}) would excede memory dedicated to data chunks ({}) while parsing the header (size: {})",
129 readPointer, endOfData, SIZE_DATA_HEADER));
131 const auto header_data = decode_data_header_v3(readPointer,
version);
132 if (header_data.total_expected_size > m_wordCountFlx * WORD_SIZE - readPointer + 1) {
133 throw std::length_error(
Muon::nsw::format(
"STG TP stream size {} larger than expected packet size {}",
134 header_data.total_expected_size,
135 m_wordCountFlx * WORD_SIZE - readPointer + 1));
137 if (header_data.nwords * header_data.data_size + readPointer > endOfData) {
138 throw std::length_error(
Muon::nsw::format(
"Requested to decode {} bits but only {} bits are remaining",
139 header_data.nwords * header_data.data_size, endOfData - readPointer));
141 m_stream_data.push_back(decode_data_payload_v3(readPointer, header_data,
version));
149 return decode_data_v3(readPointer,
version);
151 auto PADDING_BITS_END = std::size_t{16};
154 while (readPointer < endOfData) {
157 if (readPointer + SIZE_DATA_HEADER > endOfData) {
158 throw std::length_error(
159 Muon::nsw::format(
"Read pointer ({}) would excede memory dedicated to data chunks ({}) while parsing the header (size: {})",
160 readPointer, endOfData, SIZE_DATA_HEADER));
162 const auto header_data = decode_data_header(readPointer,
version);
164 if (header_data.total_expected_size > m_wordCountFlx - ceil(readPointer / WORD_SIZE ) + 1) {
165 throw std::length_error(
Muon::nsw::format(
"STG TP stream size {} larger than expected packet size {}",
166 header_data.total_expected_size,
167 m_wordCountFlx - ceil(readPointer / WORD_SIZE ) + 1));
169 if (header_data.nwords * header_data.data_size + readPointer > endOfData) {
170 throw std::length_error(
Muon::nsw::format(
"Requested to decode {} bits but only {} bits are remaining",
171 header_data.nwords * header_data.data_size, endOfData - readPointer));
174 m_stream_data.push_back(decode_data_payload(readPointer, header_data,
version));
180 std::size_t& readPointer,
int version) {
184 throw std::invalid_argument(
"decode_data_header_v3 version should be exactly 3");
187 size_t felix_word_size = WORD_SIZE_DOUBLE;
188 auto PADDING_BITS_END = std::size_t{16};
193 const auto total_expected_size = stream_head_nbits * stream_head_nwords;
195 size_t current_stream_head_nbits = 0;
196 size_t current_stream_head_nwords = 0;
198 switch (current_stream_head_streamID)
213 if (current_stream_head_nbits == 0 )
215 throw std::runtime_error(
"Corrupted message - sTGC stream has an unrecognized stream header");
218 if (readPointer + total_expected_size > endOfData)
220 throw std::runtime_error(
"Corrupted message - sTGC expected size goes beyond the end of data");
223 current_stream_head_nwords = (stream_head_nwords == 0) ? 0 : total_expected_size / current_stream_head_nbits;
224 size_t data_size = std::ceil(total_expected_size / felix_word_size);
229 m_stream_head_nbits.push_back(current_stream_head_nbits);
230 m_stream_head_nwords.push_back(current_stream_head_nwords);
231 m_stream_head_fifo_size.push_back(current_stream_head_fifo_size);
232 m_stream_head_streamID.push_back(current_stream_head_streamID);
236 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nbits: {}", current_stream_head_nbits));
237 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nwords: {}", current_stream_head_nwords));
238 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_fifo_size: {}", current_stream_head_fifo_size));
239 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_streamID: {}", current_stream_head_streamID));
241 ERS_DEBUG(2,
Muon::nsw::format(
"m_wordCountFlx: {}, ceil(readPointer/{}): {}", m_wordCountFlx,felix_word_size,
242 ceil(readPointer / felix_word_size)));
245 return {current_stream_head_nbits, current_stream_head_nwords, current_stream_head_fifo_size,
246 current_stream_head_streamID, total_expected_size, data_size};
250 std::size_t& readPointer,
int version) {
252 return decode_data_header_v3(readPointer,
version);
261 const auto corrected_current_stream_head_nbits = correct_size_for_padding(current_stream_head_nbits);
263 m_stream_head_nbits.push_back(corrected_current_stream_head_nbits);
264 m_stream_head_nwords.push_back(current_stream_head_nwords);
265 m_stream_head_fifo_size.push_back(current_stream_head_fifo_size);
266 m_stream_head_streamID.push_back(current_stream_head_streamID);
268 size_t word_size = WORD_SIZE_DOUBLE;
269 const auto data_size =
static_cast<std::size_t
>(std::ceil(corrected_current_stream_head_nbits / word_size));
270 const auto total_expected_size = data_size * current_stream_head_nwords;
272 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nbits: {}", corrected_current_stream_head_nbits));
273 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_nwords: {}", current_stream_head_nwords));
274 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_fifo_size: {}", current_stream_head_fifo_size));
275 ERS_DEBUG(2,
Muon::nsw::format(
"stream_head_streamID: {}", current_stream_head_streamID));
276 ERS_DEBUG(2,
Muon::nsw::format(
"total_expected_size: {}", data_size * current_stream_head_nwords));
277 ERS_DEBUG(2,
Muon::nsw::format(
"m_wordCountFlx: {}, ceil(readPointer/{}): {}", m_wordCountFlx, word_size,
278 ceil(readPointer / word_size)));
280 return {corrected_current_stream_head_nbits, current_stream_head_nwords, current_stream_head_fifo_size,
281 current_stream_head_streamID, total_expected_size, data_size};
286 std::vector<std::vector<std::uint32_t>> current_stream_data{};
289 throw std::invalid_argument(
"decode_data_header_v3 version should be at least 3");
292 size_t word_size = WORD_SIZE;
293 size_t felix_n_words = (
header.nwords == 0 ) ? 0 : std::ceil(
header.data_size /
header.nwords);
294 for (std::size_t
i = 0;
i <
header.nwords; ++
i) {
295 std::vector<std::uint32_t>
data{};
296 for (std::size_t j = 0; j < felix_n_words; ++j) {
297 data.push_back(
decode(readPointer, word_size));
299 current_stream_data.push_back(std::move(
data));
301 return current_stream_data;
305 std::vector<std::vector<std::uint32_t>> current_stream_data{};
308 return decode_data_payload_v3( readPointer,
header,
version);
309 size_t word_size = WORD_SIZE;
310 for (std::size_t
i = 0;
i <
header.nwords; ++
i) {
311 std::vector<std::uint32_t>
data{};
312 for (std::size_t j = 0; j <
header.data_size; ++j) {
313 data.push_back(
decode(readPointer, word_size));
315 current_stream_data.push_back(std::move(
data));
317 return current_stream_data;
327 return Muon::nsw::decode_and_advance<std::uint64_t, std::uint32_t>(
m_data, readPointer,
size);
332 size_t word_size = WORD_SIZE_DOUBLE;
333 auto counterChunk = std::size_t{0};
334 for (
const auto& dataChunk : m_stream_data) {
335 for (
const auto& dataWord : dataChunk) {
336 const auto expectedSize =
337 static_cast<std::size_t
>(std::ceil(m_stream_head_nbits.at(counterChunk) / word_size));
338 if (
std::size(dataWord) != expectedSize) {
339 throw std::length_error(
Muon::nsw::format(
"Stream data size {} does not match expected number of messages {}",
342 switch (m_stream_head_streamID.at(counterChunk)) {
344 m_pad_packets.emplace_back(dataWord,
version);
347 m_segment_packets.emplace_back(dataWord,
version);
350 m_mm_packets.emplace_back(dataWord,
version);
353 m_strip_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 m_strip_packets.emplace_back(dataWord,
version);
390 throw std::runtime_error(
Muon::nsw::format(
"Invalid stream type {}", m_stream_head_streamID.at(counterChunk)));
398 static constexpr
auto PADDING = 16;
399 if (initial % PADDING) {
400 return ((initial + PADDING - 1) / PADDING) * PADDING;