150 auto rdhPrevious = rdh;
151 bool firstRdh =
true;
152 uint32_t totalDataInputSize = 0;
153 mTotalHBFPayLoad = 0;
154 if (o2::raw::RDHUtils::getStop(rdh)) {
155 if (mMaxErrsPrinted > 0) {
156 LOGP(error,
"First RDH for given HBF for FEE ID {:#04x} has stop bit set", o2::raw::RDHUtils::getFEEID(rdh));
163 while (!o2::raw::RDHUtils::getStop(rdh)) {
165 LOG(info) <<
"Current RDH is as follows:";
168 }
catch (std::runtime_error& e) {
169 LOG(error) << e.what();
171 LOGP(
debug,
"mDataBufferSize {}, mDataBufferPtr {}, mCurrRdhPtr {}, totalDataInputSize {}. Already read: {}. Current payload {}", mDataBufferSize, fmt::ptr(mDataBufferPtr), fmt::ptr(mCurrRdhPtr), totalDataInputSize, mCurrRdhPtr - mDataBufferPtr, o2::raw::RDHUtils::getMemorySize(rdh));
176 if (!firstRdh && !
compareRDH(rdhPrevious, rdh)) {
182 auto headerSize = o2::raw::RDHUtils::getHeaderSize(rdh);
183 auto memorySize = o2::raw::RDHUtils::getMemorySize(rdh);
184 auto offsetToNext = o2::raw::RDHUtils::getOffsetToNext(rdh);
185 auto rdhpayload = memorySize - headerSize;
186 mFEEID.
word = o2::raw::RDHUtils::getFEEID(rdh);
187 mCRUEndpoint = o2::raw::RDHUtils::getEndPointID(rdh);
188 mCRUID = o2::raw::RDHUtils::getCRUID(rdh);
189 mIR = o2::raw::RDHUtils::getTriggerIR(rdh);
191 if (totalDataInputSize + memorySize >= mDataBufferSize) {
193 if (mMaxErrsPrinted > 0) {
194 LOGP(error,
"RDH memory size of {} + already read data size {} = {} >= {} (total available buffer size) from CRU with FEE ID {:#04x}",
195 memorySize, totalDataInputSize, memorySize + totalDataInputSize, mDataBufferSize, mFEEID.
word);
203 std::memcpy((
char*)&mHBFPayload[0] + mTotalHBFPayLoad, ((
char*)rdh) + headerSize, rdhpayload);
205 mTotalHBFPayLoad += rdhpayload;
206 totalDataInputSize += offsetToNext;
208 mCurrRdhPtr += offsetToNext;
212 mCurrRdhPtr += o2::raw::RDHUtils::getOffsetToNext(rdh);
215 LOG(info) <<
"Current RDH is as follows (should have STOP bit set):";
218 }
catch (std::runtime_error& e) {
219 LOG(error) << e.what();
226 mPreviousHalfCRUHeaderSet =
false;
227 while (mHBFoffset32 < (mTotalHBFPayLoad / 4)) {
229 LOGP(info,
"Current half-CRU iteration {}, current offset in the HBF payload {}, total payload in number of 32-bit words {}", iteration, mHBFoffset32, mTotalHBFPayLoad / 4);
238 return totalDataInputSize;
245 mDigitHCHeader.
word = mHBFPayload[mHBFoffset32++];
251 if (mDigitHCHeader.
major == 0 && mDigitHCHeader.
minor == 0 && mDigitHCHeader.
numberHCW == 0) {
252 mDigitHCHeader.
major = mHalfChamberMajor;
253 mDigitHCHeader.
minor = 42;
254 mDigitHCHeader.
numberHCW = mHalfChamberWords;
255 if (mHalfChamberWords == 0 || mHalfChamberMajor == 0) {
256 if (mMaxWarnPrinted > 0) {
257 LOG(alarm) <<
"DigitHCHeader is corrupted and using a hack as workaround is not configured";
266 if (hcid != halfChamberIdHeader) {
268 if (mMaxWarnPrinted > 0) {
269 LOGF(warning,
"HCID mismatch in DigitHCHeader detected for ref HCID %i. DigitHCHeader says HCID is %i", hcid, halfChamberIdHeader);
275 int additionalHeaderWords = mDigitHCHeader.
numberHCW;
276 if (additionalHeaderWords >= 3) {
278 if (mMaxWarnPrinted > 0) {
279 LOGF(warn,
"Found too many additional words (%i) in DigitHCHeader 0x%08x", additionalHeaderWords, mDigitHCHeader.
word);
284 std::bitset<3> headersfound;
285 std::array<uint32_t, 3> headers{0};
287 for (
int headerwordcount = 0; headerwordcount < additionalHeaderWords; ++headerwordcount) {
288 headers[headerwordcount] = mHBFPayload[mHBFoffset32++];
292 if (headersfound.test(0)) {
295 LOGF(warn,
"We have more than one DigitHCHeader of type 1. Current word in hex %08x", headers[headerwordcount]);
302 header1.
word = headers[headerwordcount];
304 mPreTriggerPhase &= 0x0f;
305 mPreTriggerPhase /= 3;
306 LOGP(
debug,
"Found pretrigger phase of Phase:{:x}", mPreTriggerPhase);
311 LOGF(warn,
"According to Digit HC Header 1 there are %i time bins configured", (
int)header1.
numtimebins);
321 if (headersfound.test(1)) {
324 LOGF(warn,
"We have more than one DigitHCHeader of type 2. Current word in hex %08x", headers[headerwordcount]);
338 if (headersfound.test(2)) {
341 LOG(info) <<
"We have a >1 Digit HC Header 2 : " << std::hex <<
" raw: 0x" << headers[headerwordcount];
348 header3.
word = headers[headerwordcount];
350 if (mHaveSeenDigitHCHeader3) {
351 if (header3.
svnver != mPreviousDigitHCHeadersvnver || header3.
svnrver != mPreviousDigitHCHeadersvnrver) {
353 LOG(warning) <<
"Conflicting SVN in DigitHCHeader3";
360 mPreviousDigitHCHeadersvnver = header3.
svnver;
361 mPreviousDigitHCHeadersvnrver = header3.
svnrver;
362 mHaveSeenDigitHCHeader3 =
true;
386 LOG(info) <<
"blank rdh payload data at " << mHBFoffset32 <<
": 0x" << std::hex << mHBFPayload[mHBFoffset32] <<
" and 0x" << mHBFPayload[mHBFoffset32 + 1];
389 while (mHBFPayload[mHBFoffset32] ==
CRUPADDING32 && loopcount < 8) {
397 auto crustart = std::chrono::high_resolution_clock::now();
399 memcpy(&mCurrentHalfCRUHeader, &(mHBFPayload[mHBFoffset32]),
sizeof(
HalfCRUHeader));
407 mWordsRejected += (mTotalHBFPayLoad / 4) - mHBFoffset32 +
sizeof(
HalfCRUHeader) / 4;
413 uint32_t totalHalfCRUDataLength256 = std::accumulate(mCurrentHalfCRULinkLengths.begin(),
414 mCurrentHalfCRULinkLengths.end(),
416 uint32_t totalHalfCRUDataLength32 = totalHalfCRUDataLength256 * 8;
420 mWordsRejected += totalHalfCRUDataLength32;
421 mHBFoffset32 += totalHalfCRUDataLength32;
424 if (mCRUEndpoint != mCurrentHalfCRUHeader.
EndPoint) {
425 if (mMaxWarnPrinted > 0) {
426 LOGF(warn,
"End point mismatch detected. HalfCRUHeader says %i, RDH says %i", mCurrentHalfCRUHeader.
EndPoint, mCRUEndpoint);
430 mHBFoffset32 += totalHalfCRUDataLength32;
431 mWordsRejected += totalHalfCRUDataLength32;
435 if (mPreviousHalfCRUHeaderSet) {
439 if (mMaxWarnPrinted > 0) {
440 LOGF(warn,
"For current half-CRU index %i we have end point %i, while the previous end point was %i", iteration, mCurrentHalfCRUHeader.
EndPoint, mPreviousHalfCRUHeader.
EndPoint);
444 mWordsRejected += totalHalfCRUDataLength32;
445 mHBFoffset32 += totalHalfCRUDataLength32;
448 if (mCurrentHalfCRUHeader.
StopBit != mPreviousHalfCRUHeader.
StopBit) {
449 if (mMaxWarnPrinted > 0) {
450 LOGF(warn,
"For current half-CRU index %i we have stop bit %i, while the previous stop bit was %i", iteration, mCurrentHalfCRUHeader.
StopBit, mPreviousHalfCRUHeader.
StopBit);
454 mWordsRejected += totalHalfCRUDataLength32;
455 mHBFoffset32 += totalHalfCRUDataLength32;
459 mPreviousHalfCRUHeader = mCurrentHalfCRUHeader;
460 mPreviousHalfCRUHeaderSet =
true;
463 if (totalHalfCRUDataLength32 > (mTotalHBFPayLoad / 4) - mHBFoffset32) {
464 if (mMaxWarnPrinted > 0) {
465 LOGP(warn,
"HalfCRU header says it contains more data ({} 32-bit words) than is remaining in the payload ({} 32-bit words)", totalHalfCRUDataLength32, ((mTotalHBFPayLoad / 4) - mHBFoffset32));
469 mWordsRejected += (mTotalHBFPayLoad / 4) - mHBFoffset32;
478 mHBFoffset32 += totalHalfCRUDataLength32;
479 mWordsRejected += totalHalfCRUDataLength32;
492 uint32_t linksizeAccum32 = 0;
493 auto hbfOffsetTmp = mHBFoffset32;
494 for (
int currentlinkindex = 0; currentlinkindex <
NLINKSPERHALFCRU; currentlinkindex++) {
497 int halfCruIdx = cruIdx * 2 + mFEEID.
endpoint;
499 int halfChamberId = mLinkMap->
getHCID(linkIdxGlobal);
502 mEventRecords.
incLinkErrorFlags(halfChamberId, mCurrentHalfCRULinkErrorFlags[currentlinkindex]);
503 mEventRecords.
incLinkWords(halfChamberId, mCurrentHalfCRULinkLengths[currentlinkindex]);
504 uint32_t currentlinksize32 = mCurrentHalfCRULinkLengths[currentlinkindex] * 8;
505 uint32_t endOfCurrentLink = mHBFoffset32 + currentlinksize32;
509 linksizeAccum32 += currentlinksize32;
510 if (currentlinksize32 == 0) {
514 if (currentlinksize32 > 0) {
515 LOGF(info,
"Half-CRU link %i raw dump before parsing starts:", currentlinkindex);
516 for (uint32_t dumpoffset = mHBFoffset32; dumpoffset < mHBFoffset32 + currentlinksize32; dumpoffset += 8) {
517 LOGF(info,
"0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", mHBFPayload[dumpoffset], mHBFPayload[dumpoffset + 1], mHBFPayload[dumpoffset + 2], mHBFPayload[dumpoffset + 3], mHBFPayload[dumpoffset + 4], mHBFPayload[dumpoffset + 5], mHBFPayload[dumpoffset + 6], mHBFPayload[dumpoffset + 7]);
520 LOGF(info,
"Half-CRU link %i has zero link size", currentlinkindex);
523 if (currentlinksize32 > 0) {
524 auto trackletparsingstart = std::chrono::high_resolution_clock::now();
526 LOGF(info,
"Tracklet parser starting at offset %u and processing up to %u words", mHBFoffset32, currentlinksize32);
528 int trackletWordsRejected = 0;
529 int trackletWordsReadOK = 0;
530 int numberOfTrackletsFound = 0;
531 int trackletWordsRead =
parseTrackletLinkData(currentlinksize32, halfChamberId, trackletWordsRejected, trackletWordsReadOK, numberOfTrackletsFound);
532 std::chrono::duration<float, std::micro> trackletparsingtime = std::chrono::high_resolution_clock::now() - trackletparsingstart;
534 LOGP(info,
"Could read {} 32-bit words w/o errors, found {} tracklets, rejected {} 32-bit words for {}. Parsing OK? {}", trackletWordsReadOK, numberOfTrackletsFound, trackletWordsRejected,
HelperMethods::getSectorStackLayerSide(halfChamberId), (trackletWordsRead != -1 && trackletWordsRejected == 0));
536 if (trackletWordsRead == -1) {
538 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
542 if (trackletWordsRejected > 0) {
545 mHBFoffset32 += trackletWordsRead;
547 endOfCurrentLink - mHBFoffset32 >= 8) {
548 if (mMaxWarnPrinted > 0) {
549 LOGF(warn,
"After successfully parsing the tracklet data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
557 LOGF(
debug,
"Read %i tracklet words and rejected %i words", trackletWordsRead, trackletWordsRejected);
559 mTrackletWordsRejected += trackletWordsRejected;
560 mTrackletWordsRead += trackletWordsRead;
568 if (mHBFoffset32 != endOfCurrentLink &&
573 uint32_t offsetBeforeDigitParsing = mHBFoffset32;
576 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
579 if (mHBFoffset32 - offsetBeforeDigitParsing != 1U + mDigitHCHeader.
numberHCW) {
580 if (mMaxErrsPrinted > 0) {
581 LOGF(error,
"Did not read as many digit headers (%i) as expected (%i)",
582 mHBFoffset32 - offsetBeforeDigitParsing, mDigitHCHeader.
numberHCW + 1);
585 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
591 if (mDigitHCHeader.
major == 0x47) {
594 mHBFoffset32 = hbfOffsetTmp + currentlinksize32;
595 mDigitWordsRejected += hbfOffsetTmp + currentlinksize32;
596 LOG(info) <<
"Configuration event ";
598 auto digitsparsingstart = std::chrono::high_resolution_clock::now();
599 int digitWordsRejected = 0;
600 int digitWordsRead =
parseDigitLinkData(endOfCurrentLink - mHBFoffset32, halfChamberId, digitWordsRejected);
601 std::chrono::duration<float, std::micro> digitsparsingtime = std::chrono::high_resolution_clock::now() - digitsparsingstart;
602 if (digitWordsRead == -1) {
604 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
607 mHBFoffset32 += digitWordsRead;
608 if (endOfCurrentLink - mHBFoffset32 >= 8) {
611 if (mMaxWarnPrinted > 0) {
612 LOGF(warn,
"After successfully parsing the digit data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
618 if (digitWordsRejected > 0) {
626 LOGF(info,
"Read %i digit words and rejected %i words", digitWordsRead, digitWordsRejected);
628 mDigitWordsRead += digitWordsRead;
629 mDigitWordsRejected += digitWordsRejected;
641 if (mHBFoffset32 != hbfOffsetTmp + linksizeAccum32) {
643 LOGF(
debug,
"After processing link %i the payload offset of %u is not the expected %u + %u", currentlinkindex, mHBFoffset32, hbfOffsetTmp, linksizeAccum32);
644 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
647 if (mHBFoffset32 != hbfOffsetTmp + totalHalfCRUDataLength32) {
648 LOGF(
debug,
"After processing half-CRU data the offset (%u) is not pointing to the expected position (%u + %u = %u)", mHBFoffset32, hbfOffsetTmp, totalHalfCRUDataLength32, totalHalfCRUDataLength32 + hbfOffsetTmp);
649 mHBFoffset32 = hbfOffsetTmp + totalHalfCRUDataLength32;
656 std::chrono::duration<float, std::micro> cruparsingtime = std::chrono::high_resolution_clock::now() - crustart;