20#include <fmt/format.h>
31 for (
int ich = 0; ich < 4; ++ich) {
44 return fmt::format(
"BCid: 0x{:x} Orbit: 0x{:x}",
ir.
bc,
ir.
orbit);
47uint32_t UserLogicChecker::getId(
const ROBoard& board)
const
50 uint32_t
id =
static_cast<uint32_t
>(board.boardId);
57void UserLogicChecker::fillBoards(gsl::span<const ROBoard>
data, gsl::span<const ROFRecord> rofRecords,
bool isUL)
61 auto& boards = isUL ? mBoardsUL : mBoardsBare;
65 for (
auto rofIt = rofRecords.begin(); rofIt != rofRecords.end(); ++rofIt) {
66 auto& loc =
data[rofIt->firstEntry];
68 auto isInside = mInsideDataTaking.find(
id);
69 if (
isInside == mInsideDataTaking.end()) {
70 mInsideDataTaking[
id] =
false;
71 isInside = mInsideDataTaking.find(
id);
73 if (loc.triggerWord & raw::sSOX) {
75 }
else if (loc.triggerWord & raw::sEOX) {
78 if (loc.triggerWord & raw::sPHY) {
82 boards[
id].push_back({rofIt->interactionRecord, loc});
87void UserLogicChecker::clearBoards()
91 for (
int itype = 0; itype < 2; ++itype) {
92 auto& boards = (itype == 0) ? mBoardsUL : mBoardsBare;
93 auto& lastChecked = (itype == 0) ? mLastCheckedUL : mLastCheckedBare;
94 std::unordered_map<uint32_t, std::vector<boardInfo>> newBoards;
95 for (
auto& boardItem : boards) {
96 auto lastIdxItem = lastChecked.find(boardItem.first);
97 if (lastIdxItem->second != boardItem.second.size()) {
98 auto&
vec = newBoards[boardItem.first];
99 vec.insert(
vec.end(), boardItem.second.begin() + lastIdxItem->second, boardItem.second.end());
102 boards.swap(newBoards);
107bool UserLogicChecker::checkBoards(gsl::span<const ROBoard> bareData, gsl::span<const ROFRecord> bareRofs, gsl::span<const ROBoard> ulData, gsl::span<const ROFRecord> ulRofs)
111 fillBoards(bareData, bareRofs,
false);
112 fillBoards(ulData, ulRofs,
true);
115 for (
auto& bareItem : mBoardsBare) {
116 std::string boardType = (bareItem.first < 0x10000) ?
"Loc" :
"Reg";
117 auto& lastCheckedBare = mLastCheckedBare[bareItem.first];
118 auto& stats = mStatistics[bareItem.first];
119 stats[0] += bareItem.second.size();
120 std::stringstream ss;
121 ss <<
"\n-----------" << std::endl;
122 uint16_t boardId = (bareItem.first & 0xFFFF);
124 <<
" " << boardType <<
" board: " <<
static_cast<int>(
raw::getLocId(boardId)) << std::endl;
125 auto ulItem = mBoardsUL.find(bareItem.first);
126 if (ulItem == mBoardsUL.end()) {
127 ss <<
" cannot find " << printIRHex(bareItem.second.front().interactionRecord) <<
" in ul" << std::endl;
129 ss <<
"-----------" << std::endl;
130 mDebugMsg += ss.str();
131 stats[1] += bareItem.second.size();
134 auto& lastCheckedUL = mLastCheckedUL[ulItem->first];
136 auto lastOk = lastCheckedUL;
137 bool isCurrentOk =
true;
138 for (lastCheckedBare = 0; lastCheckedBare < bareItem.second.size(); ++lastCheckedBare) {
139 if (lastCheckedUL == ulItem->second.size()) {
141 }
else if (!isSame(ulItem->second[lastCheckedUL].board, bareItem.second[lastCheckedBare].board) || ulItem->second[lastCheckedUL].interactionRecord != bareItem.second[lastCheckedBare].interactionRecord) {
142 ss <<
"\nFirst divergence at element " << lastCheckedBare + 1 <<
" / " << bareItem.second.size() <<
":" << std::endl;
143 ss <<
"bare: " << printIRHex(bareItem.second[lastCheckedBare].interactionRecord) << std::endl;
144 ss << bareItem.second[lastCheckedBare].board << std::endl;
145 ss <<
"ul: " << printIRHex(ulItem->second[lastCheckedUL].interactionRecord) << std::endl;
146 ss << ulItem->second[lastCheckedUL].board << std::endl;
150 if (lastOk != lastCheckedUL) {
151 ss <<
"lastOk: " << printIRHex(ulItem->second[lastOk].interactionRecord) << std::endl;
152 ss << ulItem->second[lastOk].board << std::endl;
154 ss <<
"lastOk: none. This is the first event!" << std::endl;
156 ss <<
"-----------" << std::endl;
157 mDebugMsg += ss.str();
158 stats[1] += lastCheckedUL;
159 lastCheckedUL = ulItem->second.size();
160 lastCheckedBare = bareItem.second.size();
164 lastOk = lastCheckedUL;
171std::unordered_map<uint64_t, std::vector<size_t>> UserLogicChecker::getOrderedIndexes(gsl::span<const ROFRecord> rofRecords)
const
174 std::unordered_map<uint64_t, std::vector<size_t>> orderIndexes;
175 for (
auto rofIt = rofRecords.begin(); rofIt != rofRecords.end(); ++rofIt) {
177 orderIndexes[rofIt->interactionRecord.toLong()].emplace_back(rofIt->firstEntry);
182bool UserLogicChecker::checkAll(gsl::span<const ROBoard> bareData, gsl::span<const ROFRecord> bareRofs, gsl::span<const ROBoard> ulData, gsl::span<const ROFRecord> ulRofs)
184 auto bareIndexes = getOrderedIndexes(bareRofs);
185 auto ulIndexes = getOrderedIndexes(ulRofs);
188 std::stringstream ss;
189 InteractionRecord
ir;
190 for (
auto& bareItem : bareIndexes) {
191 auto ulItem = ulIndexes.find(bareItem.first);
193 if (ulItem == ulIndexes.end()) {
195 ss <<
"\nCannot find: " << printIRHex(
ir) <<
" in ul\n";
198 std::vector<size_t> auxVec = ulItem->second;
199 for (
auto& idx1 : bareItem.second) {
201 for (
auto auxIt = auxVec.begin(); auxIt != auxVec.end(); ++auxIt) {
202 if (isSame(bareData[idx1], ulData[*auxIt])) {
210 ss <<
"\nOnly in bare: " << printIRHex(
ir) <<
"\n";
211 ss <<
" " << bareData[idx1] <<
"\n";
214 for (
auto& idx2 : auxVec) {
216 ss <<
"\nOnly in ul: " << printIRHex(
ir) <<
"\n";
217 ss <<
" " << ulData[idx2] <<
"\n";
221 for (
auto& ulItem : ulIndexes) {
222 auto bareItem = bareIndexes.find(ulItem.first);
223 if (bareItem == bareIndexes.end()) {
226 ss <<
"\nCannot find: " << printIRHex(
ir) <<
" in bare\n";
229 mDebugMsg = ss.str();
233bool UserLogicChecker::process(gsl::span<const ROBoard> bareData, gsl::span<const ROFRecord> bareRofs, gsl::span<const ROBoard> ulData, gsl::span<const ROFRecord> ulRofs,
bool isFull)
237 return isFull ? checkAll(bareData, bareRofs, ulData, ulRofs) : checkBoards(bareData, bareRofs, ulData, ulRofs);
243 mInsideDataTaking.clear();
250 std::stringstream ss;
251 for (
auto& statItem : mStatistics) {
252 std::string boardType = (statItem.first < 0x10000) ?
"Loc" :
"Reg";
253 double badFraction = (statItem.second[0] == 0) ? 0. :
static_cast<double>(statItem.second[1]) /
static_cast<double>(statItem.second[0]);
254 uint16_t boardId = (statItem.first & 0xFFFF);
255 ss <<
"Crate: " <<
static_cast<int>(
raw::getCrateId(boardId)) <<
" " << boardType <<
" board: " <<
static_cast<int>(
raw::getLocId(boardId)) <<
" fraction of events not in sync: " << statItem.second[1] <<
" / " << statItem.second[0] <<
" = " << badFraction << std::endl;
Class to check the CRU user logic.
bool process(gsl::span< const ROBoard > bareData, gsl::span< const ROFRecord > bareRofs, gsl::span< const ROBoard > ulData, gsl::span< const ROFRecord > ulRofs, bool isFull=false)
std::string getSummary() const
bool isOk(ResultWas::OfType resultType)
uint8_t getCrateId(uint8_t uniqueLocId)
bool isLoc(uint8_t statusWord)
uint8_t getLocId(uint8_t uniqueLocId)
bool isInside(double localX, double localY, const std::vector< PreCluster > &sortedPC, std::string &errorMsg)
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)
std::array< uint16_t, 4 > patternsNBP
Bending plane pattern.
std::array< uint16_t, 4 > patternsBP
Fired chambers.
uint8_t boardId
Trigger word.
uint8_t triggerWord
Status word.
uint8_t firedChambers
Board ID in crate.
std::vector< o2::ctf::BufferType > vec
o2::InteractionRecord ir(0, 0)