Process the event and put new data products into it.
58 {
59 ldmx_log(debug) << "QIEEncoder: produce() starts! Event number: "
60 << event.getEventHeader().getEventNumber();
61
62 std::vector<trigscint::QIEStream> qieOuts;
63 int nSamp = QIEStream::NUM_SAMPLES;
64 std::vector<int> initVec(nSamp, 0);
65 ldmx_log(debug) << "num samples = " << nSamp;
66
67
68
69 for (int iQ = 0; iQ < nChannels_; iQ++) {
70 QIEStream qieOut;
71 qieOut.setADC(initVec);
72 qieOut.setTDC(initVec);
73 qieOut.setCID(initVec);
74 qieOut.setElectronicsID(iQ);
75
76 qieOuts.push_back(qieOut);
77 }
78
79 ldmx_log(debug) << "Looking up input collection " << inputCollection_ << "_"
80 << inputPassName_;
82 inputCollection_, inputPassName_)};
83 ldmx_log(debug) << "Got input collection" << inputCollection_ << "_"
84 << inputPassName_;
85
86 bool isCIDunsync = false;
87
88 bool isCIDskipped = false;
89 bool isCRC0malformed = false;
90 bool isCRC1malformed = false;
91
92 int firstCID = -1;
93 ldmx_log(debug) << "entering loop over digis ";
94 for (auto &digi : digis) {
95 int bar = digi.getChanID();
96 auto itr = channelMap_.find(bar);
97 if (itr == channelMap_.end()) {
98 ldmx_log(fatal) << "Couldn't find an entry for bar " << bar
99 << "; check the (choice of) channel map!. Exiting event "
100 << event.getEventHeader().getEventNumber();
101 return;
102 }
103 int idx = itr->second;
104
105 qieOuts.at(idx).setChannelID(bar);
106 qieOuts.at(idx).setElectronicsID(idx);
107 ldmx_log(debug) << "Channel " << bar << " elec ID "
108 << qieOuts.at(idx).getElectronicsID();
109 std::vector<int> LEtdcs;
110 std::vector<uint8_t> cids;
111 for (int iS = 0; iS < nSamp; iS++) {
112 int tdc = digi.getTDC().at(iS);
113 int cid = digi.getCID().at(iS);
114 if (cids.size() > 0 && (cid % 4) != ((cids.back() + 1) % 4)) {
115
116
117 isCIDskipped = true;
118 }
119 if (verbose_) {
120 std::vector<uint8_t> adcs;
121 int adc = digi.getADC().at(iS);
122 uint8_t mant = adc % 64;
123 uint8_t exp = adc / 64;
124 ldmx_log(debug) << "\tSample " << iS << std::left << std::setw(6)
125 << " ADC " << adc << ",\texp " << unsigned(exp)
126 << " mant " << unsigned(mant) << ",\tTDC = " << tdc
127 << ", LE TDC = " << std::bitset<8>(tdc / 16)
128 << " and capID= " << cid;
129 adcs.push_back(64 * exp + mant);
130 ldmx_log(debug) << "Combined ADC: " << std::showbase
131 << std::bitset<8>(adcs.back()) << " and original adc "
132 << std::bitset<8>(adc) << std::dec;
133 }
134
135 tdc /= 16;
136 LEtdcs.push_back(tdc);
137 cids.push_back((uint8_t)cid);
138 }
139 if (firstCID == -1) {
140
141
142 firstCID = cids.back();
143 }
144 if (firstCID != cids.back()) {
145 isCIDunsync =
146 true;
147 }
148 qieOuts.at(idx).setADC(digi.getADC());
149 qieOuts.at(idx).setTDC(LEtdcs);
150 }
151 if (isCIDunsync) ldmx_log(debug) << "Found unsynced CIDs!";
152 if (isCIDskipped) ldmx_log(info) << "Found skipped CIDs!";
153
154
155
156
157
158
159
160
161
162
163 uint16_t triggerID = event.getEventHeader().getEventNumber();
164 uint8_t randomChecksum =
165 30;
166 uint8_t flags = 0;
167
168 flags |= (isCRC0malformed << QIEStream::CRC0_ERR_POS);
169 flags |= (isCRC1malformed << QIEStream::CRC1_ERR_POS);
170 flags |= (isCIDunsync << QIEStream::CID_UNSYNC_POS);
171 flags |= (isCIDskipped << QIEStream::CID_SKIP_POS);
172 ldmx_log(debug) << "FLAGS: " << std::bitset<8>(flags);
173
174 std::vector<uint8_t> outWord;
175 std::vector<uint8_t> triggerIDwords;
176 for (int iW = QIEStream::TRIGID_LEN_BYTES - 1; iW >= 0; iW--) {
177
178 uint8_t tIDword = triggerID >> iW * 8;
179 triggerIDwords.push_back(tIDword);
180 outWord.push_back(tIDword);
181 }
182
183 outWord.push_back(flags);
184 outWord.push_back(randomChecksum);
185
186 if (verbose_) {
187 std::cout << "header word ";
188 for (auto word : outWord) std::cout << std::bitset<8>(word) << " ";
189 std::cout << std::endl;
190 }
191
192
193
194 for (int iS = 0; iS < nSamp; iS++) {
195 for (int iQ = 0; iQ < nChannels_; iQ++) {
196 outWord.push_back(qieOuts.at(iQ).getADC().at(iS));
197 }
198 for (int iQ = 0; iQ < nChannels_; iQ++) {
199 outWord.push_back(qieOuts.at(iQ).getTDC().at(iS));
200 }
201 }
202
203
204 if (verbose_) {
205 std::cout << "total word ";
206 int widx = 0;
207 int iWstart =
208 std::max(std::max(QIEStream::ERROR_POS, QIEStream::CHECKSUM_POS),
209 QIEStream::TRIGID_POS + (QIEStream::TRIGID_LEN_BYTES)) +
210 1;
211 for (auto word : outWord) {
212 if ((widx - iWstart) % nChannels_ == 0) {
213 int sample = (widx - iWstart) / nChannels_;
214 if (sample % 2 == 0)
215 std::cout << "\n sample " << sample / 2 << " | ";
216 else
217 std::cout << "\n TDC: ";
218 }
219 std::cout << (unsigned)word << " ";
220
221
222 widx++;
223 }
224 std::cout << std::endl;
225 }
226
227 event.add(outputCollection_, outWord);
228}
class for storing QIE output