LDMX Software
packing::MultiSampleECONDEventPacket Class Reference

Unpack an event that has potentially more than one sample collected from a single ECOND. More...

#include <MultiSampleECONDEventPacket.h>

Public Types

enum  Corruption : std::size_t {
  RESYNC = 0 , LOST_SYNC = 1 , NO_TRAILER = 2 , TRAILER_COUNT_MISMATCH = 3 ,
  ECON_ID_MISMATCH = 4 , SAMPLE_INDEX_MISMATCH = 5 , TRUNCATED_FRAME = 6 , EXTRA_WORDS = 7 ,
  NO_SOI = 8 , N_CORRUPTION = 9
}
 index of frame-level corruption flags More...
 

Public Member Functions

 MultiSampleECONDEventPacket (int n_links)
 constructor defining how many links are connected to this ECOND
 
const ECONDEventPacket & soi () const
 get the sample of interest
 
bool isCorrupt () const
 any of the frame-level corruption flags are set
 
void from (std::span< const uint32_t > frame)
 unpack the given frame into this structure
 

Public Attributes

std::array< bool, N_CORRUPTION > corruption_ {}
 corruption flags indexed by Corruption
 
std::size_t i_soi_ {0}
 index of the sample of interest (SOI)
 
int econd_id_ {-1}
 ID for this econ from the first capture header (-1 if none)
 
int trailer_n_samples_ {-1}
 number of samples written in the trailer (-1 if no trailer)
 
std::size_t n_skipped_words_ {0}
 number of words skipped while searching for capture headers
 
std::vector< DAQSampleHeader > headers_
 capture headers stored in order of transmission
 
std::vector< ECONDEventPacket > samples_
 samples from ECOND stored in order of transmission
 

Private Member Functions

std::size_t resync (std::span< const uint32_t > frame, std::size_t start, std::size_t i_sample) const
 find the next capture header for sample i_sample or the trailer
 
 enableLogging ("MultiSampleECONDEventPacket")
 handle to logging source
 

Private Attributes

int n_links_
 number of links connected to the ECOND
 

Detailed Description

Unpack an event that has potentially more than one sample collected from a single ECOND.

The frame is what SingleSubsystemUnpacker puts on the event bus (the data after the LDMX RoR header) as 32-bit words: for each sample a DAQSampleHeader followed by the ECON-D packet, then the DAQSampleHeader::endingTrailer and zero padding.

Corrupted ECON-D packets are flagged in their ECONDEventPacket and we move on to the next capture header using the length. If the word at that position is not a capture header, we search forward for the capture header of the next sample (or the trailer) and count the skipped words.

See also
ECONDEventPacket for how a single sample from a single ECOND is unpacked.
Note
Ported from pflib::packing::MultiSampleECONDEventPacket.

Definition at line 29 of file MultiSampleECONDEventPacket.h.

Member Enumeration Documentation

◆ Corruption

index of frame-level corruption flags

Enumerator
RESYNC 

a capture header was missing, words were skipped to find the next

LOST_SYNC 

no further capture header or trailer found, rest of frame dropped

NO_TRAILER 

the frame ended without the ending trailer

TRAILER_COUNT_MISMATCH 

number of samples in the trailer does not match the number found

ECON_ID_MISMATCH 

ECON ID changed within the frame.

SAMPLE_INDEX_MISMATCH 

sample index in capture header does not match its position

TRUNCATED_FRAME 

capture header length goes past the end of the frame

EXTRA_WORDS 

non-zero words after the ending trailer

NO_SOI 

no sample flagged as the sample of interest

N_CORRUPTION 

number of corruption flags

Definition at line 32 of file MultiSampleECONDEventPacket.h.

32 : std::size_t {
34 RESYNC = 0,
36 LOST_SYNC = 1,
38 NO_TRAILER = 2,
48 EXTRA_WORDS = 7,
50 NO_SOI = 8,
52 N_CORRUPTION = 9
53 };
@ NO_TRAILER
the frame ended without the ending trailer
@ RESYNC
a capture header was missing, words were skipped to find the next
@ NO_SOI
no sample flagged as the sample of interest
@ TRUNCATED_FRAME
capture header length goes past the end of the frame
@ LOST_SYNC
no further capture header or trailer found, rest of frame dropped
@ SAMPLE_INDEX_MISMATCH
sample index in capture header does not match its position
@ TRAILER_COUNT_MISMATCH
number of samples in the trailer does not match the number found
@ EXTRA_WORDS
non-zero words after the ending trailer
@ ECON_ID_MISMATCH
ECON ID changed within the frame.

Constructor & Destructor Documentation

◆ MultiSampleECONDEventPacket()

packing::MultiSampleECONDEventPacket::MultiSampleECONDEventPacket ( int n_links)
explicit

constructor defining how many links are connected to this ECOND

Definition at line 11 of file MultiSampleECONDEventPacket.cxx.

12 : n_links_{n_links} {}
int n_links_
number of links connected to the ECOND

Member Function Documentation

◆ from()

void packing::MultiSampleECONDEventPacket::from ( std::span< const uint32_t > frame)

unpack the given frame into this structure

Definition at line 42 of file MultiSampleECONDEventPacket.cxx.

42 {
43 corruption_.fill(false);
44 i_soi_ = 0;
45 econd_id_ = -1;
48 headers_.clear();
49 samples_.clear();
50
51 bool found_soi{false};
52 std::size_t offset{0};
53 DAQSampleHeader header;
54 while (offset < frame.size()) {
55 header.from(frame[offset]);
56 if (header.version_ == DAQSampleHeader::VERSION and
57 header.isEndingTrailer()) {
59 ldmx_log(trace) << "Last sample packet found at offset = " << offset
60 << " (frame.size() = " << frame.size() << ")";
61 offset++;
62 break;
63 }
64
65 bool valid =
66 DAQSampleHeader::isValid(frame[offset]) and
67 (econd_id_ < 0 or header.econd_id_ == static_cast<uint32_t>(econd_id_));
68 if (not valid) {
69 if (DAQSampleHeader::isValid(frame[offset])) {
71 }
72 auto next = resync(frame, offset + 1, samples_.size());
73 ldmx_log(debug) << Hex(frame[offset])
74 << " is not a capture header, skipping "
75 << (next - offset) << " words";
76 corruption_[RESYNC] = true;
77 n_skipped_words_ += next - offset;
78 if (next == frame.size()) {
79 corruption_[LOST_SYNC] = true;
80 }
81 offset = next;
82 continue;
83 }
84
85 if (econd_id_ < 0) econd_id_ = header.econd_id_;
86 ldmx_log(trace) << Hex(frame[offset]) << " -> " << header;
87
88 // header decoded, shift offset
89 offset++;
90
91 std::size_t i_sample{samples_.size()};
92 if (i_sample != header.i_l1a_) {
93 ldmx_log(debug) << "mismatch between transmitted index " << header.i_l1a_
94 << " and unpacking index for sample " << i_sample;
96 }
97
98 if (header.is_soi_ and not found_soi) {
99 i_soi_ = i_sample;
100 found_soi = true;
101 }
102
103 std::size_t len{header.econd_len_};
104 if (offset + len > frame.size()) {
105 ldmx_log(debug) << "capture header length " << len << " goes past the "
106 << "end of the frame by " << (offset + len - frame.size())
107 << " words";
109 len = frame.size() - offset;
110 }
111
112 headers_.push_back(header);
113 samples_.emplace_back(n_links_);
114 samples_.back().from(frame.subspan(offset, len));
115 offset += len;
116 }
117
118 if (trailer_n_samples_ < 0) {
119 corruption_[NO_TRAILER] = true;
120 } else if (static_cast<std::size_t>(trailer_n_samples_) != samples_.size()) {
121 ldmx_log(debug) << "trailer says " << trailer_n_samples_
122 << " samples but found " << samples_.size();
124 }
125
126 // only zero padding is expected after the trailer
127 if (std::any_of(frame.begin() + offset, frame.end(),
128 [](uint32_t w) { return w != 0; })) {
129 ldmx_log(debug) << "non-zero words after the ending trailer";
130 corruption_[EXTRA_WORDS] = true;
131 }
132
133 if (not samples_.empty() and not found_soi) {
134 corruption_[NO_SOI] = true;
135 }
136}
int trailer_n_samples_
number of samples written in the trailer (-1 if no trailer)
std::size_t resync(std::span< const uint32_t > frame, std::size_t start, std::size_t i_sample) const
find the next capture header for sample i_sample or the trailer
std::size_t i_soi_
index of the sample of interest (SOI)
int econd_id_
ID for this econ from the first capture header (-1 if none)
std::vector< ECONDEventPacket > samples_
samples from ECOND stored in order of transmission
std::vector< DAQSampleHeader > headers_
capture headers stored in order of transmission
std::size_t n_skipped_words_
number of words skipped while searching for capture headers
std::array< bool, N_CORRUPTION > corruption_
corruption flags indexed by Corruption
static const uint32_t VERSION
expected format version
static bool isValid(uint32_t word)
check if the decoded word looks like a capture header
static uint32_t trailerNumSamples(uint32_t word)
number of samples written in the ending trailer

References corruption_, ECON_ID_MISMATCH, packing::DAQSampleHeader::econd_id_, econd_id_, packing::DAQSampleHeader::econd_len_, EXTRA_WORDS, packing::DAQSampleHeader::from(), headers_, packing::DAQSampleHeader::i_l1a_, i_soi_, packing::DAQSampleHeader::is_soi_, packing::DAQSampleHeader::isEndingTrailer(), packing::DAQSampleHeader::isValid(), LOST_SYNC, n_links_, n_skipped_words_, NO_SOI, NO_TRAILER, RESYNC, resync(), SAMPLE_INDEX_MISMATCH, samples_, TRAILER_COUNT_MISMATCH, trailer_n_samples_, packing::DAQSampleHeader::trailerNumSamples(), TRUNCATED_FRAME, packing::DAQSampleHeader::VERSION, and packing::DAQSampleHeader::version_.

◆ isCorrupt()

bool packing::MultiSampleECONDEventPacket::isCorrupt ( ) const

any of the frame-level corruption flags are set

Definition at line 18 of file MultiSampleECONDEventPacket.cxx.

18 {
19 return std::any_of(corruption_.begin(), corruption_.end(),
20 [](bool c) { return c; });
21}

References corruption_.

◆ resync()

std::size_t packing::MultiSampleECONDEventPacket::resync ( std::span< const uint32_t > frame,
std::size_t start,
std::size_t i_sample ) const
private

find the next capture header for sample i_sample or the trailer

Definition at line 23 of file MultiSampleECONDEventPacket.cxx.

25 {
26 DAQSampleHeader header;
27 for (std::size_t i{start}; i < frame.size(); i++) {
28 header.from(frame[i]);
29 if (header.version_ == DAQSampleHeader::VERSION and
30 header.isEndingTrailer()) {
31 return i;
32 }
33 if (DAQSampleHeader::isValid(frame[i]) and header.i_l1a_ == i_sample and
34 (econd_id_ < 0 or
35 header.econd_id_ == static_cast<uint32_t>(econd_id_))) {
36 return i;
37 }
38 }
39 return frame.size();
40}

References packing::DAQSampleHeader::econd_id_, econd_id_, packing::DAQSampleHeader::from(), packing::DAQSampleHeader::i_l1a_, packing::DAQSampleHeader::isEndingTrailer(), packing::DAQSampleHeader::isValid(), packing::DAQSampleHeader::VERSION, and packing::DAQSampleHeader::version_.

Referenced by from().

◆ soi()

const ECONDEventPacket & packing::MultiSampleECONDEventPacket::soi ( ) const

get the sample of interest

Definition at line 14 of file MultiSampleECONDEventPacket.cxx.

14 {
15 return samples_.at(i_soi_);
16}

References i_soi_, and samples_.

Member Data Documentation

◆ corruption_

std::array<bool, N_CORRUPTION> packing::MultiSampleECONDEventPacket::corruption_ {}

corruption flags indexed by Corruption

Definition at line 56 of file MultiSampleECONDEventPacket.h.

56{};

Referenced by from(), and isCorrupt().

◆ econd_id_

int packing::MultiSampleECONDEventPacket::econd_id_ {-1}

ID for this econ from the first capture header (-1 if none)

Definition at line 60 of file MultiSampleECONDEventPacket.h.

60{-1};

Referenced by from(), and resync().

◆ headers_

std::vector<DAQSampleHeader> packing::MultiSampleECONDEventPacket::headers_

capture headers stored in order of transmission

Definition at line 66 of file MultiSampleECONDEventPacket.h.

Referenced by from().

◆ i_soi_

std::size_t packing::MultiSampleECONDEventPacket::i_soi_ {0}

index of the sample of interest (SOI)

Definition at line 58 of file MultiSampleECONDEventPacket.h.

58{0};

Referenced by from(), and soi().

◆ n_links_

int packing::MultiSampleECONDEventPacket::n_links_
private

number of links connected to the ECOND

Definition at line 88 of file MultiSampleECONDEventPacket.h.

Referenced by from().

◆ n_skipped_words_

std::size_t packing::MultiSampleECONDEventPacket::n_skipped_words_ {0}

number of words skipped while searching for capture headers

Definition at line 64 of file MultiSampleECONDEventPacket.h.

64{0};

Referenced by from().

◆ samples_

std::vector<ECONDEventPacket> packing::MultiSampleECONDEventPacket::samples_

samples from ECOND stored in order of transmission

Definition at line 68 of file MultiSampleECONDEventPacket.h.

Referenced by from(), and soi().

◆ trailer_n_samples_

int packing::MultiSampleECONDEventPacket::trailer_n_samples_ {-1}

number of samples written in the trailer (-1 if no trailer)

Definition at line 62 of file MultiSampleECONDEventPacket.h.

62{-1};

Referenced by from().


The documentation for this class was generated from the following files: