Project
Loading...
Searching...
No Matches
RawDataDecoder.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14#include <fstream>
21#include <boost/range/adaptor/reversed.hpp>
22
23using namespace o2::ctp;
24
25// Inverse of Digits2Raw::makeGBTWord
26void RawDataDecoder::makeGBTWordInverse(std::vector<gbtword80_t>& diglets, gbtword80_t& GBTWord, gbtword80_t& remnant, uint32_t& size_gbt, uint32_t Npld)
27{
28 gbtword80_t diglet = remnant;
29 uint32_t i = 0;
30 while (i < (NGBT - Npld)) {
31 std::bitset<NGBT> masksize = 0;
32 for (uint32_t j = 0; j < (Npld - size_gbt); j++) {
33 masksize[j] = 1;
34 }
35 diglet |= (GBTWord & masksize) << (size_gbt);
36 diglets.push_back(diglet);
37 diglet = 0;
38 i += Npld - size_gbt;
39 GBTWord = GBTWord >> (Npld - size_gbt);
40 size_gbt = 0;
41 }
42 size_gbt = NGBT - i;
43 remnant = GBTWord;
44}
45int RawDataDecoder::addCTPDigit(uint32_t linkCRU, uint32_t orbit, gbtword80_t& diglet, gbtword80_t& pldmask, std::map<o2::InteractionRecord, CTPDigit>& digits)
46{
47 int ret = 0;
48 gbtword80_t pld = (diglet & pldmask);
49 if (pld.count() == 0) {
50 return 0;
51 }
52 pld >>= 12;
53 CTPDigit digit;
54 const gbtword80_t bcidmask = 0xfff;
55 uint16_t bcid = (diglet & bcidmask).to_ulong();
56 LOG(debug) << bcid << " pld:" << pld;
58 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
59 int32_t BCShiftCorrectionInps = -o2::ctp::TriggerOffsetsParam::Instance().globalInputsShift;
60 LOG(debug) << "InputMaskCount:" << digits[ir].CTPInputMask.count();
61 LOG(debug) << "ir ir ori:" << ir;
62 if ((ir.orbit <= mTFOrbit) && ((int32_t)ir.bc < BCShiftCorrectionInps)) {
63 // LOG(warning) << "Loosing ir:" << ir;
64 mIRRejected++;
65 return 0;
66 }
67 ir -= BCShiftCorrectionInps;
68 LOG(debug) << "ir ir corrected:" << ir;
69 digit.intRecord = ir;
70 if (digits.count(ir) == 0) {
71 digit.setInputMask(pld);
72 digits[ir] = digit;
73 LOG(debug) << bcid << " inputs case 0 bcid orbit " << orbit << " pld:" << pld;
74 } else if (digits.count(ir) == 1) {
75 if (digits[ir].CTPInputMask.count() == 0) {
77 LOG(debug) << bcid << " inputs bcid case 1 orbit " << orbit << " pld:" << pld;
78 } else {
79 if (mErrorIR < mErrorMax) {
80 LOG(error) << "Two CTP IRs with the same timestamp:" << ir.bc << " " << ir.orbit << " pld:" << pld << " dig:" << digits[ir];
81 }
82 ret = 4;
83 mErrorIR++;
84 mStickyError = true;
85 }
86 } else {
87 LOG(error) << "Two digits with the same timestamp:" << ir.bc << " " << ir.orbit;
88 ret = 8;
89 }
90 } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) {
93 LOG(debug) << "tcr ir ori:" << ir;
94 if ((ir.orbit <= mTFOrbit) && ((int32_t)ir.bc < offset)) {
95 // LOG(warning) << "Loosing tclass:" << ir;
96 mTCRRejected++;
97 return 0;
98 }
99 ir -= offset;
100 LOG(debug) << "tcr ir corrected:" << ir;
101 digit.intRecord = ir;
102 if (digits.count(ir) == 0) {
103 digit.setClassMask(pld);
104 digits[ir] = digit;
105 LOG(debug) << bcid << " class bcid case 0 orbit " << orbit << " pld:" << pld;
106 } else if (digits.count(ir) == 1) {
107 if (digits[ir].CTPClassMask.count() == 0) {
108 digits[ir].setClassMask(pld);
109 LOG(debug) << bcid << " class bcid case 1 orbit " << orbit << " pld:" << pld;
110 } else {
111 if (mErrorTCR < mErrorMax) {
112 LOG(error) << "Two CTP Class masks for same timestamp";
113 mStickyError = true;
114 }
115 mErrorTCR++;
116 ret = 16;
117 }
118 } else {
119 LOG(error) << "Two digits with the same timestamp:" << ir.bc << " " << ir.orbit;
120 ret = 32;
121 }
122 } else {
123 LOG(error) << "Unxpected CTP CRU link:" << linkCRU;
124 }
125 return ret;
126}
127//
128// Decodes one page
129// It is NOT assumed that CTP HBF has never more than one page.
130// 1 HBF/page <= 8000kB = 8*1024*8/120 = 546 GBT words = 546 IRs/page = 5.5 MHz
131int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec>& filter, o2::pmr::vector<CTPDigit>& digits, std::vector<LumiInfo>& lumiPointsHBF1)
132{
133 int ret = 0;
134 static int nwrites = 0;
135 uint64_t countsMBT = 0;
136 uint64_t countsMBV = 0;
137 std::map<o2::InteractionRecord, CTPDigit> digitsMap;
138 //
139 // using InputSpec = o2::framework::InputSpec;
140 // using ConcreteDataTypeMatcher = o2::framework::ConcreteDataTypeMatcher;
141 // using Lifetime = o2::framework::Lifetime;
142 o2::framework::DPLRawParser parser(inputs, filter);
143 uint32_t payloadCTP = 0;
144 gbtword80_t remnant = 0;
145 uint32_t size_gbt = 0;
146 mTFOrbit = 0;
147 uint32_t orbit0 = 0;
148 for (auto it = parser.begin(); it != parser.end(); ++it) {
149 const o2::header::RDHAny* rdh = nullptr;
150 try {
151 rdh = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
152 mPadding = (o2::raw::RDHUtils::getDataFormat(rdh) == 0);
153 } catch (std::exception& e) {
154 LOG(error) << "Failed to extract RDH, abandoning TF sending dummy output, exception was: " << e.what();
155 // dummyOutput();
156 return 1;
157 }
158 // auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(rdh);
159 uint32_t stopBit = o2::raw::RDHUtils::getStop(rdh);
160 uint32_t packetCounter = o2::raw::RDHUtils::getPageCounter(rdh);
162 uint32_t rdhOrbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdh);
163 uint32_t triggerType = o2::raw::RDHUtils::getTriggerType(rdh);
164 // std::cout << "diff orbits:" << triggerOrbit - rdhOrbit << std::endl;
165 bool tf = (triggerType & TF_TRIGGERTYPE_MASK) && (packetCounter == 0);
166 bool hb = (triggerType & HB_TRIGGERTYPE_MASK) && (packetCounter == 0);
167 if (tf) {
168 mTFOrbit = rdhOrbit;
169 // std::cout << "tforbit==================>" << mTFOrbit << " " << std::hex << mTFOrbit << std::endl;
170 mTFOrbits.push_back(mTFOrbit);
171 }
172 static bool prt = true;
173 if (prt) {
174 LOG(info) << "RDH version:" << version << " Padding:" << mPadding;
175 prt = false;
176 }
177 auto feeID = o2::raw::RDHUtils::getFEEID(rdh); // 0 = IR, 1 = TCR
178 auto linkCRU = (feeID & 0xf00) >> 8;
179 // LOG(info) << "CRU link:" << linkCRU;
180 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
181 payloadCTP = o2::ctp::NIntRecPayload;
182 } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) {
183 payloadCTP = o2::ctp::NClassPayload;
184 if (!mDoDigits) { // Do not do TCR if only lumi
185 continue;
186 }
187 } else {
188 LOG(error) << "Unxpected CTP CRU link:" << linkCRU;
189 }
190 LOG(debug) << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << rdhOrbit << " triggerType:" << triggerType;
191 // LOG(info) << "remnant :" << remnant.count();
192 gbtword80_t pldmask = 0;
193 for (uint32_t i = 0; i < payloadCTP; i++) {
194 pldmask[12 + i] = 1;
195 }
196 // std::cout << (orbit0 != rdhOrbit) << " comp " << (mTFOrbit==rdhOrbit) << std::endl;
197 // if(orbit0 != rdhOrbit) {
198 if (hb) {
199 if ((mDoLumi && payloadCTP == o2::ctp::NIntRecPayload) && !tf) { // create lumi per HB
200 lumiPointsHBF1.emplace_back(LumiInfo{rdhOrbit, 0, 0, countsMBT, countsMBV});
201 // std::cout << "hb:" << nhb << " countsMBT:" << countsMBT << std::endl;
202 countsMBT = 0;
203 countsMBV = 0;
204 // nhb++;
205 }
206 remnant = 0;
207 size_gbt = 0;
208 orbit0 = rdhOrbit;
209 // std::cout << "orbit0============>" << std::dec << orbit0 << " " << std::hex << orbit0 << std::endl;
210 }
211 // Create 80 bit words
212 gsl::span<const uint8_t> payload(it.data(), it.size());
213 gbtword80_t gbtWord80;
214 gbtWord80.set();
215 int wordCount = 0;
216 int wordSize = 10;
217 std::vector<gbtword80_t> gbtwords80;
218 // mPadding = 0;
219 if (mPadding == 1) {
220 wordSize = 16;
221 }
222 // LOG(info) << ii << " payload size:" << payload.size();
223 /* if (payload.size()) {
224 //LOG(info) << "payload size:" << payload.size();
225 // LOG(info) << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << triggerOrbit << " stopbit:" << stopBit << " packet:" << packetCounter;
226 // LOGP(info, "RDH FEEid: {} CRU link: {}, Orbit: {}", feeID, linkCRU, triggerOrbit);
227 std::cout << std::hex << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << rdhOrbit << std::endl;
228 } */
229 gbtword80_t bcmask = std::bitset<80>("111111111111");
230 for (auto payloadWord : payload) {
231 int wc = wordCount % wordSize;
232 // LOG(info) << wordCount << ":" << wc << " payload:" << int(payloadWord);
233 if ((wc == 0) && (wordCount != 0)) {
234 if (gbtWord80.count() != 80) {
235 gbtwords80.push_back(gbtWord80);
236 }
237 gbtWord80.set();
238 }
239 if (wc < 10) {
240 for (int i = 0; i < 8; i++) {
241 gbtWord80[wc * 8 + i] = bool(int(payloadWord) & (1 << i));
242 }
243 }
244 wordCount++;
245 }
246 if ((gbtWord80.count() != 80) && (gbtWord80.count() > 0)) {
247 gbtwords80.push_back(gbtWord80);
248 }
249 // decode 80 bits payload
250 for (auto word : gbtwords80) {
251 std::vector<gbtword80_t> diglets;
252 gbtword80_t gbtWord = word;
253 makeGBTWordInverse(diglets, gbtWord, remnant, size_gbt, payloadCTP);
254 for (auto diglet : diglets) {
255 if (mDoLumi && payloadCTP == o2::ctp::NIntRecPayload) {
256 gbtword80_t pld = (diglet >> 12) & mTVXMask;
257 if (pld.count() != 0) {
258 countsMBT++;
259 }
260 pld = (diglet >> 12) & mVBAMask;
261 if (pld.count() != 0) {
262 countsMBV++;
263 }
264 }
265 if (!mDoDigits) {
266 continue;
267 }
268 LOG(debug) << "diglet:" << diglet << " " << (diglet & bcmask).to_ullong();
269 ret = addCTPDigit(linkCRU, rdhOrbit, diglet, pldmask, digitsMap);
270 }
271 }
272 if ((remnant.count() > 0) && stopBit) {
273 if (mDoLumi && payloadCTP == o2::ctp::NIntRecPayload) {
274 gbtword80_t pld = (remnant >> 12) & mTVXMask;
275 if (pld.count() != 0) {
276 countsMBT++;
277 }
278 pld = (remnant >> 12) & mVBAMask;
279 if (pld.count() != 0) {
280 countsMBV++;
281 }
282 }
283 if (!mDoDigits) {
284 continue;
285 }
286 ret = addCTPDigit(linkCRU, rdhOrbit, remnant, pldmask, digitsMap);
287 LOG(debug) << "diglet:" << remnant << " " << (remnant & bcmask).to_ullong();
288 remnant = 0;
289 }
290 }
291 if (mDoLumi) {
292 lumiPointsHBF1.emplace_back(LumiInfo{orbit0, 0, 0, countsMBT, countsMBV});
293 // std::cout << "last lumi:" << nhb << std::endl;
294 }
295 if (mDoDigits & mDecodeInps) {
296 uint64_t trgclassmask = 0xffffffffffffffff;
297 uint64_t trgclassmaskNOTRGDet = 0xffffffffffffffff;
298 if (mCTPConfig.getRunNumber() != 0) {
299 trgclassmask = mCTPConfig.getTriggerClassMaskWInputs();
300 trgclassmaskNOTRGDet = mCTPConfig.getTriggerClassMaskWInputsNoTrgDets();
301 // mCTPConfig.printStream(std::cout);
302 }
303 // std::cout << "trgclassmask:" << std::hex << trgclassmask << std::dec << std::endl;
304 ret = shiftInputs(digitsMap, digits, mTFOrbit);
305 if (mCheckConsistency) {
306 ret = checkReadoutConsistentncy(digits, trgclassmask, trgclassmaskNOTRGDet);
307 }
308 }
309 if (mDoDigits && !mDecodeInps) {
310 for (auto const& dig : digitsMap) {
311 digits.push_back(dig.second);
312 }
313 }
314 // ret = 1;
315 if (mStickyError) {
316 if (nwrites < mErrorMax) {
317 std::string file = "dumpCTP" + std::to_string(nwrites) + ".bin";
318 std::ofstream dumpctp(file.c_str(), std::ios::out | std::ios::binary);
319 if (!dumpctp.good()) {
320 LOGP(error, "Failed to open file {}", file);
321 } else {
322 LOGP(info, "CTP dump file open {}", file);
323 for (auto it = parser.begin(); it != parser.end(); ++it) {
324 char* dataout = (char*)(it.raw());
325 dumpctp.write(dataout, it.sizeTotal());
326 }
327 dumpctp.close();
328 }
329 nwrites++;
330 }
331 // LOG(error) << "CTP decoding IR errors:" << mErrorIR << " TCR errors:" << mErrorTCR;
332 }
333 return ret;
334}
335//
336int RawDataDecoder::decodeRawFatal(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec>& filter)
337{
338 o2::framework::DPLRawParser parser(inputs, filter);
339 uint32_t payloadCTP = 0;
340 gbtword80_t remnant = 0;
341 uint32_t size_gbt = 0;
342 mTFOrbit = 0;
343 uint32_t orbit0 = 0;
344 std::array<int, o2::ctp::CTP_NCLASSES> rates{};
345 std::array<int, o2::ctp::CTP_NCLASSES> ratesC{};
346 for (auto it = parser.begin(); it != parser.end(); ++it) {
347 const o2::header::RDHAny* rdh = nullptr;
348 try {
349 rdh = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
350 mPadding = (o2::raw::RDHUtils::getDataFormat(rdh) == 0);
351 } catch (std::exception& e) {
352 LOG(error) << "Failed to extract RDH, abandoning TF sending dummy output, exception was: " << e.what();
353 // dummyOutput();
354 return 1;
355 }
356 // auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(rdh);
357 uint32_t stopBit = o2::raw::RDHUtils::getStop(rdh);
358 uint32_t packetCounter = o2::raw::RDHUtils::getPageCounter(rdh);
360 uint32_t rdhOrbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdh);
361 uint32_t triggerType = o2::raw::RDHUtils::getTriggerType(rdh);
362 // std::cout << "diff orbits:" << triggerOrbit - rdhOrbit << std::endl;
363 bool tf = (triggerType & TF_TRIGGERTYPE_MASK) && (packetCounter == 0);
364 bool hb = (triggerType & HB_TRIGGERTYPE_MASK) && (packetCounter == 0);
365 if (tf) {
366 mTFOrbit = rdhOrbit;
367 // std::cout << "tforbit==================>" << mTFOrbit << " " << std::hex << mTFOrbit << std::endl;
368 mTFOrbits.push_back(mTFOrbit);
369 }
370 static bool prt = true;
371 if (prt) {
372 LOG(info) << "RDH version:" << version << " Padding:" << mPadding;
373 prt = false;
374 }
375 auto feeID = o2::raw::RDHUtils::getFEEID(rdh); // 0 = IR, 1 = TCR
376 auto linkCRU = (feeID & 0xf00) >> 8;
377 // LOG(info) << "CRU link:" << linkCRU;
378 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
379 payloadCTP = o2::ctp::NIntRecPayload;
380 } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) {
381 payloadCTP = o2::ctp::NClassPayload;
382 } else {
383 LOG(error) << "Unxpected CTP CRU link:" << linkCRU;
384 }
385 LOG(debug) << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << rdhOrbit << " triggerType:" << triggerType;
386 // LOG(info) << "remnant :" << remnant.count();
387 gbtword80_t pldmask = 0;
388 for (uint32_t i = 0; i < payloadCTP; i++) {
389 pldmask[12 + i] = 1;
390 }
391 // std::cout << (orbit0 != rdhOrbit) << " comp " << (mTFOrbit==rdhOrbit) << std::endl;
392 // if(orbit0 != rdhOrbit) {
393 if (hb) {
394 remnant = 0;
395 size_gbt = 0;
396 orbit0 = rdhOrbit;
397 // std::cout << "orbit0============>" << std::dec << orbit0 << " " << std::hex << orbit0 << std::endl;
398 }
399 // Create 80 bit words
400 gsl::span<const uint8_t> payload(it.data(), it.size());
401 gbtword80_t gbtWord80;
402 gbtWord80.set();
403 int wordCount = 0;
404 int wordSize = 10;
405 std::vector<gbtword80_t> gbtwords80;
406 // mPadding = 0;
407 if (mPadding == 1) {
408 wordSize = 16;
409 }
410 // LOG(info) << ii << " payload size:" << payload.size();
411 gbtword80_t bcmask = std::bitset<80>("111111111111");
412 for (auto payloadWord : payload) {
413 int wc = wordCount % wordSize;
414 // LOG(info) << wordCount << ":" << wc << " payload:" << int(payloadWord);
415 if ((wc == 0) && (wordCount != 0)) {
416 if (gbtWord80.count() != 80) {
417 gbtwords80.push_back(gbtWord80);
418 }
419 gbtWord80.set();
420 }
421 if (wc < 10) {
422 for (int i = 0; i < 8; i++) {
423 gbtWord80[wc * 8 + i] = bool(int(payloadWord) & (1 << i));
424 }
425 }
426 wordCount++;
427 }
428 if ((gbtWord80.count() != 80) && (gbtWord80.count() > 0)) {
429 gbtwords80.push_back(gbtWord80);
430 }
431 // decode 80 bits payload
432 for (auto word : gbtwords80) {
433 std::vector<gbtword80_t> diglets;
434 gbtword80_t gbtWord = word;
435 makeGBTWordInverse(diglets, gbtWord, remnant, size_gbt, payloadCTP);
436 for (auto diglet : diglets) {
437 int nbits = payloadCTP - 12;
438 for (int i = 0; i < nbits; i++) {
439 gbtword80_t mask = 1ull << i;
440 gbtword80_t pld = (diglet >> 12) & mask;
441 // LOG(info) << "diglet:" << diglet << " pld:" << pld;
442 if (pld.count() != 0) {
443 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
444 rates[i]++;
445 } else {
446 ratesC[i]++;
447 }
448 }
449 }
450 // LOG(debug) << "diglet:" << diglet << " " << (diglet & bcmask).to_ullong();
451 }
452 }
453 if ((remnant.count() > 0) && stopBit) {
454 int nbits = payloadCTP - 12;
455 for (int i = 0; i < nbits; i++) {
456 gbtword80_t mask = 1ull << i;
457 gbtword80_t pld = (remnant >> 12) & mask;
458 // LOG(info) << "diglet:" << remnant << " pld:" << pld;
459 if (pld.count() != 0) {
460 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
461 rates[i]++;
462 } else {
463 ratesC[i]++;
464 }
465 }
466 }
467 remnant = 0;
468 }
469 }
470 // print max rates
471 std::map<int, int> ratesmap;
472 std::map<int, int> ratesmapC;
473 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
474 if (rates[i]) {
475 ratesmap[rates[i]] = i;
476 }
477 if (ratesC[i]) {
478 ratesmapC[ratesC[i]] = i;
479 }
480 }
482 std::string message = "Ringing inputs [MHz]:";
483 for (auto const& r : boost::adaptors::reverse(ratesmap)) {
484 // LOG(error) << r.second;
486 }
487 std::string messageC = "Ringing classes [MHz]:";
488 for (auto const& r : boost::adaptors::reverse(ratesmapC)) {
489 messageC += " class" + std::to_string(r.second) + ":" + std::to_string(r.first / 32. / o2::constants::lhc::LHCOrbitMUS);
490 }
491 LOG(error) << messageC;
492 LOG(fatal) << message;
493 return 0;
494}
495//
496int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec>& filter, std::vector<CTPDigit>& digits, std::vector<LumiInfo>& lumiPointsHBF1)
497{
499 int ret = decodeRaw(inputs, filter, pmrdigits, lumiPointsHBF1);
500 for (auto const d : pmrdigits) {
501 digits.push_back(d);
502 }
503 return ret;
504}
505//
506// Not to be called with level LM
507// Keeping shift in params if needed to be generalised
508int RawDataDecoder::shiftNew(const o2::InteractionRecord& irin, uint32_t TFOrbit, std::bitset<48>& inpmask, int64_t shift, int level, std::map<o2::InteractionRecord, CTPDigit>& digmap)
509{
510 //
511 if (irin.orbit > TFOrbit || irin.bc >= shift) {
512 auto lxmask = L0MASKInputs;
513 if (level == 1) {
514 lxmask = L1MASKInputs;
515 }
516 auto ir = irin - shift; // add L0 to prev digit
517 if (digmap.count(ir)) {
518 if ((digmap[ir].CTPInputMask & lxmask).count()) {
519 LOG(error) << " Overwriting LX ? X:" << level;
520 }
521 digmap[ir].CTPInputMask = digmap[ir].CTPInputMask | (inpmask & lxmask);
522 } else {
523 CTPDigit digit = {ir, inpmask & lxmask, 0};
524 digmap[ir] = digit;
525 }
526 } else {
527 LOG(info) << "LOST:" << irin << " shift:" << shift;
528 }
529 return 0;
530}
531//
532
533int RawDataDecoder::shiftInputs(std::map<o2::InteractionRecord, CTPDigit>& digitsMap, o2::pmr::vector<CTPDigit>& digits, uint32_t TFOrbit, uint64_t trgclassmask)
534{
535 // int nClasswoInp = 0; // counting classes without input which should never happen
536 std::map<o2::InteractionRecord, CTPDigit> digitsMapShifted;
538 auto L1shift = L0shift + o2::ctp::TriggerOffsetsParam::Instance().L0_L1;
539 for (auto const& dig : digitsMap) {
540 auto inpmask = dig.second.CTPInputMask;
541 auto inpmaskLM = inpmask & LMMASKInputs;
542 auto inpmaskL0 = inpmask & L0MASKInputs;
543 auto inpmaskL1 = inpmask & L1MASKInputs;
544 int lm = inpmaskLM.count() > 0;
545 int l0 = inpmaskL0.count() > 0;
546 int l1 = inpmaskL1.count() > 0;
547 int lut = lm + (l0 << 1) + (l1 << 2);
548 // std::cout << "L0mask:" << L0MASKInputs << std::endl;
549 // std::cout << "L0:" << inpmaskL0 << std::endl;
550 // std::cout << "L1:" << inpmaskL1 << std::endl;
551 if (lut == 0 || lut == 1) { // no inps or LM
552 digitsMapShifted[dig.first] = dig.second;
553 } else if (lut == 2) { // L0
554 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
555 if (dig.second.CTPClassMask.count()) {
556 // LOG(error) << "Adding class mask without input ?";
557 // This is not needed as it can happen; Full checj done below - see next LOG(error)
558 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
559 digitsMapShifted[dig.first] = digi;
560 }
561 } else if (lut == 4) { // L1
562 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
563 if (dig.second.CTPClassMask.count()) {
564 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
565 digitsMapShifted[dig.first] = digi;
566 }
567 } else if (lut == 6) { // L0 and L1
568 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
569 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
570 if (dig.second.CTPClassMask.count()) {
571 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
572 digitsMapShifted[dig.first] = digi;
573 }
574 } else if (lut == 3) { // LM and L0
575 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
576 CTPDigit digi = {dig.first, inpmask & (~L0MASKInputs), dig.second.CTPClassMask};
577 // if LM level do not need to add class as LM is not shifted;
578 digitsMapShifted[dig.first] = digi;
579 } else if (lut == 5) { // LM and L1
580 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
581 CTPDigit digi = {dig.first, inpmask & (~L1MASKInputs), dig.second.CTPClassMask};
582 digitsMapShifted[dig.first] = digi;
583 } else if (lut == 7) { // LM and L0 and L1
584 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
585 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
586 CTPDigit digi = {dig.first, inpmaskLM, dig.second.CTPClassMask};
587 digitsMapShifted[dig.first] = digi;
588 } else {
589 LOG(fatal) << "lut = " << lut;
590 }
591 }
592 for (auto const& dig : digitsMapShifted) {
593 digits.push_back(dig.second);
594 }
595 return 0;
596}
597//
598int RawDataDecoder::checkReadoutConsistentncy(o2::pmr::vector<CTPDigit>& digits, uint64_t trgclassmask, uint64_t trgclassmaskNoTrgDet)
599{
600 LOG(debug) << "Checking readout";
601 int ret = 0;
602 static int nerror = 0;
603 for (auto const& digit : digits) {
604 // if class mask => inps
605 for (int i = 0; i < digit.CTPClassMask.size(); i++) {
606 bool trgcls = trgclassmask & (1ull << i);
607 if (digit.CTPClassMask[i] & trgcls) {
608 const CTPClass* cls = mCTPConfig.getCTPClassFromHWIndex(i);
609 if (cls == nullptr) {
610 if (nerror < mErrorMax) {
611 LOG(error) << "Class mask index not found in CTP config:" << i;
612 nerror++;
613 }
614 ret = 128;
615 continue;
616 }
617 mClassCountersA[i]++;
618 if (cls->descriptor == nullptr) {
619 continue;
620 }
621 uint64_t clsinpmask = cls->descriptor->getInputsMask();
622 uint64_t diginpmask = digit.CTPInputMask.to_ullong();
623 if (!((clsinpmask & diginpmask) == clsinpmask)) {
624 if (nerror < mErrorMax) {
625 LOG(error) << "Cls=>Inps: CTP class:" << cls->name << " inpmask:" << clsinpmask << " not compatible with inputs mask:" << diginpmask;
626 nerror++;
627 }
628 mClassErrorsA[i]++;
629 ret = 128;
630 }
631 }
632 }
633 // if inps => class mask
634 for (auto const& cls : mCTPConfig.getCTPClasses()) {
635 // cls.printStream(std::cout);
636 if (cls.descriptor == nullptr) {
637 continue;
638 }
639 uint64_t clsinpmask = cls.descriptor->getInputsMask(); // class definition
640 uint64_t diginpmask = digit.CTPInputMask.to_ullong();
641 uint64_t digclsmask = digit.CTPClassMask.to_ullong();
642 if ((clsinpmask & diginpmask) == clsinpmask) {
643 if (cls.classMask & trgclassmask) {
644 mClassCountersB[cls.getIndex()]++;
645 if ((cls.classMask & digclsmask) == 0) {
649 if (digit.intRecord.bc < offset) {
650 if ((nerror < mErrorMax) && (cls.classMask & ~trgclassmaskNoTrgDet)) {
651 LOG(info) << "Inp=>Cls: CTP class:" << cls.name << " inpmask:" << clsinpmask << " cls mask:" << cls.classMask << " not found in digit:" << digit;
652 nerror++;
653 }
654 mClassErrorsB[cls.getIndex()]++;
655 ret = 256;
656 } else {
657 mLostDueToShift++;
658 }
659 }
660 }
661 }
662 }
663 }
664 if (mLostDueToShift) {
665 LOG(debug) << "LOST classes because of shift:" << mLostDueToShift;
666 }
667 return ret;
668}
669//
670int RawDataDecoder::setLumiInp(int lumiinp, std::string inp)
671{
672 // check if valid input
674 if (index == 0xff) {
675 LOG(fatal) << "CTP raw decoder: input index not found:" << inp;
676 return 0xff;
677 }
678 if (lumiinp == 1) {
679 mTVXMask.reset();
680 mTVXMask[index - 1] = true;
681 } else {
682 mVBAMask.reset();
683 mVBAMask[index - 1] = true;
684 }
685 return index;
686}
687//
689{
690 return 0;
691}
A raw page parser for DPL input.
definition of CTPConfiguration and related CTP structures
uint64_t orbit
Definition RawEventData.h:6
int32_t i
Helper for geometry and GRP related CCDB requests.
Digits tw Raw translation.
uint32_t j
Definition RawData.h:0
uint32_t version
Definition RawData.h:8
std::ostringstream debug
std::vector< CTPClass > & getCTPClasses()
uint64_t getTriggerClassMaskWInputsNoTrgDets() const
const CTPClass * getCTPClassFromHWIndex(const int index) const
uint64_t getTriggerClassMaskWInputs() const
int addCTPDigit(uint32_t linkCRU, uint32_t triggerOrbit, gbtword80_t &diglet, gbtword80_t &pldmask, std::map< o2::InteractionRecord, CTPDigit > &digits)
static int shiftNew(const o2::InteractionRecord &irin, uint32_t TFOrbit, std::bitset< 48 > &inpmask, int64_t shift, int level, std::map< o2::InteractionRecord, CTPDigit > &digmap)
static void makeGBTWordInverse(std::vector< gbtword80_t > &diglets, gbtword80_t &GBTWord, gbtword80_t &remnant, uint32_t &size_gbt, uint32_t Npld)
int checkReadoutConsistentncy(o2::pmr::vector< CTPDigit > &digits, uint64_t trgclassmask=0xffffffffffffffff, uint64_t trigclassmaskNoTrgDets=0xffffffffffffffff)
int setLumiInp(int lumiinp, std::string inp)
int decodeRaw(o2::framework::InputRecord &inputs, std::vector< o2::framework::InputSpec > &filter, o2::pmr::vector< CTPDigit > &digits, std::vector< LumiInfo > &lumiPointsHBF1)
static int shiftInputs(std::map< o2::InteractionRecord, CTPDigit > &digitsMap, o2::pmr::vector< CTPDigit > &digits, uint32_t TFOrbit, uint64_t trgclassmask=0xffffffffffffffff)
int decodeRawFatal(o2::framework::InputRecord &inputs, std::vector< o2::framework::InputSpec > &filter)
static constexpr ID CTP
Definition DetID.h:79
The parser handles transparently input in the format of raw pages.
const_iterator end() const
const_iterator begin() const
The input API of the Data Processing Layer This class holds the inputs which are valid for processing...
GLint GLsizei count
Definition glcorearb.h:399
GLuint index
Definition glcorearb.h:781
GLintptr offset
Definition glcorearb.h:660
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLuint GLsizei const GLchar * message
Definition glcorearb.h:2517
GLint level
Definition glcorearb.h:275
GLboolean r
Definition glcorearb.h:1233
GLint GLuint mask
Definition glcorearb.h:291
GLuint GLsizei const GLenum * rates
Definition glcorearb.h:5738
constexpr int LHCMaxBunches
constexpr double LHCOrbitMUS
std::bitset< NGBT > gbtword80_t
Definition Digits.h:36
std::vector< T, o2::pmr::polymorphic_allocator< T > > vector
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::unique_ptr< GPUReconstructionTimeframe > tf
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
Class = Mask+Descriptor+Cluster.
CTPDescriptor const * descriptor
std::uint64_t getInputsMask() const
std::bitset< CTP_NCLASSES > CTPClassMask
Definition Digits.h:53
o2::InteractionRecord intRecord
Definition Digits.h:51
void setInputMask(gbtword80_t mask)
Definition Digits.cxx:31
void setClassMask(gbtword80_t mask)
Definition Digits.cxx:37
static std::string getInputNameFromIndex(uint32_t index)
static int getInputIndexFromName(std::string &name)
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:60
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits