Project
Loading...
Searching...
No Matches
RawDecoder.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#include <fairlogger/Logger.h>
15#include "InfoLogger/InfoLogger.hxx"
17#include "CPVBase/Geometry.h"
18
19using namespace o2::cpv;
20
21RawDecoder::RawDecoder(RawReaderMemory& reader) : mRawReader(reader),
22 mChannelsInitialized(false),
23 mIsMuteErrors(false)
24{
25}
26
28{
29 // auto& rdh = mRawReader.getRawHeader();
30 // short linkID = o2::raw::RDHUtils::getLinkID(rdh);
31 mDigits.clear();
32 mBCRecords.clear();
33
34 auto payloadWords = mRawReader.getPayload();
35 if (payloadWords.size() == 0) {
36 return kOK_NO_PAYLOAD;
37 }
38
39 return readChannels();
40}
41
43{
44 mChannelsInitialized = false;
45 // // test error
46 // if (!mIsMuteErrors) {
47 // LOG(error) << "RawDecoder::readChannels() : "
48 // << "test error";
49 // }
50 // mErrors.emplace_back(-1, 0, 0, 0, kOK); //5 is non-existing link with general errors
51
52 uint8_t dataFormat = mRawReader.getDataFormat();
53 int wordLength;
54 if (dataFormat == 0x0) {
55 wordLength = 16; // 128 bits word with padding
56 } else if (dataFormat == 0x2) {
57 wordLength = 10; // 80 bits word without padding
58 } else {
60 }
61 auto& payloadWords = mRawReader.getPayload();
62 uint32_t wordCountFromLastHeader = 1; // header word is included
63 int nDigitsAddedFromLastHeader = 0;
64 bool isHeaderExpected = true; // true if we expect to read header, false otherwise
65 bool skipUntilNextHeader = true; // true if something wrong with data format, try to read next header
66 uint16_t currentBC;
67 uint32_t currentOrbit = mRawReader.getCurrentHBFOrbit();
68 auto b = payloadWords.cbegin();
69 auto e = payloadWords.cend();
70 while (b != e) { // payload must start with cpvheader folowed by cpvwords and finished with cpvtrailer
71 CpvHeader header(b, e);
72 if (header.isOK()) {
73 LOG(debug) << "RawDecoder::readChannels() : "
74 << "I read cpv header for orbit = " << header.orbit()
75 << " and BC = " << header.bc();
76 if (!isHeaderExpected) { // actually, header was not expected
77 if (!mIsMuteErrors) {
78 LOG(error) << "RawDecoder::readChannels() : "
79 << "header was not expected";
80 }
81 removeLastNDigits(nDigitsAddedFromLastHeader); // remove previously added digits as they are bad
82 mErrors.emplace_back(-1, 0, 0, 0, kNO_CPVTRAILER);
83 }
84 skipUntilNextHeader = false;
85 currentBC = header.bc();
86 wordCountFromLastHeader = 0;
87 nDigitsAddedFromLastHeader = 0;
88 if (currentOrbit != header.orbit()) { // bad cpvheader
89 if (!mIsMuteErrors) {
90 LOG(error) << "RawDecoder::readChannels() : "
91 << "currentOrbit(=" << currentOrbit
92 << ") != header.orbit()(=" << header.orbit() << ")";
93 }
94 mErrors.emplace_back(-1, 0, 0, 0, kCPVHEADER_INVALID); // 5 is non-existing link with general errors
95 skipUntilNextHeader = true;
96 }
97 } else {
98 if (skipUntilNextHeader) {
99 b += wordLength;
100 continue; // continue while'ing until it's not header
101 }
102 CpvWord word(b, e);
103 if (word.isOK()) {
104 wordCountFromLastHeader++;
105 for (int i = 0; i < 3; i++) {
106 PadWord pw = {word.cpvPadWord(i)};
107 if (pw.zero == 0) { // cpv pad word, not control or empty
108 if (addDigit(pw.mDataWord, word.ccId(), currentBC)) {
109 nDigitsAddedFromLastHeader++;
110 } else {
111 if (!mIsMuteErrors) {
112 LOG(debug) << "RawDecoder::readChannels() : "
113 << "read pad word with non-valid pad address";
114 }
115 unsigned int dil = pw.dil, gas = pw.gas, address = pw.address;
116 mErrors.emplace_back(word.ccId(), dil, gas, address, kPadAddress);
117 }
118 }
119 }
120 } else { // this may be trailer
121 CpvTrailer trailer(b, e);
122 if (trailer.isOK()) {
123 int diffInCount = wordCountFromLastHeader - trailer.wordCounter();
124 if (diffInCount > 1 ||
125 diffInCount < -1) {
126 // some words lost?
127 if (!mIsMuteErrors) {
128 LOG(error) << "RawDecoder::readChannels() : "
129 << "Read " << wordCountFromLastHeader << " words, expected " << trailer.wordCounter();
130 }
131 mErrors.emplace_back(-1, 0, 0, 0, kCPVTRAILER_INVALID);
132 // throw all previous data and go to next header
133 removeLastNDigits(nDigitsAddedFromLastHeader);
134 skipUntilNextHeader = true;
135 }
136 if (trailer.bc() != currentBC) {
137 // trailer does not fit header
138 if (!mIsMuteErrors) {
139 LOG(error) << "RawDecoder::readChannels() : "
140 << "CPVHeader BC(" << currentBC << ") != CPVTrailer BC(" << trailer.bc() << ")";
141 }
142 mErrors.emplace_back(-1, 0, 0, 0, kCPVTRAILER_INVALID);
143 removeLastNDigits(nDigitsAddedFromLastHeader);
144 skipUntilNextHeader = true;
145 }
146 isHeaderExpected = true;
147 } else {
148 uint8_t unknownWord[10];
149 bool isPadding = isHeaderExpected && dataFormat == 0x2; // may this be padding?
150 for (int i = 0; i < 10 && (b + i) != e; i++) { // read up to 10 mBytes
151 unknownWord[i] = *(b + i);
152 if (unknownWord[i] != 0xff) { // padding
153 isPadding = false;
154 }
155 }
156 if (!isPadding) { // this is unknown word error
157 if (!mIsMuteErrors) {
158 LOGF(info, "RawDecoder::readChannels() : Read unknown word 0x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
159 unknownWord[9], unknownWord[8], unknownWord[7], unknownWord[6], unknownWord[5], unknownWord[4], unknownWord[3],
160 unknownWord[2], unknownWord[1], unknownWord[0]);
161 }
162 mErrors.emplace_back(-1, 0, 0, 0, kUNKNOWN_WORD); // add error for non-existing row
163 wordCountFromLastHeader++;
164 }
165 }
166 }
167 }
168 b += wordLength;
169 }
170 mChannelsInitialized = true;
171 return kOK;
172}
173
174bool RawDecoder::addDigit(uint32_t w, short ccId, uint16_t bc)
175{
176 // add digit
177 PadWord pad = {w};
178 unsigned short absId;
179 if (!o2::cpv::Geometry::hwaddressToAbsId(ccId, pad.dil, pad.gas, pad.address, absId)) {
180 return false;
181 }
182
183 // new bc -> add bc reference
184 if (mBCRecords.empty() || (mBCRecords.back().bc != bc)) {
185 mBCRecords.push_back(BCRecord(bc, mDigits.size(), mDigits.size()));
186 } else {
187 mBCRecords.back().lastDigit++;
188 }
189
190 AddressCharge ac = {0};
191 ac.Address = absId;
192 ac.Charge = pad.charge;
193 mDigits.push_back(ac.mDataWord);
194
195 return true;
196}
197
198void RawDecoder::removeLastNDigits(int n)
199{
200 if (n < 0) {
201 return;
202 }
203 int nRemoved = 0;
204 while (nRemoved < n) {
205 if (mDigits.size() > 0) { // still has digits to remove
206 mDigits.pop_back();
207 if (mBCRecords.back().lastDigit == mBCRecords.back().firstDigit) {
208 mBCRecords.pop_back();
209 } else {
210 mBCRecords.back().lastDigit--;
211 }
212 nRemoved++;
213 } else { // has nothing to remove already
214 break;
215 }
216 }
217}
uint64_t bc
Definition RawEventData.h:5
int32_t i
std::ostringstream debug
uint16_t bc() const
Definition RawFormats.h:100
bool isOK() const
Definition RawFormats.h:97
uint32_t orbit() const
Definition RawFormats.h:101
uint16_t bc() const
Definition RawFormats.h:134
uint16_t wordCounter() const
Definition RawFormats.h:132
bool isOK() const
Definition RawFormats.h:131
bool isOK() const
Definition RawFormats.h:50
short ccId() const
Definition RawFormats.h:54
uint32_t cpvPadWord(int i) const
Definition RawFormats.h:55
static bool hwaddressToAbsId(short ccId, short dil, short gas, short pad, unsigned short &absId)
Definition Geometry.cxx:109
RawErrorType_t readChannels()
Read channels for the current event in the raw buffer.
RawErrorType_t decode()
Decode the raw cpv payload stream.
RawDecoder(RawReaderMemory &reader)
Constructor.
Reader for raw data produced by the Readout application in in-memory format.
uint8_t getDataFormat() const
get data format from RDH
const std::vector< char > & getPayload() const
access to the full raw payload (single or multiple DMA pages)
uint32_t getCurrentHBFOrbit() const
GLdouble n
Definition glcorearb.h:1982
GLuint GLuint64EXT address
Definition glcorearb.h:5846
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
@ kCPVTRAILER_INVALID
@ kOK
NoError.
@ kOK_NO_PAYLOAD
No payload per ddl (not error)
BC reference to digits.
Definition RawDecoder.h:49
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint32_t Charge
Bits 18 - 32 : charge.
Definition RawDecoder.h:44
uint32_t Address
Bits 0 - 17 : Address.
Definition RawDecoder.h:43
uint32_t dil
Bits 21 - 22 : dilogic (1..24)
Definition RawFormats.h:31
uint32_t charge
Bits 0 - 11 : charge.
Definition RawFormats.h:28
uint32_t address
Bits 12 - 17 : address (0..47)
Definition RawFormats.h:29
uint32_t mDataWord
Definition RawFormats.h:26
uint32_t zero
Bits 23 - 23 : control bit (0 -> pad word, 1 -> FEE control word)
Definition RawFormats.h:32
uint32_t gas
Bits 18 - 20 : gasiplex (1..10)
Definition RawFormats.h:30