LDMX Software
EcalRawEncoder.cxx
1#include "Ecal/EcalRawEncoder.h"
2
3#include <bitset>
4
6#include "DetDescr/EcalID.h"
8#include "Packing/Utility/CRC.h"
9#include "Packing/Utility/Mask.h"
11
12namespace ecal {
13
14EcalRawEncoder::EcalRawEncoder(const std::string& name,
15 framework::Process& process)
16 : Producer(name, process) {}
17
19
21 input_name_ = ps.get<std::string>("input_name");
22 input_pass_ = ps.get<std::string>("input_pass");
23 output_name_ = ps.get<std::string>("output_name");
24 roc_version_ = ps.get<int>("roc_version");
25}
26
31 // static const unsigned int common_mode_channel = roc_version_ == 2 ? 19 : 1;
32
33 auto digis{
35 std::vector<std::map<
36 uint16_t, std::map<uint16_t, std::map<uint32_t, uint32_t> // channel to
37 // sample
38 > // links
39 > // fpgas
40 > // bunches
41 sorted_samples(digis.getNumSamplesPerDigi());
42
51 auto detmap{
53 for (auto digi : digis) {
54 ldmx::EcalID detid{digi.id()};
55 ldmx::EcalElectronicsID eid{detmap.get(detid)};
56
57 for (std::size_t i_bx{0}; i_bx < digis.getNumSamplesPerDigi(); i_bx++) {
58 sorted_samples[i_bx][eid.fiber()][eid.elink()][eid.channel()] =
59 digi.at(i_bx).raw();
60 }
61 }
62
73 std::vector<uint32_t> buffer;
74 // word to use for constructing buffer
75 static uint32_t word;
76 uint32_t i_bx{0};
77 for (auto const& bunch : sorted_samples) {
82 uint32_t bunch_id = event.getEventNumber();
83 uint32_t rreq = i_bx;
84 uint32_t orbit = event.getEventHeader().getRun();
85
86 // bunch lists the fpgs, links, and channels with their corresponding sample
87 for (auto const& [fpga_id, links] : bunch) {
99 std::vector<uint32_t> link_lengths;
100 for (auto const& [link_id, channels] : links) {
101 link_lengths.push_back(3 + 1 + channels.size() + 1);
102 }
103
114 uint32_t n_linkwords =
115 link_lengths.size() / 4 + (link_lengths.size() % 4 != 0);
116 uint32_t total_length{2 + n_linkwords + 1};
117 for (uint32_t const& link_len : link_lengths) {
118 total_length += link_len;
119 }
120
121 packing::utility::CRC fpga_crc;
137 word = 0;
138
139 word |= (1 << (12 + 1 + 6 + 8)); // version
140 word |= (fpga_id & packing::utility::MASK<8>) << (12 + 1 + 6); // FPGA
141 word |= (links.size() & packing::utility::MASK<6>) << (12 + 1); // NLINKS
142 word |= (total_length & packing::utility::MASK<12>); // LEN TODO
143 buffer.push_back(word);
144 fpga_crc << word;
145
146 word = 0;
147 word |= (bunch_id & packing::utility::MASK<12>) << 20; // BX ID
148 word |= (rreq & packing::utility::MASK<10>) << 10; // RREQ
149 word |= (orbit & packing::utility::MASK<10>); // OR
150 buffer.push_back(word);
151 fpga_crc << word;
152
156 for (uint32_t i_linkword{0}; i_linkword < n_linkwords; i_linkword++) {
157 word = 0;
158 for (uint32_t i_linklen{0}; i_linklen < 4; i_linklen++) {
159 uint32_t i_link = 4 * i_linkword + i_linklen;
160 if (i_link <= link_lengths.size()) {
161 // we have a link
162 word |= (((0b11 << 6) +
163 (link_lengths.at(i_link) & packing::utility::MASK<6>))
164 << 8 * i_linklen);
165 } // do we have a link for this linklen subword?
166 } // loop through subwords in this word
167 buffer.push_back(word);
168 fpga_crc << word;
169 } // loop through words
170
171 // fpga lists the links and channels with their corresponding sample
172 for (auto const& [link_id, channels] : links) {
176 std::bitset<40> ro_map; // starts as all 0s
177 ro_map.set(0); // special "header" word from ROC
178 ro_map.set(39); // trailing checksum from ROC
179 // each link maps the channels that were readout to their sample
180 for (auto const& [channel, sample] : channels) {
181 ro_map.set(channel);
182 }
183
184 packing::utility::CRC link_crc;
194 word = 0;
195 word |= (link_id & packing::utility::MASK<16>) << 16;
196 word |= 1 << 15;
197 // put first 8bits of RO Map in first header word
198 word |= (ro_map >> 32).to_ulong();
199
200 buffer.push_back(word);
201 fpga_crc << word;
202 link_crc << word;
203
204 // next header word is end of RO map
205 word = (ro_map.to_ulong() & 0xFFFFFFFF);
206 buffer.push_back(word);
207 fpga_crc << word;
208 link_crc << word;
209
210 // special "header" word from ROC
211 word = 0;
212 word |= 0b0101 << 28;
213 word |= (bunch_id & packing::utility::MASK<12>) << 16;
214 word |= (rreq & packing::utility::MASK<6>) << 10;
215 word |= (orbit & packing::utility::MASK<3>) << 7;
216 // skipping hamming error bits because we will set them all to false
217 // here
218 word |= 0b0101;
219 buffer.push_back(word);
220 fpga_crc << word;
221 link_crc << word;
222
231 // put samples into buffer
232 for (auto const& [channel, sample] : channels) {
233 buffer.push_back(sample);
234 fpga_crc << sample;
235 link_crc << sample;
236 }
237 buffer.push_back(link_crc.get());
238 fpga_crc << link_crc.get();
239 }
240 }
241 i_bx++;
242 }
243
244 event.add(output_name_, buffer);
245
246 return;
247} // produce
248
249} // namespace ecal
250
Class which contains logic for how the detector items connect to and relate with the reconstruction c...
Class that identifies a location in the Ecal readout chain.
Class that defines an ECal detector ID with a cell number.
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Class that represents a digitized hit in a calorimeter cell readout by an HGCROC.
static constexpr const char * CONDITIONS_OBJECT_NAME
The name of the EID <-> DetID map for the ECal.
std::string output_name_
output object to put onto event bus
std::string input_pass_
input pass of creating encoded data
virtual void configure(framework::config::Parameters &)
Callback for the EventProcessor to configure itself from the given set of parameters.
virtual ~EcalRawEncoder()
Destructor.
EcalRawEncoder(const std::string &name, framework::Process &process)
Constructor.
int roc_version_
version of HGC ROC we are decoding
virtual void produce(framework::Event &event)
Process the event and put new data products into it.
std::string input_name_
input object of encoded data
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
Implements an event buffer system for storing event data.
Definition Event.h:40
Class which represents the process under execution.
Definition Process.h:34
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
Identifies a location in the Ecal readout chain.
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20
Represents a collection of the digi hits readout by an HGCROC.
The HGC ROC and FPGA use a CRC checksum to double check that the data transfer has been done correctl...
Definition CRC.h:51
uint32_t get()
Get the calculate checksum from the calculator.
Definition CRC.h:111