LDMX Software
ecal::EcalRawEncoder Class Reference

Public Member Functions

 EcalRawEncoder (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~EcalRawEncoder ()
 Destructor.
 
virtual void configure (framework::config::Parameters &)
 Callback for the EventProcessor to configure itself from the given set of parameters.
 
virtual void produce (framework::Event &event)
 Process the event and put new data products into it.
 
- 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.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
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 Attributes

std::string input_name_
 input object of encoded data
 
std::string input_pass_
 input pass of creating encoded data
 
std::string output_name_
 output object to put onto event bus
 
int roc_version_
 version of HGC ROC we are decoding
 

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

Definition at line 14 of file EcalRawEncoder.h.

Constructor & Destructor Documentation

◆ EcalRawEncoder()

ecal::EcalRawEncoder::EcalRawEncoder ( const std::string & name,
framework::Process & process )

Constructor.

Definition at line 14 of file EcalRawEncoder.cxx.

16 : Producer(name, process) {}
Producer(const std::string &name, Process &process)
Class constructor.
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

◆ ~EcalRawEncoder()

ecal::EcalRawEncoder::~EcalRawEncoder ( )
virtual

Destructor.

Definition at line 18 of file EcalRawEncoder.cxx.

18{}

Member Function Documentation

◆ configure()

void ecal::EcalRawEncoder::configure ( framework::config::Parameters & parameters)
virtual

Callback for the EventProcessor to configure itself from the given set of parameters.

The parameters a processor has access to are the member variables of the python class in the sequence that has class_name equal to the EventProcessor class name.

For an example, look at MyProcessor.

Parameters
parametersParameters for configuration.

Reimplemented from framework::EventProcessor.

Definition at line 20 of file EcalRawEncoder.cxx.

20 {
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}
std::string output_name_
output object to put onto event bus
std::string input_pass_
input pass of creating encoded data
int roc_version_
version of HGC ROC we are decoding
std::string input_name_
input object of encoded data

References framework::config::Parameters::get(), input_name_, input_pass_, output_name_, and roc_version_.

◆ produce()

void ecal::EcalRawEncoder::produce ( framework::Event & event)
virtual

Process the event and put new data products into it.

Parameters
eventThe Event to process.

Static parameters depending on ROC version

Translation

Now the HgcrocDigiCollection::Sample class handles the unpacking of individual samples; however, we still need to translate detector IDs into electronics ID and resort the data into grouped by bunch.

Encoding

Now that the samples are sorted into per-bunch groupings, we can start writing this data into the encoded data format documented in the ECal DAQ specifications. Since the class HgcrocDigiCollection::Sample handles the encoding and decoding of specific sample words, we "only" need to actually encode the header information the calculate the CRC checksums.

TODO calculate bunch ID, read request, and orbit from sample ID, event number, and run number placeholder: bunch ID = event number read request = sample ID orbit = run number

Calculate lengths of link sub-packets

Table 4 of ECal DAQ Specifications.

Each ROC link has 3 header words, a common mode channel, and a trailing CRC checksum word. The 3 header words contain a readout map of which channels are included in the DAQ packet, so we end up with.

len of link = 3 + 1 + channels.size() + 1;

The total FPGA packet includes at least 2 header words, a trailing checksum word, and a single word for each four links.

This means we add up the subpacket lengths into subpacket_total and then

n_linkwords = (nlinks/4+(nlinks%4!=0)) total_length = 2 + n_linkwords + subpacket_total + 1;

Encode Bunch Header We have a few words of header material before the actual data. This header material is assumed to be encoded as in Table 3 of the DAQ specs.

<name> (bits)

VERSION (4) | FPGA_ID (8) | NLINKS (6) | 0 | LEN (12) BX ID (12) | RREQ (10) | OR (10) RID ok (1) | CDC ok (1) | LEN3 (6) | RID ok (1) | CDC ok (1) | LEN2 (6) | RID ok (1) | CDC ok (1) | LEN1 (6) | RID ok (1) | CDC ok (1) | LEN0 (6) ... other listing of links ...

Encode lengths of link subpackets

Prepare RO Map bitset

Encode Each Link in Sequence Now we should be decoding each link serially where each link was encoded as in Table 4 of the DAQ specs

ROC_ID (16) | CRC ok (1) | 00000 | RO Map (8) RO Map (32)

TODO: Common-Mode Channel Somewhere in here is where the common-mode channel would be inserted. I'm not sure if we should expect that the common mode channel also has a sample or it will be reserved and never should have a sample

Implements framework::Producer.

Definition at line 27 of file EcalRawEncoder.cxx.

27 {
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
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.
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

References ecal::EcalDetectorMap::CONDITIONS_OBJECT_NAME, packing::utility::CRC::get(), framework::EventProcessor::getCondition(), input_name_, input_pass_, and output_name_.

Member Data Documentation

◆ input_name_

std::string ecal::EcalRawEncoder::input_name_
private

input object of encoded data

Definition at line 36 of file EcalRawEncoder.h.

Referenced by configure(), and produce().

◆ input_pass_

std::string ecal::EcalRawEncoder::input_pass_
private

input pass of creating encoded data

Definition at line 38 of file EcalRawEncoder.h.

Referenced by configure(), and produce().

◆ output_name_

std::string ecal::EcalRawEncoder::output_name_
private

output object to put onto event bus

Definition at line 40 of file EcalRawEncoder.h.

Referenced by configure(), and produce().

◆ roc_version_

int ecal::EcalRawEncoder::roc_version_
private

version of HGC ROC we are decoding

Definition at line 42 of file EcalRawEncoder.h.

Referenced by configure().


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