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