LDMX Software
EcalRawEncoder.cxx
1#include "Ecal/EcalRawEncoder.h"
2
3#include <bitset>
4
6#include "DetDescr/EcalID.h"
8#include "Packing/Utility/BufferReader.h"
9#include "Packing/Utility/CRC.h"
10#include "Packing/Utility/Mask.h"
12
13namespace ecal {
14
15EcalRawEncoder::EcalRawEncoder(const std::string& name,
16 framework::Process& process)
17 : Producer(name, process) {}
18
20
22 input_name_ = ps.getParameter<std::string>("input_name");
23 input_pass_ = ps.getParameter<std::string>("input_pass");
24 output_name_ = ps.getParameter<std::string>("output_name");
25 roc_version_ = ps.getParameter<int>("roc_version");
26}
27
32 // static const unsigned int common_mode_channel = roc_version_ == 2 ? 19 : 1;
33
34 auto digis{
36 std::vector<std::map<
37 uint16_t, std::map<uint16_t, std::map<uint32_t, uint32_t> // channel to
38 // sample
39 > // links
40 > // fpgas
41 > // bunches
42 sorted_samples(digis.getNumSamplesPerDigi());
43
52 auto detmap{
53 getCondition<EcalDetectorMap>(EcalDetectorMap::CONDITIONS_OBJECT_NAME)};
54 for (auto digi : digis) {
55 ldmx::EcalID detid{digi.id()};
56 ldmx::EcalElectronicsID eid{detmap.get(detid)};
57
58 for (std::size_t i_bx{0}; i_bx < digis.getNumSamplesPerDigi(); i_bx++) {
59 sorted_samples[i_bx][eid.fiber()][eid.elink()][eid.channel()] =
60 digi.at(i_bx).raw();
61 }
62 }
63
74 std::vector<uint32_t> buffer;
75 // word to use for constructing buffer
76 static uint32_t word;
77 uint32_t i_bx{0};
78 for (auto const& bunch : sorted_samples) {
83 uint32_t bunch_id = event.getEventNumber();
84 uint32_t rreq = i_bx;
85 uint32_t orbit = event.getEventHeader().getRun();
86
87 // bunch lists the fpgs, links, and channels with their corresponding sample
88 for (auto const& [fpga_id, links] : bunch) {
100 std::vector<uint32_t> link_lengths;
101 for (auto const& [link_id, channels] : links) {
102 link_lengths.push_back(3 + 1 + channels.size() + 1);
103 }
104
115 uint32_t n_linkwords =
116 link_lengths.size() / 4 + (link_lengths.size() % 4 != 0);
117 uint32_t total_length{2 + n_linkwords + 1};
118 for (uint32_t const& link_len : link_lengths) {
119 total_length += link_len;
120 }
121
122 packing::utility::CRC fpga_crc;
138 word = 0;
139
140 word |= (1 << (12 + 1 + 6 + 8)); // version
141 word |= (fpga_id & packing::utility::mask<8>) << (12 + 1 + 6); // FPGA
142 word |= (links.size() & packing::utility::mask<6>) << (12 + 1); // NLINKS
143 word |= (total_length & packing::utility::mask<12>); // LEN TODO
144 buffer.push_back(word);
145 fpga_crc << word;
146
147 word = 0;
148 word |= (bunch_id & packing::utility::mask<12>) << 20; // BX ID
149 word |= (rreq & packing::utility::mask<10>) << 10; // RREQ
150 word |= (orbit & packing::utility::mask<10>); // OR
151 buffer.push_back(word);
152 fpga_crc << word;
153
157 for (uint32_t i_linkword{0}; i_linkword < n_linkwords; i_linkword++) {
158 word = 0;
159 for (uint32_t i_linklen{0}; i_linklen < 4; i_linklen++) {
160 uint32_t i_link = 4 * i_linkword + i_linklen;
161 if (i_link <= link_lengths.size()) {
162 // we have a link
163 word |= (((0b11 << 6) +
164 (link_lengths.at(i_link) & packing::utility::mask<6>))
165 << 8 * i_linklen);
166 } // do we have a link for this linklen subword?
167 } // loop through subwords in this word
168 buffer.push_back(word);
169 fpga_crc << word;
170 } // loop through words
171
172 // fpga lists the links and channels with their corresponding sample
173 for (auto const& [link_id, channels] : links) {
177 std::bitset<40> ro_map; // starts as all 0s
178 ro_map.set(0); // special "header" word from ROC
179 ro_map.set(39); // trailing checksum from ROC
180 // each link maps the channels that were readout to their sample
181 for (auto const& [channel, sample] : channels) {
182 ro_map.set(channel);
183 }
184
185 packing::utility::CRC link_crc;
195 word = 0;
196 word |= (link_id & packing::utility::mask<16>) << 16;
197 word |= 1 << 15;
198 // put first 8bits of RO Map in first header word
199 word |= (ro_map >> 32).to_ulong();
200
201 buffer.push_back(word);
202 fpga_crc << word;
203 link_crc << word;
204
205 // next header word is end of RO map
206 word = (ro_map.to_ulong() & 0xFFFFFFFF);
207 buffer.push_back(word);
208 fpga_crc << word;
209 link_crc << word;
210
211 // special "header" word from ROC
212 word = 0;
213 word |= 0b0101 << 28;
214 word |= (bunch_id & packing::utility::mask<12>) << 16;
215 word |= (rreq & packing::utility::mask<6>) << 10;
216 word |= (orbit & packing::utility::mask<3>) << 7;
217 // skipping hamming error bits because we will set them all to false
218 // here
219 word |= 0b0101;
220 buffer.push_back(word);
221 fpga_crc << word;
222 link_crc << word;
223
232 // put samples into buffer
233 for (auto const& [channel, sample] : channels) {
234 buffer.push_back(sample);
235 fpga_crc << sample;
236 link_crc << sample;
237 }
238 buffer.push_back(link_crc.get());
239 fpga_crc << link_crc.get();
240 }
241 }
242 i_bx++;
243 }
244
245 event.add(output_name_, buffer);
246
247 return;
248} // produce
249
250} // namespace ecal
251
252DECLARE_PRODUCER_NS(ecal, EcalRawEncoder);
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_NS(NS, 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
Implements an event buffer system for storing event data.
Definition Event.h:41
Class which represents the process under execution.
Definition Process.h:36
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
RawValue raw() const
Definition DetectorID.h:68
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:50
uint32_t get()
Get the calculate checksum from the calculator.
Definition CRC.h:110