17#define BOOST_TEST_MODULE Test MID raw
18#define BOOST_TEST_DYN_LINK
20#include <boost/test/unit_test.hpp>
22#include <boost/test/data/test_case.hpp>
42BOOST_AUTO_TEST_SUITE(o2_mid_raw)
44o2::mid::ColumnData
getColData(uint8_t deId, uint8_t columnId, uint16_t nbp = 0, uint16_t bp1 = 0, uint16_t bp2 = 0, uint16_t bp3 = 0, uint16_t bp4 = 0)
48 col.columnId = columnId;
49 col.setNonBendPattern(nbp);
50 col.setBendPattern(bp1, 0);
51 col.setBendPattern(bp2, 1);
52 col.setBendPattern(bp3, 2);
53 col.setBendPattern(bp4, 3);
57std::vector<o2::mid::ColumnData>
sortData(
const std::vector<o2::mid::ColumnData>&
data,
size_t first,
size_t last)
59 std::vector<o2::mid::ColumnData> sortedData(
data.begin() +
first,
data.begin() + last);
62}return (
a.deId <
b.deId); });
68 BOOST_REQUIRE(rofRecords.size() == inData.size());
69 auto inItMap = inData.begin();
70 for (
auto rofIt = rofRecords.begin(); rofIt != rofRecords.end(); ++rofIt) {
71 BOOST_TEST(
static_cast<int>(rofIt->eventType) ==
static_cast<int>(inEventType));
72 BOOST_TEST(rofIt->interactionRecord == inItMap->first);
73 BOOST_TEST(rofIt->nEntries == inItMap->second.size());
74 auto sortedIn =
sortData(inItMap->second, 0, inItMap->second.size());
75 auto sortedOut =
sortData(
data, rofIt->firstEntry, rofIt->firstEntry + rofIt->nEntries);
76 BOOST_REQUIRE(sortedOut.size() == sortedIn.size());
77 for (
size_t icol = 0; icol < sortedOut.size(); ++icol) {
78 BOOST_TEST(sortedOut[icol].deId == sortedIn[icol].deId);
79 BOOST_TEST(sortedOut[icol].columnId == sortedIn[icol].columnId);
80 BOOST_TEST(sortedOut[icol].getNonBendPattern() == sortedIn[icol].getNonBendPattern());
81 for (
int iline = 0; iline < 4; ++iline) {
82 BOOST_TEST(sortedOut[icol].getBendPattern(iline) == sortedIn[icol].getBendPattern(iline));
91 auto severity = fair::Logger::GetConsoleSeverity();
92 fair::Logger::SetConsoleSeverity(fair::Severity::warning);
95 std::string tmpConfigFilename =
"tmp_MIDConfig.cfg";
96 encoder.
getWriter().writeConfFile(
"MID",
"RAWDATA", tmpConfigFilename.c_str(),
false);
97 for (
auto& item : inData) {
98 encoder.
process(item.second, item.first, inEventType);
107 for (
size_t ilink = 0; ilink < rawReader.
getNLinks(); ++ilink) {
108 auto& link = rawReader.
getLink(ilink);
113 std::vector<char> linkBuffer(tfsz);
114 link.readNextTF(linkBuffer.data());
115 buffer.insert(
buffer.end(), linkBuffer.begin(), linkBuffer.end());
118 fair::Logger::SetConsoleSeverity(
severity);
120 std::remove(
"MID.raw");
121 std::remove(tmpConfigFilename.c_str());
124 gsl::span<const uint8_t>
data(
reinterpret_cast<uint8_t*
>(
buffer.data()),
buffer.size());
135 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
141 inData[
ir].emplace_back(
getColData(3, 4, 0xFF00, 0xFF));
145 inData[
ir].emplace_back(
getColData(5, 1, 0xFF00, 0xFF));
146 inData[
ir].emplace_back(
getColData(14, 1, 0, 0, 0, 0xFF));
148 std::vector<o2::mid::ROFRecord> rofs;
149 std::vector<o2::mid::ROBoard> outData;
152 for (
auto& item : inData) {
153 converter.
process(item.second);
154 auto firstEntry = outData.size();
155 for (
auto& board : converter.
getData()) {
156 outData.emplace_back(board);
157 rofs.push_back({item.first, inEventType, firstEntry, outData.size() - firstEntry});
162 aggregator.
process(outData, rofs);
172 board.patternsBP[0] = 2;
173 board.patternsNBP[0] = 1;
177 std::vector<o2::mid::ROBoard> locBoards{board};
179 BOOST_REQUIRE(regBoard.size() == 1);
188 std::map<uint16_t, std::vector<o2::mid::ROBoard>> inData;
192 loc.
statusWord = o2::mid::raw::sSTARTBIT | o2::mid::raw::sCARDTYPE;
198 inData[
bc].emplace_back(loc);
207 inData[
bc].emplace_back(loc);
213 uint8_t linkInCrate = 0;
218 for (
auto& item : inData) {
223 std::vector<char>
buf;
226 auto memSize =
buf.size() + 64;
227 rdh.
word1 |= (memSize | (memSize << 16));
229 uint16_t feeId = feeIdConfig.
getFEEId(gbtUniqueId);
230 rdh.
word0 |= (feeId << 16);
232 std::vector<o2::mid::ROBoard>
data;
233 std::vector<o2::mid::ROFRecord> rofs;
234 std::vector<uint8_t> convertedBuffer(
buf.size());
235 memcpy(convertedBuffer.data(),
buf.data(),
buf.size());
236 decoder->process(convertedBuffer, rdh,
data, rofs);
237 BOOST_REQUIRE(rofs.size() == inData.size());
238 auto inItMap = inData.begin();
239 for (
auto rofIt = rofs.begin(); rofIt != rofs.end(); ++rofIt) {
240 BOOST_TEST(rofIt->interactionRecord.bc == inItMap->first);
241 BOOST_TEST(rofIt->nEntries == inItMap->second.size());
242 auto outLoc =
data.begin() + rofIt->firstEntry;
243 for (
auto inLoc = inItMap->second.begin(); inLoc != inItMap->second.end(); ++inLoc) {
244 BOOST_TEST(inLoc->statusWord == outLoc->statusWord);
245 BOOST_TEST(inLoc->triggerWord == outLoc->triggerWord);
247 BOOST_TEST(inLoc->firedChambers == outLoc->firedChambers);
248 for (
int ich = 0; ich < 4; ++ich) {
249 BOOST_TEST(inLoc->patternsBP[ich] == outLoc->patternsBP[ich]);
250 BOOST_TEST(inLoc->patternsNBP[ich] == outLoc->patternsNBP[ich]);
262 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
268 inData[
ir].emplace_back(
getColData(11, 4, 0x3, 0xFFFF));
271 inData[
ir].emplace_back(
getColData(5, 1, 0xFFFF, 0, 0xF, 0xF0));
273 inData[
ir].emplace_back(
getColData(41, 2, 0xFF0F, 0, 0xF0FF, 0xF));
277 inData[
ir].emplace_back(
getColData(70, 3, 0xFF00, 0xFF));
281 inData[
ir].emplace_back(
getColData(70, 3, 0xFF00, 0xFF));
291 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
294 for (
int irepeat = 0; irepeat < 4000; ++irepeat) {
303 inData[
ir].emplace_back(
getColData(ide, icol, 0xFF00, 0xFFFF));
312BOOST_AUTO_TEST_SUITE_END()
Converter from ColumnData to raw local boards.
Strip pattern (aka digits)
MID decoded raw data aggregator.
Useful detector parameters for MID.
Raw data encoder for MID GBT user logic.
Class interface for the MID link decoder.
Structure to store the readout board information.
Reader for (multiple) raw data files.
std::vector< ROBoard > getData() const
Gets vector of ROBoard.
void process(gsl::span< const ColumnData > data, bool allowEmpty=false)
const std::vector< ROFRecord > & getROFRecords(EventType eventType=EventType::Standard)
Gets the vector of data RO frame records.
void process(gsl::span< const ROBoard > localBoards, gsl::span< const ROFRecord > rofRecords)
const std::vector< ColumnData > & getData(EventType eventType=EventType::Standard)
Gets the vector of data.
const std::vector< ROFRecord > & getROFRecords() const
Gets the vector of data RO frame records.
const std::vector< ROBoard > & getData() const
Gets the vector of data.
void process(gsl::span< const uint8_t > bytes)
void finalize(bool closeFile=true)
void init(std::string_view outDir=".", std::string_view fileFor="all", int verbosity=0, std::vector< ROBoardConfig > configurations=makeDefaultROBoardConfig())
void process(gsl::span< const ColumnData > data, InteractionRecord ir, EventType eventType=EventType::Standard)
uint16_t getFEEId(uint16_t gbtUniqueId) const
Gets the FEE ID from the GBT unique ID.
void process(gsl::span< const ROBoard > data, InteractionRecord ir)
void flush(std::vector< char > &buffer, const InteractionRecord &ir)
void setConfig(uint16_t gbtUniqueId, const std::vector< ROBoardConfig > &configurations)
int getFirstBoardBP(int column, int deId) const
std::vector< ROBoard > getRegionalResponse(const std::vector< ROBoard > &locs) const
bool isZeroSuppressed(const ROBoard &loc) const
Returns true if the local board has no fired digits after zero suppression.
void setNextTFToRead(uint32_t tf)
uint32_t getNTimeFrames() const
const LinkData & getLink(int i) const
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
GLenum GLuint GLenum GLsizei const GLchar * buf
uint16_t makeGBTUniqueId(uint8_t crateId, uint8_t gbtId)
Builds the GBT unique ID from the crate ID and the GBT ID in the crate.
constexpr int NDetectionElements
Number of RPCs.
uint8_t makeUniqueLocID(uint8_t crateId, uint8_t locId)
void applyElectronicsDelay(uint32_t &orbit, uint16_t &bc, int16_t delay, uint16_t maxBunches=constants::lhc::LHCMaxBunches)
std::vector< ROBoardConfig > makeNoZSROBoardConfig(uint16_t gbtUniqueId=0xFFFF)
std::unique_ptr< LinkDecoder > createLinkDecoder(const o2::header::RDHAny &rdh, uint16_t feeId, bool isDebugMode, uint8_t mask, const ElectronicsDelay &electronicsDelay, const FEEIdConfig &feeIdConfig)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint16_t bc
bunch crossing ID of interaction
Column data structure for MID.
uint8_t deId
Index of the detection element.
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 boardId
Trigger word.
uint8_t triggerWord
Status word.
uint8_t firedChambers
Board ID in crate.
size_t getNextTFSize() const
BOOST_AUTO_TEST_CASE(ColumnDataConverter)
void doTest(const std::map< o2::InteractionRecord, std::vector< o2::mid::ColumnData > > &inData, const std::vector< o2::mid::ROFRecord > &rofRecords, const std::vector< o2::mid::ColumnData > &data, const o2::mid::EventType inEventType=o2::mid::EventType::Standard)
o2::mid::ColumnData getColData(uint8_t deId, uint8_t columnId, uint16_t nbp=0, uint16_t bp1=0, uint16_t bp2=0, uint16_t bp3=0, uint16_t bp4=0)
std::tuple< std::vector< o2::mid::ColumnData >, std::vector< o2::mid::ROFRecord > > encodeDecode(std::map< o2::InteractionRecord, std::vector< o2::mid::ColumnData > > inData, o2::mid::EventType inEventType=o2::mid::EventType::Standard)
std::vector< o2::mid::ColumnData > sortData(const std::vector< o2::mid::ColumnData > &data, size_t first, size_t last)
o2::InteractionRecord ir(0, 0)
BOOST_TEST(digits==digitsD, boost::test_tools::per_element())