LDMX Software
packing::ECONDDecoder Class Reference

decode event packets built by ECON-D chips More...

#include <ECONDDecoder.h>

Public Member Functions

 ECONDDecoder (const std::string &name, framework::Process &p)
 normal constructor
 
virtual ~ECONDDecoder ()=default
 empty destructor
 
void configure (framework::config::Parameters &ps) override
 configure the decoder
 
void produce (framework::Event &event) override
 decode the raw binary data into HgcrocDigiCollection that can be used later for reconstruction or analysis
 
void onProcessEnd () override
 print a summary of the decoding
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void process (Event &event) final
 Processing an event for a Producer is calling produce.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void beforeNewRun (ldmx::RunHeader &run_header)
 Callback for Producers to add parameters to the run header before conditions are initialized.
 
virtual void onNewRun (const ldmx::RunHeader &run_header)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module_.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Member Functions

unsigned int channelID (int i_link, int i_ch) const
 get the channel ID for the input link and channel
 

Private Attributes

std::string raw_data_name_
 name of event object of raw binary data
 
std::string raw_data_pass_
 name of pass to get raw binary data from
 
std::string digi_output_name_
 output name of digi collection
 
std::string info_output_name_
 output name of supporting data object
 
bool is_ecal_ {false}
 which calorimeter subsystem we are decoding (true == Ecal, false == Hcal)
 
int n_links_ {2}
 number of enabled eRx on the ECON-D
 
int fiber_ {0}
 optical fiber index used in the electronics ID
 
bool translate_eid_ {false}
 translate electronics IDs into detector IDs
 
int roc_version_ {3}
 ROC version for the digi collection.
 
std::unique_ptr< MultiSampleECONDEventPacket > packet_
 decoding buffer
 
long n_frames_ {0}
 number of frames seen
 
long n_no_frame_ {0}
 number of events without an input frame
 
long n_frames_filled_ {0}
 number of frames whose digis were filled
 
long n_bad_frame_size_ {0}
 number of frames with a size that is not a multiple of 4 bytes
 
std::array< long, MultiSampleECONDEventPacket::N_CORRUPTION > n_frame_flags_ {}
 number of frames with each frame-level flag
 
long n_packets_ {0}
 number of packets seen
 
long n_packets_decoded_ {0}
 number of packets decoded without corruption and not empty
 
long n_packets_empty_ {0}
 number of empty packets (payload length 0)
 
long n_packets_corrupt_ {0}
 number of corrupted packets (skipped)
 
std::array< long, ECONDEventPacket::N_CORRUPTION > n_packet_flags_ {}
 number of packets with each corruption flag
 
long n_links_bad_stat_ {0}
 number of decoded link sub-packets with bad Stat bits
 
long n_l1a_jumps_ {0}
 number of L1A jumps between consecutive samples
 

Additional Inherited Members

- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManager & ntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

decode event packets built by ECON-D chips

The ECON-D chip is used to construct the event packets for both the Ecal and Hcal subsystems, so both will share this decoder.

Each event on the bus is one frame from SingleSubsystemUnpacker holding all of the samples from a single ECON-D. The channel samples are put into an HgcrocDigiCollection and the rest of the packet data into an ldmx::ECONDEventInfo. Corrupted packets are flagged and skipped, the digis are only filled if all samples in the event are good.

The input can also be the subsystem buffer from the EventBuilder. Events without the input buffer get empty outputs flagged with ldmx::ECONDEventInfo::NO_FRAME.

Definition at line 30 of file ECONDDecoder.h.

Constructor & Destructor Documentation

◆ ECONDDecoder()

packing::ECONDDecoder::ECONDDecoder ( const std::string & name,
framework::Process & p )
inline

normal constructor

Definition at line 33 of file ECONDDecoder.h.

34 : framework::Producer(name, p) {}
Base class for a module which produces a data product.

Member Function Documentation

◆ channelID()

unsigned int packing::ECONDDecoder::channelID ( int i_link,
int i_ch ) const
private

get the channel ID for the input link and channel

Definition at line 60 of file ECONDDecoder.cxx.

60 {
61 if (is_ecal_) {
62 return ldmx::EcalElectronicsID(fiber_, i_link, i_ch).raw();
63 }
64 return ldmx::HcalElectronicsID(fiber_, i_link, i_ch).raw();
65}
RawValue raw() const
Definition DetectorID.h:69
Identifies a location in the Ecal readout chain.
Identifies a location in the Hcal readout chain.
int fiber_
optical fiber index used in the electronics ID
bool is_ecal_
which calorimeter subsystem we are decoding (true == Ecal, false == Hcal)

References fiber_, is_ecal_, and ldmx::DetectorID::raw().

Referenced by produce().

◆ configure()

void packing::ECONDDecoder::configure ( framework::config::Parameters & ps)
overridevirtual

configure the decoder

mostly focused on telling it which subsystem we are decoding (to know how to pack the ID numbers correctly), the input and output event objects.

Reimplemented from framework::EventProcessor.

Definition at line 47 of file ECONDDecoder.cxx.

47 {
48 raw_data_name_ = ps.get<std::string>("raw_data_name");
49 raw_data_pass_ = ps.get<std::string>("raw_data_pass");
50 digi_output_name_ = ps.get<std::string>("digi_output_name");
51 info_output_name_ = ps.get<std::string>("info_output_name");
52 is_ecal_ = ps.get<bool>("is_ecal");
53 n_links_ = ps.get<int>("n_links");
54 fiber_ = ps.get<int>("fiber");
55 translate_eid_ = ps.get<bool>("translate_eid");
56 roc_version_ = ps.get<int>("roc_version");
57 packet_ = std::make_unique<MultiSampleECONDEventPacket>(n_links_);
58}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
int roc_version_
ROC version for the digi collection.
std::string raw_data_pass_
name of pass to get raw binary data from
bool translate_eid_
translate electronics IDs into detector IDs
std::string raw_data_name_
name of event object of raw binary data
std::string digi_output_name_
output name of digi collection
int n_links_
number of enabled eRx on the ECON-D
std::string info_output_name_
output name of supporting data object
std::unique_ptr< MultiSampleECONDEventPacket > packet_
decoding buffer

References digi_output_name_, fiber_, framework::config::Parameters::get(), info_output_name_, is_ecal_, n_links_, packet_, raw_data_name_, raw_data_pass_, roc_version_, and translate_eid_.

◆ onProcessEnd()

void packing::ECONDDecoder::onProcessEnd ( )
overridevirtual

print a summary of the decoding

Reimplemented from framework::EventProcessor.

Definition at line 196 of file ECONDDecoder.cxx.

196 {
197 ldmx_log(info) << "ECON-D decoding summary for " << raw_data_name_;
198 ldmx_log(info) << " frames seen: " << n_frames_
199 << ", digis filled: " << n_frames_filled_;
200 if (n_no_frame_ > 0) {
201 ldmx_log(info) << " events without a frame: " << n_no_frame_;
202 }
203 if (n_bad_frame_size_ > 0) {
204 ldmx_log(info) << " frames with size not a multiple of 4 bytes: "
206 }
207 for (std::size_t i{0}; i < n_frame_flags_.size(); i++) {
208 if (n_frame_flags_[i] > 0) {
209 ldmx_log(info) << " frames with " << FRAME_FLAG_NAMES[i] << ": "
210 << n_frame_flags_[i];
211 }
212 }
213 ldmx_log(info) << " packets seen: " << n_packets_
214 << ", decoded: " << n_packets_decoded_
215 << ", empty: " << n_packets_empty_
216 << ", corrupt (skipped): " << n_packets_corrupt_;
217 for (std::size_t i{0}; i < n_packet_flags_.size(); i++) {
218 if (n_packet_flags_[i] > 0) {
219 ldmx_log(info) << " packets with " << PACKET_FLAG_NAMES[i] << ": "
220 << n_packet_flags_[i];
221 }
222 }
223 if (n_links_bad_stat_ > 0) {
224 ldmx_log(info) << " decoded links with bad Stat bits: "
226 }
227 ldmx_log(info) << " L1A jumps between samples: " << n_l1a_jumps_;
228}
long n_l1a_jumps_
number of L1A jumps between consecutive samples
long n_packets_empty_
number of empty packets (payload length 0)
long n_links_bad_stat_
number of decoded link sub-packets with bad Stat bits
long n_packets_
number of packets seen
long n_packets_corrupt_
number of corrupted packets (skipped)
std::array< long, MultiSampleECONDEventPacket::N_CORRUPTION > n_frame_flags_
number of frames with each frame-level flag
std::array< long, ECONDEventPacket::N_CORRUPTION > n_packet_flags_
number of packets with each corruption flag
long n_packets_decoded_
number of packets decoded without corruption and not empty
long n_no_frame_
number of events without an input frame
long n_bad_frame_size_
number of frames with a size that is not a multiple of 4 bytes
long n_frames_filled_
number of frames whose digis were filled
long n_frames_
number of frames seen

References n_bad_frame_size_, n_frame_flags_, n_frames_, n_frames_filled_, n_l1a_jumps_, n_links_bad_stat_, n_no_frame_, n_packet_flags_, n_packets_, n_packets_corrupt_, n_packets_decoded_, n_packets_empty_, and raw_data_name_.

◆ produce()

void packing::ECONDDecoder::produce ( framework::Event & event)
overridevirtual

decode the raw binary data into HgcrocDigiCollection that can be used later for reconstruction or analysis

Implements framework::Producer.

Definition at line 67 of file ECONDDecoder.cxx.

67 {
71 digis.setNumSamplesPerDigi(0);
73
74 // e.g. an EventBuilder event without a fragment from this subsystem
75 if (not event.exists(raw_data_name_, raw_data_pass_)) {
77 info.setFrame(1 << ldmx::ECONDEventInfo::NO_FRAME, -1, 0, 0);
78 event.add(digi_output_name_, digis);
79 event.add(info_output_name_, info);
80 return;
81 }
82
83 const auto& raw_binary{
84 event.getCollection<uint8_t>(raw_data_name_, raw_data_pass_)};
85 n_frames_++;
86
87 int frame_corruption{0};
88 if (raw_binary.size() % 4 != 0) {
89 ldmx_log(debug) << raw_data_name_ << " has " << raw_binary.size()
90 << " bytes which is not a multiple of 4, ignoring the "
91 << raw_binary.size() % 4 << " trailing bytes";
92 frame_corruption |= (1 << ldmx::ECONDEventInfo::BAD_FRAME_SIZE);
94 }
95 // copy into 32-bit words, the data is little endian
96 std::vector<uint32_t> words(raw_binary.size() / 4);
97 std::memcpy(words.data(), raw_binary.data(), words.size() * 4);
98
99 packet_->from(words);
100 const auto& pkt{*packet_};
101 frame_corruption |= toMask(pkt.corruption_);
102 for (std::size_t i{0}; i < pkt.corruption_.size(); i++) {
103 if (pkt.corruption_[i]) n_frame_flags_[i]++;
104 }
105
106 bool all_good = (frame_corruption == 0) and not pkt.samples_.empty();
107 for (std::size_t i_sample{0}; i_sample < pkt.samples_.size(); i_sample++) {
108 const auto& header{pkt.headers_[i_sample]};
109 const auto& sample{pkt.samples_[i_sample]};
110 n_packets_++;
111
112 ldmx::ECONDSampleInfo sample_info;
113 sample_info.setCaptureHeader(header.econd_id_, header.i_l1a_,
114 header.is_soi_, header.econd_len_);
115 int flags = (sample.passthrough_ ? 1 : 0) | (sample.expected_ ? 2 : 0) |
116 (sample.match_ ? 4 : 0) | (sample.truncated_ ? 8 : 0) |
117 (sample.subpacket_error_ ? 16 : 0);
118 sample_info.setHeader(sample.payload_length_, flags, sample.ht_,
119 sample.ebo_, sample.bx_, sample.l1a_, sample.orbit_,
120 sample.reset_request_);
121 sample_info.setCorruption(toMask(sample.corruption_));
122
123 for (std::size_t i{0}; i < sample.corruption_.size(); i++) {
124 if (sample.corruption_[i]) n_packet_flags_[i]++;
125 }
126
127 if (sample.isCorrupt()) {
129 all_good = false;
130 } else if (sample.isEmpty()) {
132 all_good = false;
133 } else {
135 for (const auto& link : sample.links_) {
136 if (link.badStat()) n_links_bad_stat_++;
137 ldmx::ECONDLinkInfo link_info;
138 link_info.set(link.stat_, link.is_empty_, link.adc_cm0_, link.adc_cm1_,
139 link.calib_);
140 sample_info.addLink(link_info);
141 }
142 }
143
144 // L1A numbers are 6 bits
145 if (i_sample > 0 and not sample.isCorrupt() and
146 not pkt.samples_[i_sample - 1].isCorrupt() and
147 sample.l1a_ != ((pkt.samples_[i_sample - 1].l1a_ + 1) & 0x3f)) {
148 n_l1a_jumps_++;
149 }
150
151 info.addSample(sample_info);
152 }
153
154 info.setFrame(frame_corruption, pkt.trailer_n_samples_, pkt.i_soi_,
155 pkt.n_skipped_words_);
156
157 if (all_good) {
158 std::size_t n_samples{pkt.samples_.size()};
159 digis.setNumSamplesPerDigi(n_samples);
160 digis.setSampleOfInterestIndex(pkt.i_soi_);
161 // resort from (sample, link, channel) to (link, channel, sample)
162 std::vector<uint32_t> digi(n_samples);
163 for (int i_link{0}; i_link < n_links_; i_link++) {
164 for (int i_ch{0}; i_ch < 36; i_ch++) {
165 for (std::size_t i_sample{0}; i_sample < n_samples; i_sample++) {
166 digi[i_sample] =
167 pkt.samples_[i_sample].links_[i_link].channels_[i_ch];
168 }
169 unsigned int id{channelID(i_link, i_ch)};
170 if (translate_eid_) {
171 if (is_ecal_) {
172 const auto& detmap{getCondition<ecal::EcalDetectorMap>(
175 if (not detmap.exists(eid)) continue;
176 id = detmap.get(eid).raw();
177 } else {
178 const auto& detmap{getCondition<hcal::HcalDetectorMap>(
181 if (not detmap.exists(eid)) continue;
182 id = detmap.get(eid).raw();
183 }
184 }
185 digis.addDigi(id, digi);
186 }
187 }
189 }
190 info.setDigisFilled(all_good);
191
192 event.add(digi_output_name_, digis);
193 event.add(info_output_name_, info);
194}
static constexpr const char * CONDITIONS_OBJECT_NAME
The name of the EID <-> DetID map for the ECal.
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:107
static constexpr const char * CONDITIONS_OBJECT_NAME
The name of the EID <-> DetID map for the ECal.
Supporting data for one event decoded from a single ECON-D.
Data from one eRx ("link") sub-packet of an ECON-D packet that is not a normal channel.
void set(int stat, bool is_empty, int adc_cm0, int adc_cm1, uint32_t calib)
Set the link data.
Capture header and ECON-D header data for one sample (L1A)
void setHeader(int payload_length, int flags, int ht, int ebo, int bx, int l1a, int orbit, int reset_request)
Set the ECON-D event header data.
void setCaptureHeader(int econ_id, int i_sample, bool is_soi, int length)
Set the capture header data.
void addLink(const ECONDLinkInfo &link)
add the data from the next link
void setCorruption(int mask)
set the corruption mask
Represents a collection of the digi hits readout by an HGCROC.
void setNumSamplesPerDigi(unsigned int n)
Set number of samples for each digi.
void setSampleOfInterestIndex(unsigned int n)
Set index of sample of interest.
void setVersion(int v)
Set the version of the ROC we have read.
void addDigi(unsigned int id, const std::vector< Sample > &digi)
Add samples to collection.
unsigned int channelID(int i_link, int i_ch) const
get the channel ID for the input link and channel

References ldmx::HgcrocDigiCollection::addDigi(), ldmx::ECONDSampleInfo::addLink(), channelID(), ecal::EcalDetectorMap::CONDITIONS_OBJECT_NAME, hcal::HcalDetectorMap::CONDITIONS_OBJECT_NAME, digi_output_name_, framework::Event::exists(), framework::EventProcessor::getCondition(), info_output_name_, is_ecal_, n_bad_frame_size_, n_frame_flags_, n_frames_, n_frames_filled_, n_l1a_jumps_, n_links_, n_links_bad_stat_, n_no_frame_, n_packet_flags_, n_packets_, n_packets_corrupt_, n_packets_decoded_, n_packets_empty_, packet_, raw_data_name_, raw_data_pass_, roc_version_, ldmx::ECONDLinkInfo::set(), ldmx::ECONDSampleInfo::setCaptureHeader(), ldmx::ECONDSampleInfo::setCorruption(), ldmx::ECONDSampleInfo::setHeader(), ldmx::HgcrocDigiCollection::setNumSamplesPerDigi(), ldmx::HgcrocDigiCollection::setSampleOfInterestIndex(), ldmx::HgcrocDigiCollection::setVersion(), and translate_eid_.

Member Data Documentation

◆ digi_output_name_

std::string packing::ECONDDecoder::digi_output_name_
private

output name of digi collection

Definition at line 65 of file ECONDDecoder.h.

Referenced by configure(), and produce().

◆ fiber_

int packing::ECONDDecoder::fiber_ {0}
private

optical fiber index used in the electronics ID

Definition at line 76 of file ECONDDecoder.h.

76{0};

Referenced by channelID(), and configure().

◆ info_output_name_

std::string packing::ECONDDecoder::info_output_name_
private

output name of supporting data object

Definition at line 67 of file ECONDDecoder.h.

Referenced by configure(), and produce().

◆ is_ecal_

bool packing::ECONDDecoder::is_ecal_ {false}
private

which calorimeter subsystem we are decoding (true == Ecal, false == Hcal)

Definition at line 72 of file ECONDDecoder.h.

72{false};

Referenced by channelID(), configure(), and produce().

◆ n_bad_frame_size_

long packing::ECONDDecoder::n_bad_frame_size_ {0}
private

number of frames with a size that is not a multiple of 4 bytes

Definition at line 92 of file ECONDDecoder.h.

92{0};

Referenced by onProcessEnd(), and produce().

◆ n_frame_flags_

std::array<long, MultiSampleECONDEventPacket::N_CORRUPTION> packing::ECONDDecoder::n_frame_flags_ {}
private

number of frames with each frame-level flag

Definition at line 94 of file ECONDDecoder.h.

94{};

Referenced by onProcessEnd(), and produce().

◆ n_frames_

long packing::ECONDDecoder::n_frames_ {0}
private

number of frames seen

Definition at line 86 of file ECONDDecoder.h.

86{0};

Referenced by onProcessEnd(), and produce().

◆ n_frames_filled_

long packing::ECONDDecoder::n_frames_filled_ {0}
private

number of frames whose digis were filled

Definition at line 90 of file ECONDDecoder.h.

90{0};

Referenced by onProcessEnd(), and produce().

◆ n_l1a_jumps_

long packing::ECONDDecoder::n_l1a_jumps_ {0}
private

number of L1A jumps between consecutive samples

Definition at line 108 of file ECONDDecoder.h.

108{0};

Referenced by onProcessEnd(), and produce().

◆ n_links_

int packing::ECONDDecoder::n_links_ {2}
private

number of enabled eRx on the ECON-D

Definition at line 74 of file ECONDDecoder.h.

74{2};

Referenced by configure(), and produce().

◆ n_links_bad_stat_

long packing::ECONDDecoder::n_links_bad_stat_ {0}
private

number of decoded link sub-packets with bad Stat bits

Definition at line 106 of file ECONDDecoder.h.

106{0};

Referenced by onProcessEnd(), and produce().

◆ n_no_frame_

long packing::ECONDDecoder::n_no_frame_ {0}
private

number of events without an input frame

Definition at line 88 of file ECONDDecoder.h.

88{0};

Referenced by onProcessEnd(), and produce().

◆ n_packet_flags_

std::array<long, ECONDEventPacket::N_CORRUPTION> packing::ECONDDecoder::n_packet_flags_ {}
private

number of packets with each corruption flag

Definition at line 104 of file ECONDDecoder.h.

104{};

Referenced by onProcessEnd(), and produce().

◆ n_packets_

long packing::ECONDDecoder::n_packets_ {0}
private

number of packets seen

Definition at line 96 of file ECONDDecoder.h.

96{0};

Referenced by onProcessEnd(), and produce().

◆ n_packets_corrupt_

long packing::ECONDDecoder::n_packets_corrupt_ {0}
private

number of corrupted packets (skipped)

Definition at line 102 of file ECONDDecoder.h.

102{0};

Referenced by onProcessEnd(), and produce().

◆ n_packets_decoded_

long packing::ECONDDecoder::n_packets_decoded_ {0}
private

number of packets decoded without corruption and not empty

Definition at line 98 of file ECONDDecoder.h.

98{0};

Referenced by onProcessEnd(), and produce().

◆ n_packets_empty_

long packing::ECONDDecoder::n_packets_empty_ {0}
private

number of empty packets (payload length 0)

Definition at line 100 of file ECONDDecoder.h.

100{0};

Referenced by onProcessEnd(), and produce().

◆ packet_

std::unique_ptr<MultiSampleECONDEventPacket> packing::ECONDDecoder::packet_
private

decoding buffer

Definition at line 83 of file ECONDDecoder.h.

Referenced by configure(), and produce().

◆ raw_data_name_

std::string packing::ECONDDecoder::raw_data_name_
private

name of event object of raw binary data

Definition at line 61 of file ECONDDecoder.h.

Referenced by configure(), onProcessEnd(), and produce().

◆ raw_data_pass_

std::string packing::ECONDDecoder::raw_data_pass_
private

name of pass to get raw binary data from

Definition at line 63 of file ECONDDecoder.h.

Referenced by configure(), and produce().

◆ roc_version_

int packing::ECONDDecoder::roc_version_ {3}
private

ROC version for the digi collection.

Definition at line 80 of file ECONDDecoder.h.

80{3};

Referenced by configure(), and produce().

◆ translate_eid_

bool packing::ECONDDecoder::translate_eid_ {false}
private

translate electronics IDs into detector IDs

Definition at line 78 of file ECONDDecoder.h.

78{false};

Referenced by configure(), and produce().


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