LDMX Software
HcalRawDecoder.cxx
1
2
3#include "Hcal/HcalRawDecoder.h"
4
5#include <iomanip>
6
8
9// un comment for HcalRawDecoder-specific debug printouts to std::cout
10// #define DEBUG
11
12namespace hcal {
13
14namespace utility {
15
19class Reader {
20 const std::vector<uint8_t>& buffer_;
21 std::size_t i_word_;
22 uint32_t next() {
23 uint32_t w = buffer_.at(i_word_) | (buffer_.at(i_word_ + 1) << 8) |
24 (buffer_.at(i_word_ + 2) << 16) |
25 (buffer_.at(i_word_ + 3) << 24);
26 i_word_ += 4;
27 return w;
28 }
29
30 public:
31 Reader(const std::vector<uint8_t>& b) : buffer_{b}, i_word_{0} {}
32 operator bool() { return (i_word_ < buffer_.size()); }
33 Reader& operator>>(uint32_t& w) {
34 if (*this) w = next();
35 return *this;
36 }
37}; // Reader
38
39} // namespace utility
40
41namespace debug {
42
43struct Hex {
44 uint32_t word_;
45 Hex(uint32_t w) : word_{w} {}
46};
47
48} // namespace debug
49
50inline std::ostream& operator<<(std::ostream& os, const debug::Hex& h) {
51 os << "0x" << std::setfill('0') << std::setw(8) << std::hex << h.word_
52 << std::dec;
53 return os;
54}
55
61 const std::string& prefix) {
62 {
63 event.add(prefix + "Version", version_);
64 event.add(prefix + "FPGA", fpga_);
65 event.add(prefix + "NSamples", nsamples_);
66 event.add(prefix + "Spill", spill_);
67 event.add(prefix + "Ticks", ticks_);
68 event.add(prefix + "Bunch", bunch_);
69 event.add(prefix + "Number", number_);
70 event.add(prefix + "Run", run_);
71 event.add(prefix + "DD", dd_);
72 event.add(prefix + "MM", month_);
73 event.add(prefix + "hh", hh_);
74 event.add(prefix + "mm", mm_);
75 event.add(prefix + "GoodLinkHeader", good_bxheader_);
76 event.add(prefix + "GoodLinkTrailer", good_trailer_);
77 }
78}
79
81 input_file_ = ps.get<std::string>("input_file");
82 input_names_ = ps.get<std::vector<std::string>>("input_names", {});
83 input_pass_ = ps.get<std::string>("input_pass");
84 output_name_ = ps.get<std::string>("output_name");
85 roc_version_ = ps.get<int>("roc_version");
86 translate_eid_ = ps.get<bool>("translate_eid");
87 read_from_file_ = ps.get<bool>("read_from_file");
88 detector_name_ = ps.get<std::string>("detector_name");
89 if (read_from_file_) {
91 }
92}
93
95 // if we are reading from a file, we need to provide the detector name
96 if (read_from_file_) {
98 }
99}
100
103 std::vector<ldmx::HgcrocDigiCollection::Sample>>
104 eid_to_samples;
106 if (read_from_file_) {
107 if (!file_reader_ or file_reader_.eof()) return;
108 eid_to_samples = this->read(file_reader_, eh);
109 } else {
110 for (const auto& name : input_names_) {
111 hcal::utility::Reader bus_reader(
112 event.getCollection<uint8_t>(name, input_pass_));
113 auto single_pf_samples = this->read(bus_reader, eh);
114 for (const auto& [id, samples] : single_pf_samples) {
115 eid_to_samples[id] = samples;
116 }
117 }
118 }
119
120 eh.board(event, output_name_);
121
123 // assume all channels have same number of samples
124 digis.setNumSamplesPerDigi(eid_to_samples.begin()->second.size());
125 digis.setSampleOfInterestIndex(0); // TODO configurable
127 if (translate_eid_) {
135#ifdef DEBUG
136 std::cout << "Translating EIDs into DetIDs. Printing skipped EIDs..."
137 << std::endl;
138#endif
139 auto detmap{
141 for (auto const& [eid, digi] : eid_to_samples) {
142 // The electronics map returns an empty ID of the correct
143 // type when the electronics ID is not found.
144 // need to check if the electronics ID exists
145 // TODO: do we want to end processing if this happens?
146 if (detmap.exists(eid)) {
147 uint32_t did_raw = detmap.get(eid).raw();
148 digis.addDigi(did_raw, digi);
149 } else {
156#ifdef DEBUG
157 std::cout << "EID(" << eid.fiber() << "," << eid.elink() << ","
158 << eid.channel() << ") ";
159 for (auto& s : digi) std::cout << debug::hex(s.raw()) << " ";
160 std::cout << std::endl;
161#endif
162 }
163 }
164 } else {
172 for (auto const& [eid, digi] : eid_to_samples) {
173 digis.addDigi(eid.raw(), digi);
174 }
175 }
176
177#ifdef DEBUG
178 std::cout << "adding " << digis.getNumDigis() << " digis each with "
179 << digis.getNumSamplesPerDigi() << " samples to event bus"
180 << std::endl;
181#endif
182 event.add(output_name_, digis);
183 return;
184} // produce
185
186} // namespace hcal
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Class which contains logic for how the detector items connect to and relate with the reconstruction c...
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
const std::vector< ContentType > & getCollection(const std::string &collectionName, const std::string &passName) const
Get a collection (std::vector) of objects from the event bus.
Definition Event.h:409
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
static constexpr const char * CONDITIONS_OBJECT_NAME
The name of the EID <-> DetID map for the ECal.
std::string detector_name_
the detector name if we are reading from a file
bool read_from_file_
is the input_name a file or an event object
std::string output_name_
output object to put onto event bus
std::string input_file_
input file of encoded data
void beforeNewRun(ldmx::RunHeader &rh) override
add detector name if we are reading from file
packing::utility::Reader file_reader_
the file reader (if we are doing that)
void configure(framework::config::Parameters &) override
Callback for the EventProcessor to configure itself from the given set of parameters.
std::vector< std::string > input_names_
input object of encoded data
std::map< ldmx::HcalElectronicsID, std::vector< ldmx::HgcrocDigiCollection::Sample > > read(ReaderType &reader, PolarfireEventHeader &eh)
Assume input reader behaves like a binary data input stream where we can "pop" individual 32-bit word...
bool translate_eid_
are get translating electronic IDs?
int roc_version_
version of HGC ROC we are decoding
std::string input_pass_
input pass of creating encoded data
void produce(framework::Event &event) override
use read function to decode data, then translate EIDs into DetIDs
Read out 32-bit words from a 8-bit buffer.
Identifies a location in the Hcal readout chain.
Represents a collection of the digi hits readout by an HGCROC.
unsigned int getNumSamplesPerDigi() const
Get number of samples per digi.
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 getNumDigis() const
Get total number of digis.
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:68
void setDetectorName(const std::string &det)
Set the name of the detector that was used in this run.
Definition RunHeader.h:102
void open(const std::string &file_name)
Open a file with this reader.
Definition Reader.h:36
bool eof()
check if file is done
Definition Reader.h:217
int ticks_
number of 5MHz ticks since spill
int version_
version of daq format
std::vector< bool > good_trailer_
quality of link trailers
int dd_
day of month run started
int number_
event number according to this polarfire
int mm_
minute run started
int fpga_
id for polarfire
int nsamples_
number of samples
int bunch_
bunch number according to this polarfire
void board(framework::Event &event, const std::string &prefix)
board us onto the bus with the input prefix
int hh_
hour run started
int month_
month run started
int run_
run number according to this polarfire
std::vector< bool > good_bxheader_
quality of link headers