Process the event and put new data products into it.
60 {
61 ldmx_log(debug) << "QIEDecoder: produce() starts! Event number: "
62 << event.getEventHeader().getEventNumber();
63
64
65 int n_samp = n_samples_;
66 ldmx_log(debug) << "num samples = " << n_samp;
67
68 ldmx_log(debug) << "Looking up input collection " << input_collection_ << "_"
69 << input_pass_name_;
70 const auto event_stream{
71 event.getCollection<uint8_t>(input_collection_, input_pass_name_)};
72 ldmx_log(debug) << "Got input collection" << input_collection_ << "_"
73 << input_pass_name_;
74
75 uint32_t time_epoch = 0;
76
77
78 for (int i_w = 0; i_w < QIEStream::TIMESTAMP_LEN_BYTES; i_w++) {
79 int pos = QIEStream::TIMESTAMP_POS + i_w;
80 uint8_t time_word = event_stream.at(pos);
81 ldmx_log(debug) << "time stamp word at position " << pos
82 << " (with iW = " << i_w
83 << ") = " << std::bitset<8>(time_word);
84 time_epoch |= (time_word << i_w * 8);
85 }
86
87 uint32_t time_clock = 0;
88 for (int i_w = 0; i_w < QIEStream::TIMESTAMPCLOCK_LEN_BYTES; i_w++) {
89 int pos = QIEStream::TIMESTAMPCLOCK_POS + i_w;
90 uint8_t time_word = event_stream.at(pos);
91 ldmx_log(debug) << "time stamp ns word at position " << pos
92 << " (with iW = " << i_w
93 << ") = " << std::bitset<8>(time_word);
94 time_clock |= (time_word << i_w * 8);
95 }
96
97 uint32_t time_spill = 0;
98 ldmx_log(debug) << "Before starting, timeSpill = " << time_spill << " ("
99 << std::bitset<64>(time_spill) << ", or, " << std::hex
100 << time_spill << std::dec << ") counts since start of spill";
101
102 for (int i_w = 0; i_w < QIEStream::TIMESINCESPILL_LEN_BYTES; i_w++) {
103 int pos = QIEStream::TIMESINCESPILL_POS + i_w;
104 uint8_t time_word = event_stream.at(pos);
105 ldmx_log(debug) << "time since spill word at position " << pos
106 << " (with iW = " << i_w
107 << ") = " << std::bitset<8>(time_word);
108 time_spill |= (time_word << i_w * 8);
109 }
110 ldmx_log(debug) << "time stamp words are : " << time_epoch << " ("
111 << std::bitset<64>(time_epoch) << ") and " << time_clock
112 << " (" << std::bitset<64>(time_clock)
113 << ") clock ticks, and " << time_spill << " ("
114 << std::bitset<64>(time_spill) << ", or, " << std::hex
115 << time_spill << std::dec << ") counts since start of spill";
116
117 int sig_bits_skip = 6;
118 int divisor = TMath::Power(2, 32 - sig_bits_skip);
119
120
121 time_spill = time_spill % divisor;
122 ldmx_log(debug) << "After taking it mod 2^" << 32 - sig_bits_skip
123 << " (which is " << divisor << ", spill time is "
124 << time_spill;
125 event.getEventHeader().setIntParameter("timeSinceSpill", time_spill);
126
127 TTimeStamp *time_stamp = new TTimeStamp(time_epoch);
128 event.getEventHeader().setTimestamp(*time_stamp);
129
130
131 uint32_t trigger_id = 0;
132
133 for (int i_w = 0; i_w < QIEStream::TRIGID_LEN_BYTES; i_w++) {
134
135 int pos = QIEStream::TRIGID_POS + i_w;
136 uint8_t t_i_dword = event_stream.at(pos);
137 ldmx_log(debug) << "trigger word at position " << pos
138 << " (with iW = " << i_w
139 << ") = " << std::bitset<8>(t_i_dword);
140 trigger_id |= (t_i_dword << i_w * 8);
141 }
142
143
144 ldmx_log(debug) << " got triggerID " << std::bitset<32>(trigger_id);
145
147
148
149 ldmx_log(fatal) << "Got event number mismatch: framework reports "
150 << event.getEventHeader().getEventNumber()
151 << ", stream says " << trigger_id;
152 }
153
154
155
156
157
158
159
160
161
162
163
164 uint8_t flags = event_stream.at(QIEStream::ERROR_POS);
165
166 bool is_ci_dskipped{static_cast<bool>((flags >> QIEStream::CID_SKIP_POS) &
168 bool is_ci_dunsync{static_cast<bool>((flags >> QIEStream::CID_UNSYNC_POS) &
170
171
172
173
174
175
176
177
178
179 uint8_t reference_checksum = 0;
180 int checksum{(flags >> QIEStream::CHECKSUM_POS) &
182
183
184 if (checksum != reference_checksum)
185 ldmx_log(fatal) << "Got checksum mismatch: expected "
186 << (int)reference_checksum << ", stream says " << checksum;
187 if (is_ci_dunsync) ldmx_log(debug) << "Found unsynced CIDs!";
188 if (is_ci_dskipped) ldmx_log(fatal) << "Found skipped CIDs!";
189
190
191 std::vector<trigscint::TrigScintQIEDigis> out_digis;
192 std::map<int, std::vector<int>> ad_cmap;
193 std::map<int, std::vector<int>> td_cmap;
194
195
196
197 int i_wstart =
198 std::max(std::max(QIEStream::ERROR_POS, QIEStream::CHECKSUM_POS),
199 QIEStream::TRIGID_POS + (QIEStream::TRIGID_LEN_BYTES)) +
200 1;
201
202 int n_words = n_samp * n_channels_ * 2 + i_wstart;
203
204
205 int i_word = i_wstart;
206 ldmx_log(debug) << "Event parsing starts at vector idx " << i_wstart
207 << " and nWords = " << n_words;
208
209
210 for (int i_s = 0; i_s < n_samp; i_s++) {
211 for (int i_q = 0; i_q < n_channels_; i_q++) {
212 if (i_word >= n_words) {
213 ldmx_log(fatal)
214 << "More words than expected! Breaking ADC loop in sample " << i_s
215 << " at iQ = " << i_q;
216 break;
217 }
218 uint8_t val = event_stream.at(i_word);
219 if (val > 0) {
220 ldmx_log(debug) << "got ADC value " << (unsigned)val
221 << " at channel (elec) idx " << i_q;
222 if (ad_cmap.find(i_q) == ad_cmap.end()) {
223 std::vector<int> adcs(n_samp, 0);
224 ad_cmap.insert(std::pair<int, std::vector<int>>(i_q, adcs));
225 }
226 ad_cmap[i_q].at(i_s) = val;
227 }
228 i_word++;
229 }
230 for (int i_q = 0; i_q < n_channels_; i_q++) {
231 if (i_word >= n_words) {
232 ldmx_log(debug)
233 << "More words than expected! Breaking TDC loop in sample " << i_s
234 << " at iQ = " << i_q;
235 break;
236 }
237 uint8_t val = event_stream.at(i_word);
238 if (val > 0) {
239
240 ldmx_log(debug) << "got TDC value " << (unsigned)val
241 << " at channel (elec) idx " << i_q;
242 ;
243 if (td_cmap.find(i_q) == td_cmap.end()) {
244 std::vector<int> tdcs(n_samp, 0);
245 td_cmap.insert(std::pair<int, std::vector<int>>(i_q, tdcs));
246 }
247
248
249
250
251
252 td_cmap[i_q].at(i_s) = val;
253 }
254 i_word++;
255 }
256 ldmx_log(debug) << "Done with sample " << i_s;
257 }
258
259 ldmx_log(debug) << "Done reading in header, ADC and TDC for event "
260 << trigger_id;
261 for (std::map<int, std::vector<int>>::iterator itr = ad_cmap.begin();
262 itr != ad_cmap.end(); ++itr) {
263 TrigScintQIEDigis digi;
264 digi.setADC(itr->second);
265 if (channel_map_.find(itr->first) == channel_map_.end()) {
266 ldmx_log(fatal)
267 << "Couldn't find the bar ID corresponding to electronics ID "
268 << itr->first << "!! Skipping.";
269 continue;
270 }
271 int bar = channel_map_[itr->first];
272 digi.setElecID(itr->first);
273 digi.setChanID(bar);
274 digi.setTDC(td_cmap[itr->first]);
275 digi.setTimeSinceSpill(time_spill);
276 if (bar == 0)
277 ldmx_log(debug) << "for bar 0, got time since spill "
278 << digi.getTimeSinceSpill();
279 out_digis.push_back(digi);
280 ldmx_log(debug) << "Iterator points to key " << itr->first
281 << " and mapped channel supposedly is " << bar;
282 ldmx_log(debug) << "Made digi with elecID = " << digi.getElecID()
283 << ", barID = " << digi.getChanID() << ", third adc value "
284 << digi.getADC().at(2) << " and third tdc "
285 << digi.getTDC().at(2);
286 }
287
288 event.add(output_collection_, out_digis);
289}
ldmx::EventHeader & getEventHeader()
Get the event header.