Project
Loading...
Searching...
No Matches
testRaw.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
16
17#define BOOST_TEST_MODULE Test MID raw
18#define BOOST_TEST_DYN_LINK
19
20#include <boost/test/unit_test.hpp>
21
22#include <boost/test/data/test_case.hpp>
23#include <vector>
24#include <map>
25#include "Framework/Logger.h"
32#include "MIDBase/Mapping.h"
36#include "MIDRaw/Decoder.h"
37#include "MIDRaw/Encoder.h"
39#include "MIDRaw/LinkDecoder.h"
41
42BOOST_AUTO_TEST_SUITE(o2_mid_raw)
43
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)
45{
47 col.deId = deId;
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);
54 return col;
55}
56
57std::vector<o2::mid::ColumnData> sortData(const std::vector<o2::mid::ColumnData>& data, size_t first, size_t last)
58{
59 std::vector<o2::mid::ColumnData> sortedData(data.begin() + first, data.begin() + last);
60 std::sort(sortedData.begin(), sortedData.end(), [](o2::mid::ColumnData& a, o2::mid::ColumnData& b) { if (a.deId == b.deId ) { return (a.columnId < b.columnId);
61
62}return (a.deId < b.deId); });
63 return sortedData;
64}
65
66void 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)
67{
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));
83 }
84 }
85 ++inItMap;
86 }
87}
88
89std::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)
90{
91 auto severity = fair::Logger::GetConsoleSeverity();
92 fair::Logger::SetConsoleSeverity(fair::Severity::warning);
93 o2::mid::Encoder encoder;
94 encoder.init();
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);
99 }
100 encoder.finalize();
101
102 o2::raw::RawFileReader rawReader(tmpConfigFilename.c_str());
103 rawReader.init();
104 std::vector<char> buffer;
105 for (size_t itf = 0; itf < rawReader.getNTimeFrames(); ++itf) {
106 rawReader.setNextTFToRead(itf);
107 for (size_t ilink = 0; ilink < rawReader.getNLinks(); ++ilink) {
108 auto& link = rawReader.getLink(ilink);
109 auto tfsz = link.getNextTFSize();
110 if (!tfsz) {
111 continue;
112 }
113 std::vector<char> linkBuffer(tfsz);
114 link.readNextTF(linkBuffer.data());
115 buffer.insert(buffer.end(), linkBuffer.begin(), linkBuffer.end());
116 }
117 }
118 fair::Logger::SetConsoleSeverity(severity);
119
120 std::remove("MID.raw");
121 std::remove(tmpConfigFilename.c_str());
122
123 o2::mid::Decoder decoder;
124 gsl::span<const uint8_t> data(reinterpret_cast<uint8_t*>(buffer.data()), buffer.size());
125 decoder.process(data);
126
128 aggregator.process(decoder.getData(), decoder.getROFRecords());
129
130 return std::make_tuple(aggregator.getData(), aggregator.getROFRecords());
131}
132
133BOOST_AUTO_TEST_CASE(ColumnDataConverter)
134{
135 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
137 // Crate 5 link 0
138 inData[ir].emplace_back(getColData(2, 4, 0x1, 0xFFFF));
139
140 ir.bc = 200;
141 inData[ir].emplace_back(getColData(3, 4, 0xFF00, 0xFF));
142 inData[ir].emplace_back(getColData(12, 4, 0, 0, 0xFF));
143
144 ir.bc = 400;
145 inData[ir].emplace_back(getColData(5, 1, 0xFF00, 0xFF));
146 inData[ir].emplace_back(getColData(14, 1, 0, 0, 0, 0xFF));
147
148 std::vector<o2::mid::ROFRecord> rofs;
149 std::vector<o2::mid::ROBoard> outData;
150 auto inEventType = o2::mid::EventType::Standard;
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});
158 }
159 }
160
162 aggregator.process(outData, rofs);
163
164 doTest(inData, aggregator.getROFRecords(), aggregator.getData());
165}
166
168{
170
171 o2::mid::ROBoard board{o2::mid::raw::sSTARTBIT | o2::mid::raw::sCARDTYPE, 0, o2::mid::raw::makeUniqueLocID(5, 8), 1};
172 board.patternsBP[0] = 2;
173 board.patternsNBP[0] = 1;
174
175 BOOST_TEST(response.isZeroSuppressed(board) == false);
176
177 std::vector<o2::mid::ROBoard> locBoards{board};
178 auto regBoard = response.getRegionalResponse(locBoards);
179 BOOST_REQUIRE(regBoard.size() == 1);
180 BOOST_TEST(board.boardId == 0x58);
181 BOOST_TEST(board.firedChambers = 0x1);
182}
183
184BOOST_AUTO_TEST_CASE(GBTUserLogicDecoder)
185{
187
188 std::map<uint16_t, std::vector<o2::mid::ROBoard>> inData;
189 uint16_t bc = 100;
191 // Crate 5 link 0
192 loc.statusWord = o2::mid::raw::sSTARTBIT | o2::mid::raw::sCARDTYPE;
193 loc.triggerWord = 0;
194 loc.boardId = 0x52;
195 loc.firedChambers = 0x1;
196 loc.patternsBP[0] = 0xF;
197 loc.patternsNBP[0] = 0xF;
198 inData[bc].emplace_back(loc);
199
200 bc = 200;
201 loc.patternsBP.fill(0);
202 loc.patternsNBP.fill(0);
203 loc.boardId = 0x55;
204 loc.firedChambers = 0x4;
205 loc.patternsBP[2] = 0xF0;
206 loc.patternsNBP[2] = 0x5;
207 inData[bc].emplace_back(loc);
208
209 o2::mid::ElectronicsDelay electronicsDelay;
210
211 o2::mid::FEEIdConfig feeIdConfig;
212 uint8_t crateId = 5;
213 uint8_t linkInCrate = 0;
214 uint16_t gbtUniqueId = o2::mid::crateparams::makeGBTUniqueId(crateId, linkInCrate);
216 encoder.setConfig(gbtUniqueId, o2::mid::makeNoZSROBoardConfig(gbtUniqueId));
217
218 for (auto& item : inData) {
219 o2::InteractionRecord ir(item.first, 0);
221 encoder.process(item.second, ir);
222 }
223 std::vector<char> buf;
224 encoder.flush(buf, o2::InteractionRecord());
226 auto memSize = buf.size() + 64;
227 rdh.word1 |= (memSize | (memSize << 16));
228 // Sets the linkId
229 uint16_t feeId = feeIdConfig.getFEEId(gbtUniqueId);
230 rdh.word0 |= (feeId << 16);
231 auto decoder = o2::mid::createLinkDecoder(feeId);
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);
246 BOOST_TEST(o2::mid::raw::makeUniqueLocID(crateId, inLoc->boardId) == outLoc->boardId);
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]);
251 }
252 ++outLoc;
253 }
254 ++inItMap;
255 }
256}
257
259{
261
262 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
263 // Small standard event
265
266 // Crate 5 link 0
267 inData[ir].emplace_back(getColData(2, 4, 0x1, 0xFFFF));
268 inData[ir].emplace_back(getColData(11, 4, 0x3, 0xFFFF));
269
270 // Crate 1 link 1 and crate 2 link 0
271 inData[ir].emplace_back(getColData(5, 1, 0xFFFF, 0, 0xF, 0xF0));
272 // Crate 10 link 1 and crate 11 link 1
273 inData[ir].emplace_back(getColData(41, 2, 0xFF0F, 0, 0xF0FF, 0xF));
274 ir.bc = 0xde6;
275 ir.orbit = 2;
276 // Crate 12 link 1
277 inData[ir].emplace_back(getColData(70, 3, 0xFF00, 0xFF));
278
279 ir.bc = 0xdea;
280 ir.orbit = 3;
281 inData[ir].emplace_back(getColData(70, 3, 0xFF00, 0xFF));
282
283 auto [data, rofs] = encodeDecode(inData);
284
285 doTest(inData, rofs, data);
286}
287
288BOOST_AUTO_TEST_CASE(LargeBufferSample)
289{
290 o2::mid::Mapping mapping;
291 std::map<o2::InteractionRecord, std::vector<o2::mid::ColumnData>> inData;
292 // Big event that should pass the 8kB
294 for (int irepeat = 0; irepeat < 4000; ++irepeat) {
295 ++ir;
296 for (int ide = 0; ide < o2::mid::detparams::NDetectionElements; ++ide) {
297 // Since we have 1 RDH per GBT, we can put data only on 1 column
298 int icol = 4;
299 // for (int icol = mapping.getFirstColumn(ide); icol < 7; ++icol) {
300 if (mapping.getFirstBoardBP(icol, ide) != 0) {
301 continue;
302 }
303 inData[ir].emplace_back(getColData(ide, icol, 0xFF00, 0xFFFF));
304 }
305 }
306
307 auto [data, rofs] = encodeDecode(inData);
308
309 doTest(inData, rofs, data);
310}
311
312BOOST_AUTO_TEST_SUITE_END()
Converter from ColumnData to raw local boards.
Strip pattern (aka digits)
MID RO crate parameters.
MID decoded raw data aggregator.
Useful detector parameters for MID.
MID raw data decoder.
MID raw data encoder.
uint64_t bc
Definition RawEventData.h:5
Raw data encoder for MID GBT user logic.
Class interface for the MID link decoder.
Mapping for MID.
Definition of the RAW Data Header.
Local board response.
Structure to store the readout board information.
uint32_t col
Definition RawData.h:4
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.
Definition Decoder.h:67
const std::vector< ROBoard > & getData() const
Gets the vector of data.
Definition Decoder.h:64
void process(gsl::span< const uint8_t > bytes)
Definition Decoder.cxx:48
auto & getWriter()
Definition Encoder.h:51
void finalize(bool closeFile=true)
Definition Encoder.cxx:131
void init(std::string_view outDir=".", std::string_view fileFor="all", int verbosity=0, std::vector< ROBoardConfig > configurations=makeDefaultROBoardConfig())
Definition Encoder.cxx:30
void process(gsl::span< const ColumnData > data, InteractionRecord ir, EventType eventType=EventType::Standard)
Definition Encoder.cxx:150
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
Definition Mapping.cxx:178
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
GLuint buffer
Definition glcorearb.h:655
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean * data
Definition glcorearb.h:298
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLenum GLenum severity
Definition glcorearb.h:2513
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glcorearb.h:2514
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)
Definition ROBoard.h:86
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 ...
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
Column data structure for MID.
Definition ColumnData.h:29
uint8_t deId
Index of the detection element.
Definition ColumnData.h:30
int16_t localToBC
Delay between collision BC and local clock.
std::array< uint16_t, 4 > patternsNBP
Bending plane pattern.
Definition ROBoard.h:33
std::array< uint16_t, 4 > patternsBP
Fired chambers.
Definition ROBoard.h:32
uint8_t statusWord
Definition ROBoard.h:28
uint8_t boardId
Trigger word.
Definition ROBoard.h:30
uint8_t triggerWord
Status word.
Definition ROBoard.h:29
uint8_t firedChambers
Board ID in crate.
Definition ROBoard.h:31
BOOST_AUTO_TEST_CASE(ColumnDataConverter)
Definition testRaw.cxx:133
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)
Definition testRaw.cxx:66
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)
Definition testRaw.cxx:44
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)
Definition testRaw.cxx:89
std::vector< o2::mid::ColumnData > sortData(const std::vector< o2::mid::ColumnData > &data, size_t first, size_t last)
Definition testRaw.cxx:57
o2::InteractionRecord ir(0, 0)
BOOST_TEST(digits==digitsD, boost::test_tools::per_element())