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 if (mCTPConfig.getRunNumber() != 0) {
298 trgclassmask = mCTPConfig.getTriggerClassMask();
299 }
300 // std::cout << "trgclassmask:" << std::hex << trgclassmask << std::dec << std::endl;
301 ret = shiftInputs(digitsMap, digits, mTFOrbit, trgclassmask);
302 if (mCheckConsistency) {
303 ret = checkReadoutConsistentncy(digits, trgclassmask);
304 }
305 }
306 if (mDoDigits && !mDecodeInps) {
307 for (auto const& dig : digitsMap) {
308 digits.push_back(dig.second);
309 }
310 }
311 // ret = 1;
312 if (mStickyError) {
313 if (nwrites < mErrorMax) {
314 std::string file = "dumpCTP" + std::to_string(nwrites) + ".bin";
315 std::ofstream dumpctp(file.c_str(), std::ios::out | std::ios::binary);
316 if (!dumpctp.good()) {
317 LOGP(error, "Failed to open file {}", file);
318 } else {
319 LOGP(info, "CTP dump file open {}", file);
320 for (auto it = parser.begin(); it != parser.end(); ++it) {
321 char* dataout = (char*)(it.raw());
322 dumpctp.write(dataout, it.sizeTotal());
323 }
324 dumpctp.close();
325 }
326 nwrites++;
327 }
328 // LOG(error) << "CTP decoding IR errors:" << mErrorIR << " TCR errors:" << mErrorTCR;
329 }
330 return ret;
331}
332//
333int RawDataDecoder::decodeRawFatal(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec>& filter)
334{
335 o2::framework::DPLRawParser parser(inputs, filter);
336 uint32_t payloadCTP = 0;
337 gbtword80_t remnant = 0;
338 uint32_t size_gbt = 0;
339 mTFOrbit = 0;
340 uint32_t orbit0 = 0;
341 std::array<int, o2::ctp::CTP_NCLASSES> rates{};
342 std::array<int, o2::ctp::CTP_NCLASSES> ratesC{};
343 for (auto it = parser.begin(); it != parser.end(); ++it) {
344 const o2::header::RDHAny* rdh = nullptr;
345 try {
346 rdh = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
347 mPadding = (o2::raw::RDHUtils::getDataFormat(rdh) == 0);
348 } catch (std::exception& e) {
349 LOG(error) << "Failed to extract RDH, abandoning TF sending dummy output, exception was: " << e.what();
350 // dummyOutput();
351 return 1;
352 }
353 // auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(rdh);
354 uint32_t stopBit = o2::raw::RDHUtils::getStop(rdh);
355 uint32_t packetCounter = o2::raw::RDHUtils::getPageCounter(rdh);
357 uint32_t rdhOrbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdh);
358 uint32_t triggerType = o2::raw::RDHUtils::getTriggerType(rdh);
359 // std::cout << "diff orbits:" << triggerOrbit - rdhOrbit << std::endl;
360 bool tf = (triggerType & TF_TRIGGERTYPE_MASK) && (packetCounter == 0);
361 bool hb = (triggerType & HB_TRIGGERTYPE_MASK) && (packetCounter == 0);
362 if (tf) {
363 mTFOrbit = rdhOrbit;
364 // std::cout << "tforbit==================>" << mTFOrbit << " " << std::hex << mTFOrbit << std::endl;
365 mTFOrbits.push_back(mTFOrbit);
366 }
367 static bool prt = true;
368 if (prt) {
369 LOG(info) << "RDH version:" << version << " Padding:" << mPadding;
370 prt = false;
371 }
372 auto feeID = o2::raw::RDHUtils::getFEEID(rdh); // 0 = IR, 1 = TCR
373 auto linkCRU = (feeID & 0xf00) >> 8;
374 // LOG(info) << "CRU link:" << linkCRU;
375 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
376 payloadCTP = o2::ctp::NIntRecPayload;
377 } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) {
378 payloadCTP = o2::ctp::NClassPayload;
379 } else {
380 LOG(error) << "Unxpected CTP CRU link:" << linkCRU;
381 }
382 LOG(debug) << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << rdhOrbit << " triggerType:" << triggerType;
383 // LOG(info) << "remnant :" << remnant.count();
384 gbtword80_t pldmask = 0;
385 for (uint32_t i = 0; i < payloadCTP; i++) {
386 pldmask[12 + i] = 1;
387 }
388 // std::cout << (orbit0 != rdhOrbit) << " comp " << (mTFOrbit==rdhOrbit) << std::endl;
389 // if(orbit0 != rdhOrbit) {
390 if (hb) {
391 remnant = 0;
392 size_gbt = 0;
393 orbit0 = rdhOrbit;
394 // std::cout << "orbit0============>" << std::dec << orbit0 << " " << std::hex << orbit0 << std::endl;
395 }
396 // Create 80 bit words
397 gsl::span<const uint8_t> payload(it.data(), it.size());
398 gbtword80_t gbtWord80;
399 gbtWord80.set();
400 int wordCount = 0;
401 int wordSize = 10;
402 std::vector<gbtword80_t> gbtwords80;
403 // mPadding = 0;
404 if (mPadding == 1) {
405 wordSize = 16;
406 }
407 // LOG(info) << ii << " payload size:" << payload.size();
408 gbtword80_t bcmask = std::bitset<80>("111111111111");
409 for (auto payloadWord : payload) {
410 int wc = wordCount % wordSize;
411 // LOG(info) << wordCount << ":" << wc << " payload:" << int(payloadWord);
412 if ((wc == 0) && (wordCount != 0)) {
413 if (gbtWord80.count() != 80) {
414 gbtwords80.push_back(gbtWord80);
415 }
416 gbtWord80.set();
417 }
418 if (wc < 10) {
419 for (int i = 0; i < 8; i++) {
420 gbtWord80[wc * 8 + i] = bool(int(payloadWord) & (1 << i));
421 }
422 }
423 wordCount++;
424 }
425 if ((gbtWord80.count() != 80) && (gbtWord80.count() > 0)) {
426 gbtwords80.push_back(gbtWord80);
427 }
428 // decode 80 bits payload
429 for (auto word : gbtwords80) {
430 std::vector<gbtword80_t> diglets;
431 gbtword80_t gbtWord = word;
432 makeGBTWordInverse(diglets, gbtWord, remnant, size_gbt, payloadCTP);
433 for (auto diglet : diglets) {
434 int nbits = payloadCTP - 12;
435 for (int i = 0; i < nbits; i++) {
436 gbtword80_t mask = 1ull << i;
437 gbtword80_t pld = (diglet >> 12) & mask;
438 // LOG(info) << "diglet:" << diglet << " pld:" << pld;
439 if (pld.count() != 0) {
440 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
441 rates[i]++;
442 } else {
443 ratesC[i]++;
444 }
445 }
446 }
447 // LOG(debug) << "diglet:" << diglet << " " << (diglet & bcmask).to_ullong();
448 }
449 }
450 if ((remnant.count() > 0) && stopBit) {
451 int nbits = payloadCTP - 12;
452 for (int i = 0; i < nbits; i++) {
453 gbtword80_t mask = 1ull << i;
454 gbtword80_t pld = (remnant >> 12) & mask;
455 // LOG(info) << "diglet:" << remnant << " pld:" << pld;
456 if (pld.count() != 0) {
457 if (linkCRU == o2::ctp::GBTLinkIDIntRec) {
458 rates[i]++;
459 } else {
460 ratesC[i]++;
461 }
462 }
463 }
464 remnant = 0;
465 }
466 }
467 // print max rates
468 std::map<int, int> ratesmap;
469 std::map<int, int> ratesmapC;
470 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
471 if (rates[i]) {
472 ratesmap[rates[i]] = i;
473 }
474 if (ratesC[i]) {
475 ratesmapC[ratesC[i]] = i;
476 }
477 }
479 std::string message = "Ringing inputs [MHz]:";
480 for (auto const& r : boost::adaptors::reverse(ratesmap)) {
481 // LOG(error) << r.second;
483 }
484 std::string messageC = "Ringing classes [MHz]:";
485 for (auto const& r : boost::adaptors::reverse(ratesmapC)) {
486 messageC += " class" + std::to_string(r.second) + ":" + std::to_string(r.first / 32. / o2::constants::lhc::LHCOrbitMUS);
487 }
488 LOG(error) << messageC;
489 LOG(fatal) << message;
490 return 0;
491}
492//
493int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec>& filter, std::vector<CTPDigit>& digits, std::vector<LumiInfo>& lumiPointsHBF1)
494{
496 int ret = decodeRaw(inputs, filter, pmrdigits, lumiPointsHBF1);
497 for (auto const d : pmrdigits) {
498 digits.push_back(d);
499 }
500 return ret;
501}
502//
503// Not to be called with level LM
504// Keeping shift in params if needed to be generalised
505int RawDataDecoder::shiftNew(const o2::InteractionRecord& irin, uint32_t TFOrbit, std::bitset<48>& inpmask, int64_t shift, int level, std::map<o2::InteractionRecord, CTPDigit>& digmap)
506{
507 //
508 if (irin.orbit > TFOrbit || irin.bc >= shift) {
509 auto lxmask = L0MASKInputs;
510 if (level == 1) {
511 lxmask = L1MASKInputs;
512 }
513 auto ir = irin - shift; // add L0 to prev digit
514 if (digmap.count(ir)) {
515 if ((digmap[ir].CTPInputMask & lxmask).count()) {
516 LOG(error) << " Overwriting LX ? X:" << level;
517 }
518 digmap[ir].CTPInputMask = digmap[ir].CTPInputMask | (inpmask & lxmask);
519 } else {
520 CTPDigit digit = {ir, inpmask & lxmask, 0};
521 digmap[ir] = digit;
522 }
523 } else {
524 LOG(info) << "LOST:" << irin << " shift:" << shift;
525 }
526 return 0;
527}
528//
529
530int RawDataDecoder::shiftInputs(std::map<o2::InteractionRecord, CTPDigit>& digitsMap, o2::pmr::vector<CTPDigit>& digits, uint32_t TFOrbit, uint64_t trgclassmask)
531{
532 // int nClasswoInp = 0; // counting classes without input which should never happen
533 int nLM = 0;
534 int nL0 = 0;
535 int nL1 = 0;
536 int nTwI = 0;
537 int nTwoI = 0;
538 int nTwoIlost = 0;
539 std::map<o2::InteractionRecord, CTPDigit> digitsMapShifted;
541 auto L1shift = L0shift + o2::ctp::TriggerOffsetsParam::Instance().L0_L1;
542 for (auto const& dig : digitsMap) {
543 auto inpmask = dig.second.CTPInputMask;
544 auto inpmaskLM = inpmask & LMMASKInputs;
545 auto inpmaskL0 = inpmask & L0MASKInputs;
546 auto inpmaskL1 = inpmask & L1MASKInputs;
547 int lm = inpmaskLM.count() > 0;
548 int l0 = inpmaskL0.count() > 0;
549 int l1 = inpmaskL1.count() > 0;
550 int lut = lm + (l0 << 1) + (l1 << 2);
551 // std::cout << "L0mask:" << L0MASKInputs << std::endl;
552 // std::cout << "L0:" << inpmaskL0 << std::endl;
553 // std::cout << "L1:" << inpmaskL1 << std::endl;
554 if (lut == 0 || lut == 1) { // no inps or LM
555 digitsMapShifted[dig.first] = dig.second;
556 } else if (lut == 2) { // L0
557 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
558 if (dig.second.CTPClassMask.count()) {
559 // LOG(error) << "Adding class mask without input ?";
560 // This is not needed as it can happen; Full checj done below - see next LOG(error)
561 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
562 digitsMapShifted[dig.first] = digi;
563 }
564 } else if (lut == 4) { // L1
565 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
566 if (dig.second.CTPClassMask.count()) {
567 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
568 digitsMapShifted[dig.first] = digi;
569 }
570 } else if (lut == 6) { // L0 and L1
571 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
572 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
573 if (dig.second.CTPClassMask.count()) {
574 CTPDigit digi = {dig.first, 0, dig.second.CTPClassMask};
575 digitsMapShifted[dig.first] = digi;
576 }
577 } else if (lut == 3) { // LM and L0
578 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
579 CTPDigit digi = {dig.first, inpmask & (~L0MASKInputs), dig.second.CTPClassMask};
580 // if LM level do not need to add class as LM is not shifted;
581 digitsMapShifted[dig.first] = digi;
582 } else if (lut == 5) { // LM and L1
583 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
584 CTPDigit digi = {dig.first, inpmask & (~L1MASKInputs), dig.second.CTPClassMask};
585 digitsMapShifted[dig.first] = digi;
586 } else if (lut == 7) { // LM and L0 and L1
587 shiftNew(dig.first, TFOrbit, inpmask, L0shift, 0, digitsMapShifted);
588 shiftNew(dig.first, TFOrbit, inpmask, L1shift, 1, digitsMapShifted);
589 CTPDigit digi = {dig.first, inpmaskLM, dig.second.CTPClassMask};
590 digitsMapShifted[dig.first] = digi;
591 } else {
592 LOG(fatal) << "lut = " << lut;
593 }
594 }
595 for (auto const& dig : digitsMapShifted) {
596 auto d = dig.second;
597 if ((d.CTPInputMask & LMMASKInputs).count()) {
598 nLM++;
599 }
600 if ((d.CTPInputMask & L0MASKInputs).count()) {
601 nL0++;
602 }
603 if ((d.CTPInputMask & L1MASKInputs).count()) {
604 nL1++;
605 }
606 if ((d.CTPClassMask).to_ulong() & trgclassmask) {
607 if (d.CTPInputMask.count()) {
608 nTwI++;
609 } else {
610 if (d.intRecord.bc == (o2::constants::lhc::LHCMaxBunches - L1shift)) { // input can be lost because latency class-l1input = 1
611 nTwoIlost++;
612 } else {
613 // LOG(error) << d.intRecord << " " << d.CTPClassMask << " " << d.CTPInputMask;
614 // std::cout << "ERROR:" << std::hex << d.CTPClassMask << " " << d.CTPInputMask << std::dec << std::endl;
615 nTwoI++;
616 }
617 }
618 }
619 digits.push_back(dig.second);
620 }
621 int ret = 0;
622 if (nTwoI) { // Trigger class wo Input
623 LOG(error) << "LM:" << nLM << " L0:" << nL0 << " L1:" << nL1 << " TwI:" << nTwI << " Trigger classes wo input:" << nTwoI;
624 ret = 64;
625 }
626 if (nTwoIlost) {
627 LOG(warn) << " Trigger classes wo input from diff latency 1:" << nTwoIlost;
628 }
629 return ret;
630}
631//
633{
634 int ret = 0;
635 int lost = 0;
636 for (auto const& digit : digits) {
637 // if class mask => inps
638 for (int i = 0; i < digit.CTPClassMask.size(); i++) {
639 if (digit.CTPClassMask[i]) {
640 const CTPClass* cls = mCTPConfig.getCTPClassFromHWIndex(i);
641 uint64_t clsinpmask = cls->descriptor->getInputsMask();
642 uint64_t diginpmask = digit.CTPInputMask.to_ullong();
643 if (!((clsinpmask & diginpmask) == clsinpmask)) {
644 LOG(error) << "CTP class:" << cls->name << " inpmask:" << clsinpmask << " not compatible with inputs mask:" << diginpmask;
645 ret = 128;
646 }
647 }
648 }
649 // if inps => class mask
650 for (auto const& cls : mCTPConfig.getCTPClasses()) {
651 uint64_t clsinpmask = cls.descriptor->getInputsMask();
652 uint64_t diginpmask = digit.CTPInputMask.to_ullong();
653 uint64_t digclsmask = digit.CTPClassMask.to_ullong();
654 if ((clsinpmask & diginpmask) == clsinpmask) {
655 if ((cls.classMask & digclsmask) == 0) {
659 if (digit.intRecord.bc < offset) {
660 LOG(error) << "CTP class:" << cls.name << " inpmask:" << clsinpmask << " cls mask:" << cls.classMask << " not found in digit:" << digit;
661 ret = 256;
662 } else {
663 lost++;
664 }
665 }
666 }
667 }
668 }
669 if (lost) {
670 LOG(info) << "LOST classes because of shift:" << lost;
671 }
672 return ret;
673}
674//
675int RawDataDecoder::setLumiInp(int lumiinp, std::string inp)
676{
677 // check if valid input
679 if (index == 0xff) {
680 LOG(fatal) << "CTP raw decoder: input index not found:" << inp;
681 return 0xff;
682 }
683 if (lumiinp == 1) {
684 mTVXMask.reset();
685 mTVXMask[index - 1] = true;
686 } else {
687 mVBAMask.reset();
688 mVBAMask[index - 1] = true;
689 }
690 return index;
691}
692//
694{
695 return 0;
696}
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 getTriggerClassMask() const
const CTPClass * getCTPClassFromHWIndex(const int index) 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)
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:58
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits