20#include <fmt/format.h>
31 mGBTUniqueId = gbtUniqueId;
35bool GBTRawDataChecker::checkLocalBoardSize(
const ROBoard& board)
42 for (
int ich = 0; ich < 4; ++ich) {
43 bool isExpectedNull = (((board.
firedChambers >> ich) & 0x1) == 0);
45 if (isExpectedNull != isNull) {
47 ss <<
"wrong size for local board:\n";
49 mEventDebugMsg += ss.str();
56bool GBTRawDataChecker::checkLocalBoardSize(
const std::vector<ROBoard>& boards)
59 for (
auto& board : boards) {
60 if (!checkLocalBoardSize(board)) {
67bool GBTRawDataChecker::checkConsistency(
const ROBoard& board)
71 bool isSoxOrReset = board.triggerWord & (raw::sSOX | raw::sEOX | raw::sRESET);
73 bool isPhys = board.triggerWord & raw::sPHY;
92 if (isSoxOrReset && (isCalib || isPhys)) {
93 mEventDebugMsg +=
"inconsistent trigger: cannot be SOX and calibration\n";
100bool GBTRawDataChecker::checkConsistency(
const std::vector<ROBoard>& boards)
103 for (
auto& board : boards) {
104 if (!checkConsistency(board)) {
105 std::stringstream ss;
107 mEventDebugMsg += ss.str();
114bool GBTRawDataChecker::checkMasks(
const std::vector<ROBoard>& locs)
117 for (
auto loc : locs) {
119 if (loc.statusWord & raw::sOVERWRITTEN) {
120 auto maskItem = mMasks.find(loc.boardId);
121 for (
int ich = 0; ich < 4; ++ich) {
123 uint16_t maskNBP = 0;
124 if (maskItem != mMasks.end()) {
125 maskBP = maskItem->second.patternsBP[ich];
126 maskNBP = maskItem->second.patternsNBP[ich];
128 if (maskBP != loc.patternsBP[ich] || maskNBP != loc.patternsNBP[ich]) {
129 std::stringstream ss;
130 ss <<
"Pattern is not compatible with mask for:\n";
132 mEventDebugMsg += ss.str();
141bool GBTRawDataChecker::checkRegLocConsistency(
const std::vector<ROBoard>& regs,
const std::vector<ROBoard>& locs,
const InteractionRecord&
ir)
146 for (
auto& reg : regs) {
148 if (reg.triggerWord == 0) {
150 regFired |= (reg.firedChambers << (4 * ireg));
153 regFired |= (mCrateMask & (0xF << (4 * ireg)));
158 for (
auto& loc : locs) {
159 auto linkId = getElinkId(loc);
161 if (loc.triggerWord == 0) {
163 if (loc.firedChambers) {
174 uint8_t problems = (regFired ^ locFired);
180 for (uint8_t iboard = 0; iboard < crateparams::sNELinksPerGBT; ++iboard) {
181 auto rawIr = getRawIR(iboard, isTrig,
ir);
183 for (
auto& busyInfo : mBusyPeriods[iboard]) {
184 if (busyInfo.interactionRecord > rawIr) {
190 busy |= (iboard < crateparams::sMaxNBoardsInLink) ? (1 << iboard) : (0xF << (4 * (iboard % 2)));
194 if (problems & ~busy) {
195 std::stringstream ss;
196 ss << fmt::format(
"loc-reg inconsistency: fired locals ({:08b}) != expected from reg ({:08b});\n", locFired, regFired);
197 ss << printBoards(regs);
198 ss << printBoards(locs);
199 mEventDebugMsg += ss.str();
206std::string GBTRawDataChecker::printBoards(
const std::vector<ROBoard>& boards)
const
209 std::stringstream ss;
210 for (
auto& board : boards) {
216bool GBTRawDataChecker::checkEvent(
bool isTriggered,
const std::vector<ROBoard>& regs,
const std::vector<ROBoard>& locs,
const InteractionRecord&
ir)
219 mEventDebugMsg.clear();
220 if (!checkRegLocConsistency(regs, locs,
ir)) {
224 if (!checkConsistency(regs) || !checkConsistency(locs)) {
229 if (!checkLocalBoardSize(locs)) {
233 if (!checkMasks(locs)) {
241InteractionRecord GBTRawDataChecker::getRawIR(uint8_t
id,
bool isTrigger, InteractionRecord
ir)
const
247 auto delay = mElectronicsDelay.
localToBC;
248 if (
id >= crateparams::sMaxNBoardsInLink) {
255uint8_t GBTRawDataChecker::getElinkId(
const ROBoard& board)
const
259 return board.boardId % 8;
261 return 8 + board.boardId % 8;
264void GBTRawDataChecker::clearChecked(
bool isTriggered,
bool clearTrigEvents)
268 auto& boards = isTriggered ? mBoardsTrig : mBoardsSelfTrig;
269 auto& lastIndexes = isTriggered ? mLastIndexTrig : mLastIndexSelfTrig;
271 for (
auto& lastIdxItem : lastIndexes) {
272 auto firstIdx = lastIdxItem.second + 1;
273 auto& boardVec = boards[lastIdxItem.first];
274 boards[lastIdxItem.first].erase(boardVec.begin(), boardVec.begin() + firstIdx);
277 if (clearTrigEvents) {
279 auto& lastCompleteTrigIR = isTriggered ? mLastCompleteIRTrig : mLastCompleteIRSelfTrig;
280 auto up = mTrigEvents.upper_bound(lastCompleteTrigIR);
281 mTrigEvents.erase(mTrigEvents.begin(), up);
282 for (
auto& busyInfoVec : mBusyPeriods) {
283 auto upBusy = std::upper_bound(busyInfoVec.begin(), busyInfoVec.end(), lastCompleteTrigIR, [](
const InteractionRecord&
ir,
const BusyInfo& busyInfo) { return ir <= busyInfo.interactionRecord; });
284 if (upBusy != busyInfoVec.begin()) {
287 busyInfoVec.erase(busyInfoVec.begin(), upBusy);
301 bool isIncluded =
false;
302 for (uint8_t ireg = 8; ireg < crateparams::sNELinksPerGBT; ++ireg) {
303 auto& boards = mBoardsSelfTrig[ireg];
304 if (!boards.empty()) {
305 if (boards.back().interactionRecord.orbit ==
ir.
orbit) {
308 if (boards.front().interactionRecord.orbit <=
ir.
orbit) {
316unsigned int GBTRawDataChecker::getLastCompleteTrigEvent()
328 unsigned int completeMask = 0;
332 uint16_t fullMask = (3 << 8) | mCrateMask;
333 auto trigEventIt = mTrigEvents.rbegin();
334 auto end = mTrigEvents.rend();
335 for (; trigEventIt !=
end; ++trigEventIt) {
336 if ((trigEventIt->second & fullMask) == fullMask) {
341 if (mLastCompleteIRTrig.
isDummy() || mLastCompleteIRTrig < trigEventIt->first) {
343 mLastCompleteIRTrig = trigEventIt->first;
345 auto trIt = trigEventIt;
346 while (trIt !=
end) {
347 if (isCompleteSelfTrigEvent(trIt->first)) {
348 completeMask |= (1 << 1);
349 mLastCompleteIRSelfTrig = trIt->first;
362bool GBTRawDataChecker::runCheckEvents(
unsigned int completeMask)
368 if (completeMask & 0x1) {
370 isOk &= checkEvents(
true);
372 bool clearTrigger =
true;
373 for (
auto infos : mBoardsSelfTrig) {
374 if (!infos.empty()) {
375 clearTrigger =
false;
379 clearChecked(
true, clearTrigger);
382 if (completeMask & 0x2) {
384 isOk &= checkEvents(
false);
385 clearChecked(
false,
true);
391void GBTRawDataChecker::sortEvents(
bool isTriggered)
394 auto& orderedIndexes = isTriggered ? mOrderedIndexesTrig : mOrderedIndexesSelfTrig;
395 auto& lastIndexes = isTriggered ? mLastIndexTrig : mLastIndexSelfTrig;
396 auto& boards = isTriggered ? mBoardsTrig : mBoardsSelfTrig;
397 auto& lastCompleteTrigEventIR = isTriggered ? mLastCompleteIRTrig : mLastCompleteIRSelfTrig;
398 orderedIndexes.
clear();
400 for (uint8_t ilink = 0; ilink < crateparams::sNELinksPerGBT; ++ilink) {
401 long int lastIdx = -1;
402 for (
auto boardIt = boards[ilink].
begin(),
end = boards[ilink].
end(); boardIt !=
end; ++boardIt) {
403 if (boardIt->interactionRecord > lastCompleteTrigEventIR) {
406 lastIdx = std::distance(boards[ilink].
begin(), boardIt);
407 orderedIndexes[boardIt->interactionRecord.toLong()].emplace_back(ilink, lastIdx);
409 lastIndexes[ilink] = lastIdx;
413bool GBTRawDataChecker::checkEvents(
bool isTriggered)
417 auto& boards = isTriggered ? mBoardsTrig : mBoardsSelfTrig;
418 auto& orderedIndexes = isTriggered ? mOrderedIndexesTrig : mOrderedIndexesSelfTrig;
421 for (
auto& evtIdxItem : orderedIndexes) {
424 for (
auto& evtPair : evtIdxItem.second) {
425 auto& boardInfo = boards[evtPair.first][evtPair.second];
428 gbtEvent.locs.push_back(boardInfo.board);
430 gbtEvent.regs.push_back(boardInfo.board);
432 if (boardInfo.page >= 0) {
433 if (std::find(gbtEvent.pages.begin(), gbtEvent.pages.end(), boardInfo.page) == gbtEvent.pages.end()) {
434 gbtEvent.pages.push_back(boardInfo.page);
440 if (!checkEvent(isTriggered, gbtEvent.regs, gbtEvent.locs,
ir)) {
441 std::stringstream ss;
442 ss << fmt::format(
"BCid: 0x{:x} Orbit: 0x{:x}",
ir.
bc,
ir.
orbit);
443 if (!gbtEvent.pages.empty()) {
445 for (
auto& page : gbtEvent.pages) {
446 ss << std::dec <<
" page: " << page <<
" (line: " << 512 * page + 1 <<
") ";
452 ss << mEventDebugMsg <<
"\n";
453 mDebugMsg += ss.str();
461bool GBTRawDataChecker::process(gsl::span<const ROBoard> localBoards, gsl::span<const ROFRecord> rofRecords, gsl::span<const ROFRecord> pageRecords)
467 for (
auto rofIt = rofRecords.begin(); rofIt != rofRecords.end(); ++rofIt) {
468 if (rofIt->interactionRecord.orbit == 0xffffffff) {
472 for (
auto locIt = localBoards.begin() + rofIt->firstEntry; locIt != localBoards.begin() + rofIt->firstEntry + rofIt->nEntries; ++locIt) {
476 for (
auto& rofPage : pageRecords) {
477 if (rofIt->firstEntry >= rofPage.firstEntry && rofIt->firstEntry < rofPage.firstEntry + rofPage.nEntries) {
478 page = rofPage.interactionRecord.orbit;
485 auto id = getElinkId(*locIt);
486 auto& elinkVec = (locIt->triggerWord == 0) ? mBoardsSelfTrig[
id] : mBoardsTrig[
id];
487 elinkVec.push_back({*locIt, rofIt->interactionRecord, page});
489 auto& busyVec = mBusyPeriods[
id];
490 bool wasBusy = !busyVec.empty() && busyVec.back().isBusy;
491 bool isBusy = locIt->statusWord & raw::sREJECTING;
496 busyVec.push_back({
isBusy, getRawIR(
id, locIt->triggerWord != 0, rofIt->interactionRecord)});
499 if (locIt->triggerWord == 0) {
504 if (locIt->triggerWord & mSyncTrigger) {
505 mTrigEvents[rofIt->interactionRecord] |= (1 <<
id);
507 if (locIt->triggerWord & raw::sORB) {
508 mResetVal = rofIt->interactionRecord.bc + 1;
512 if (locIt->triggerWord & raw::sSOX) {
514 auto maskItem = mMasks.find(locIt->boardId);
516 if (maskItem == mMasks.end()) {
518 auto&
mask = mMasks[locIt->boardId];
519 for (
int ich = 0; ich < 4; ++ich) {
520 mask.patternsBP[ich] = locIt->patternsBP[ich];
521 mask.patternsNBP[ich] = locIt->patternsNBP[ich];
529 return runCheckEvents(getLastCompleteTrigEvent());
Class to check the raw data from a GBT link.
bool process(gsl::span< const ROBoard > localBoards, gsl::span< const ROFRecord > rofRecords, gsl::span< const ROFRecord > pageRecords)
void clear(bool all=false)
void init(uint16_t gbtUniqueId, uint8_t mask)
bool isOk(ResultWas::OfType resultType)
uint8_t itsSharedClusterMap uint8_t
bool isCalibration(uint8_t triggerWord)
bool isLoc(uint8_t statusWord)
uint8_t getLocId(uint8_t uniqueLocId)
void applyElectronicsDelay(uint32_t &orbit, uint16_t &bc, int16_t delay, uint16_t maxBunches=constants::lhc::LHCMaxBunches)
@ GBT
GBT encoded raw data.
Enum< T >::Iterator begin(Enum< T >)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint16_t bc
bunch crossing ID of interaction
void setFromLong(int64_t l)
int16_t localToReg
Delay between regional board and local board answers.
int16_t localToBC
Delay between collision BC and local clock.
std::array< uint16_t, 4 > patternsNBP
Bending plane pattern.
std::array< uint16_t, 4 > patternsBP
Fired chambers.
uint8_t firedChambers
Board ID in crate.
o2::InteractionRecord ir(0, 0)