Process the event and put new data products into it.
85 {
86 ldmx_log(debug) << "ZCCMDecoder: produce() starts! Event number: "
87 << event.getEventHeader().getEventNumber();
88
89
90 int n_samp = n_samples_;
91 ldmx_log(debug) << "num samples = " << n_samp;
92
93 ldmx_log(debug) << "Looking up input collection " << input_collection_ << "_"
94 << input_pass_name_;
95 const auto event_output{
96 event.getCollection<uint8_t>(input_collection_, input_pass_name_)};
97 ldmx_log(debug) << "Got input collection " << input_collection_ << "_"
98 << input_pass_name_;
99
100
101
102 uint32_t time_stamp = 0;
103 for (int i_w = 0; i_w < ZCCMOutput::TIMESTAMP_LEN_BYTES; i_w++) {
104 int pos = ZCCMOutput::TIMESTAMP_POS + i_w;
105 uint8_t time_word = event_output.at(pos);
106 ldmx_log(debug) << "time stamp word at position " << pos
107 << " (with iW = " << i_w
108 << ") = " << std::bitset<8>(time_word);
109 time_stamp |= (time_word << i_w * 8);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 event.getEventHeader().setIntParameter("time_stamp_", time_stamp);
128 TTimeStamp *ttime_stamp = new TTimeStamp(time_stamp);
129 event.getEventHeader().setTimestamp(
130 *ttime_stamp);
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 std::map<int, std::vector<int>> adc_map;
148 std::map<int, std::vector<int>> tdc_map;
149 std::map<int, std::vector<int>> cid_map;
150 std::map<int, std::vector<int>> bc0_map;
151 std::map<int, std::vector<int>> ce_map;
152
153 std::vector<std::vector<trigscint::TrigScintQIEDigis>> out_digis;
154 std::size_t n_modules =
155 std::ranges::count_if(modules_used_, [](int x) { return x != 0; });
156
157 out_digis.resize(n_modules);
158
159
160
161 int word_length = ZCCMOutput::SAMPLE_WORD_LEN_BYTES;
162 int num_messages =
163 ((int)event_output.size() - ZCCMOutput::EVENTDATA_POS) / word_length;
164
165
166
167 int n_lanes = n_channels_ / ZCCMOutput::NUM_CHAN_PER_LANE;
168 int num_expected_messages = n_samp * n_lanes;
169 if (num_messages != num_expected_messages)
170 ldmx_log(warn) << "Unexpected stream length! Num messages is "
171 << num_messages << ", expect " << num_expected_messages;
172
173
174
175 int i_word = 0;
176 int start_lane = -1;
177 int sample_nb = -1;
178
179 while (i_word < num_messages) {
180 uint word_pos = ZCCMOutput::EVENTDATA_POS + i_word * word_length;
181
182 uint16_t empty =
183 event_output.at(word_pos + ZCCMOutput::EMPTY_WORD_SAMPLE_WORD_POS);
184 uint8_t lane = event_output.at(word_pos + ZCCMOutput::LANE_SAMPLE_WORD_POS);
185 uint8_t flag =
186 event_output.at(word_pos + ZCCMOutput::FLAGS_SAMPLE_WORD_POS);
187
188 ldmx_log(debug) << "Start of message " << i_word << ".\n\tEmpty word is "
189 << std::bitset<16>(empty) << ", read at position "
190 << word_pos + ZCCMOutput::EMPTY_WORD_SAMPLE_WORD_POS
191 << ". \n\tFlag word is " << std::bitset<8>(flag)
192 << ", read at position "
193 << word_pos + ZCCMOutput::FLAGS_SAMPLE_WORD_POS
194 << ". \n\tLane is " << std::bitset<8>(lane)
195 << ", read at position "
196 << word_pos + ZCCMOutput::LANE_SAMPLE_WORD_POS << ".";
197
198 if (start_lane == -1) {
199 start_lane = lane;
200 ldmx_log(debug) << "Set time sample start lane to " << start_lane;
201 }
202
203 int cid{(flag >> ZCCMOutput::CAPID_POS_IN_FLAG) &
205 ldmx_log(trace) << "Got Cap ID " << cid;
206 bool bc0{static_cast<bool>((flag >> ZCCMOutput::BC0_POS_IN_FLAG) &
208 ldmx_log(trace) << "Got BC0 flag " << bc0;
209 bool ce{static_cast<bool>((flag >> ZCCMOutput::CE_POS_IN_FLAG) &
211 ldmx_log(trace) << "Got CE flag " << ce;
212 int empty_bits{(flag >> ZCCMOutput::EMPTY_FLAG_WORD_POS_IN_FLAG) &
214 if (empty_bits)
215 ldmx_log(fatal) << "Empty bits of flag not empty: " << empty_bits;
216
217
218
219
220
221
222
223
224
225
226
227
228
229 if (lane == start_lane)
230 sample_nb++;
231
232 uint8_t cid_val = cid;
233
234
235 for (int i_c = 0; i_c < ZCCMOutput::NUM_CHAN_PER_LANE; i_c++) {
236 if (i_word >= num_expected_messages) {
237 ldmx_log(fatal)
238 << "More words than expected! Breaking event data loop in sample "
239 << sample_nb << " at lane = " << lane << ", channel nb " << i_c;
240 break;
241 }
242 uint8_t adc_val =
243 event_output.at(word_pos + ZCCMOutput::ADC_SAMPLE_WORD_POS + i_c);
244 uint8_t tdc_val =
245 event_output.at(word_pos + ZCCMOutput::TDC_SAMPLE_WORD_POS + i_c);
246
247
248 int module = module_map_[lane];
249 int elec_id = 100 * lane + 10 * module + i_c;
250
251 ldmx_log(trace) << "got ADC value " << (unsigned)adc_val
252 << " and TDC value " << (unsigned)tdc_val
253 << " at channel idx " << i_c << " with elec id "
254 << elec_id;
255 if (adc_map.find(elec_id) == adc_map.end()) {
256 std::vector<int> adcs(n_samp, 0);
257 adc_map.insert(std::pair<int, std::vector<int>>(elec_id, adcs));
258 }
259 adc_map[elec_id].at(sample_nb) = adc_val;
260
261
262 if (tdc_map.find(elec_id) == tdc_map.end()) {
263 std::vector<int> tdcs(n_samp, 0);
264 tdc_map.insert(std::pair<int, std::vector<int>>(elec_id, tdcs));
265 }
266 tdc_map[elec_id].at(sample_nb) = tdc_val;
267 if (cid_map.find(elec_id) == cid_map.end()) {
268 std::vector<int> cids(n_samp, 0);
269 cid_map.insert(std::pair<int, std::vector<int>>(elec_id, cids));
270 std::vector<int> bc0s(n_samp, 0);
271 bc0_map.insert(std::pair<int, std::vector<int>>(elec_id, bc0s));
272 std::vector<int> ces(n_samp, 0);
273 ce_map.insert(std::pair<int, std::vector<int>>(elec_id, ces));
274 }
275 cid_map[elec_id].at(sample_nb) = cid_val;
276 bc0_map[elec_id].at(sample_nb) = bc0;
277 ce_map[elec_id].at(sample_nb) = ce;
278 }
279 ldmx_log(debug) << "Done with lane " << int(lane) << " which we think is "
280 << i_word % n_lanes << " in sample " << sample_nb;
281
282 if (int(lane) != i_word % n_lanes)
283 ldmx_log(fatal) << "Lane ordering has been messed up! Expect lane "
284 << i_word % n_lanes << ", but we got lane " << int(lane);
285
286 i_word++;
287 }
288
289 ldmx_log(debug) << "Done reading in header, ADC and TDC for event "
290 << event.getEventNumber();
291
292
293
294 for (std::map<int, std::vector<int>>::iterator itr = adc_map.begin();
295 itr != adc_map.end(); ++itr) {
296 TrigScintQIEDigis digi;
297 digi.setADC(itr->second);
298 if (channel_map_.find(itr->first) == channel_map_.end()) {
299 ldmx_log(fatal)
300 << "Couldn't find the bar ID corresponding to electronics ID "
301 << itr->first << "!! Skipping.";
302 continue;
303 }
304 int bar = channel_map_[itr->first];
305 digi.setElecID(itr->first);
306 digi.setChanID(bar);
307 int module = itr->first / 10 % 10;
308 digi.setModuleID(module);
309 int lane = itr->first / 100;
310 digi.setLaneID(lane);
311 digi.setTDC(tdc_map[itr->first]);
312 digi.setCID(cid_map[itr->first]);
313 digi.setBC0(bc0_map[itr->first]);
314 digi.setCE(ce_map[itr->first]);
315 if (bar == 0)
316 ldmx_log(debug) << "for bar 0, got time since spill "
317 << digi.getTimeSinceSpill();
318 out_digis[module].push_back(digi);
319 ldmx_log(debug) << "Iterator points to key " << itr->first
320 << " and mapped channel supposedly is " << bar;
321 ldmx_log(debug) << "Made digi with elecID = " << digi.getElecID()
322 << ", barID = " << digi.getChanID() << ", third adc value "
323 << digi.getADC().at(2) << " and third tdc "
324 << digi.getTDC().at(2);
325 }
326
327
328 for (uint i = 0; i < n_modules; i++)
329 event.
add(output_collection_ + Form(
"%i", i + 1), out_digis[i]);
330}
void add(const std::string &collectionName, T &obj)
Adds an object to the event bus.