Project
Loading...
Searching...
No Matches
RawReaderMemory.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 <iostream>
12#include <sstream>
13#include <string>
17#include "Headers/DAQID.h"
18
19using namespace o2::emcal;
20
22
23RawReaderMemory::RawReaderMemory(gsl::span<const char> rawmemory) : mRawMemoryBuffer(rawmemory)
24{
25 init();
26}
27
28void RawReaderMemory::setRawMemory(const gsl::span<const char> rawmemory)
29{
30 mRawMemoryBuffer = rawmemory;
31 init();
32}
33
35{
36 auto headerversion = RDHDecoder::getVersion(payloadwords);
37 if (headerversion < RDHDecoder::getVersion<o2::header::RDHLowest>() || headerversion > RDHDecoder::getVersion<o2::header::RDHHighest>()) {
39 }
40 if (!RDHDecoder::checkRDH(payloadwords, false, true)) {
41 // Header size != to 64 and 0 in reserved words indicate that the header is a fake header
43 }
44 if (RDHDecoder::getVersion(payloadwords) >= 6) {
45 // If header version is >= 6 check that the source ID is EMCAL
46 if (RDHDecoder::getSourceID(payloadwords) != o2::header::DAQID::EMC) {
48 }
49 }
50 return {*reinterpret_cast<const o2::header::RDHAny*>(payloadwords)};
51}
52
54{
55 mCurrentPosition = 0;
56 mRawHeaderInitialized = false;
57 mPayloadInitialized = false;
58 mRawBuffer.flush();
59}
60
62{
63 mRawPayload.reset();
64 mCurrentTrailer.reset();
65 mMinorErrors.clear();
66 bool isDataTerminated = false;
67 do {
68 nextPage(false);
69 if (hasNext()) {
70 auto nextheader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
78 auto nextpagecounter = RDHDecoder::getPageCounter(nextheader);
79 if (nextpagecounter == 0) {
80 isDataTerminated = true;
81 } else {
82 isDataTerminated = false;
83 }
84 } else {
85 isDataTerminated = true;
86 }
87 // Check if the data continues
88 } while (!isDataTerminated);
89 // add combined trailer to payload (in case the FEE is a SRU DDL)
90 if (mCurrentTrailer.isInitialized()) {
91 mRawPayload.appendPayloadWords(mCurrentTrailer.encode());
92 }
93}
94
95void RawReaderMemory::nextPage(bool doResetPayload)
96{
97 if (!hasNext()) {
99 }
100 if (doResetPayload) {
101 mRawPayload.reset();
102 }
103 mRawHeaderInitialized = false;
104 mPayloadInitialized = false;
105 // Read header
106 try {
107 mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
108 auto feeID = RDHDecoder::getFEEID(mRawHeader);
109 if (mCurrentFEE < 0 || mCurrentFEE != feeID) {
110 // update current FEE ID
111 mCurrentFEE = feeID;
112 }
113 // RDHDecoder::printRDH(mRawHeader);
114 if (RDHDecoder::getOffsetToNext(mRawHeader) == RDHDecoder::getHeaderSize(mRawHeader)) {
115 // No Payload - jump to next rawheader
116 // This will eventually move, depending on whether for events without payload in the SRU we send the RCU trailer
117 mCurrentPosition += RDHDecoder::getHeaderSize(mRawHeader);
118 mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
119 feeID = RDHDecoder::getFEEID(mRawHeader);
120 if (mCurrentFEE < 0 || mCurrentFEE != feeID) {
121 // update current FEE ID
122 mCurrentFEE = feeID;
123 }
124 // RDHDecoder::printRDH(mRawHeader);
125 }
126 mRawHeaderInitialized = true;
127 } catch (...) {
129 }
130 if (mCurrentPosition + RDHDecoder::getMemorySize(mRawHeader) > mRawMemoryBuffer.size()) {
131 // Payload incomplete
132 // Set to offset to next or buffer size, whatever is smaller
133 if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
134 mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
135 if (mCurrentPosition + 64 < mRawMemoryBuffer.size()) {
136 // check if the page continues with a RDH
137 // if next page is not a header decodeRawHeader will throw a RawDecodingError
138 auto nextheader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
139 if (RDHDecoder::getVersion(nextheader) != RDHDecoder::getVersion(mRawHeader)) {
140 // Next header has different header version - clear indication that it is a fake header
142 }
143 }
144 } else {
145 mCurrentPosition = mRawMemoryBuffer.size();
146 }
147 // RDHDecoder::printRDH(mRawHeader);
149 } else if (mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader) > mRawMemoryBuffer.size()) {
150 // Start position of the payload is outside the payload range
151 // Set to offset to next or buffer size, whatever is smaller
152 if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
153 mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
154 } else {
155 mCurrentPosition = mRawMemoryBuffer.size();
156 }
158 } else {
159 mRawBuffer.readFromMemoryBuffer(gsl::span<const char>(mRawMemoryBuffer.data() + mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader), RDHDecoder::getMemorySize(mRawHeader) - RDHDecoder::getHeaderSize(mRawHeader)));
160
161 gsl::span<const uint32_t> payloadWithoutTrailer;
162 auto feeID = RDHDecoder::getFEEID(mRawHeader);
163 if (feeID >= mMinSRUDDL && feeID <= mMaxSRUDDL) {
164 // Read off and chop trailer (if required)
165 //
166 // In case every page gets a trailer (intermediate format). The trailers from the single
167 // pages need to be removed. There will be a combined trailer which keeps the sum of the
168 // payloads for all trailers. This will be appended to the chopped payload.
169 //
170 // Trailer only at the last page (new format): Only last page gets trailer. The trailer is
171 // also chopped from the payload as it will be added later again.
172 //
173 // The trailer is only decoded if the DDL is in the range of SRU DDLs. STU pages are propagated
174 // 1-1 without trailer parsing
175 auto lastword = *(mRawBuffer.getDataWords().rbegin());
176 if (RCUTrailer::checkLastTrailerWord(lastword)) {
177 // lastword is a trailer word
178 // decode trailer and chop
179 try {
180 auto trailer = RCUTrailer::constructFromPayloadWords(mRawBuffer.getDataWords());
181 if (!mCurrentTrailer.isInitialized()) {
182 mCurrentTrailer = trailer;
183 } else {
184 mCurrentTrailer.setPayloadSize(mCurrentTrailer.getPayloadSize() + trailer.getPayloadSize());
185 }
186 payloadWithoutTrailer = gsl::span<const uint32_t>(mRawBuffer.getDataWords().data(), mRawBuffer.getDataWords().size() - trailer.getTrailerSize());
187 if (trailer.getTrailerWordCorruptions()) {
188 mMinorErrors.emplace_back(RawDecodingError::ErrorType_t::TRAILER_INCOMPLETE, mCurrentFEE);
189 }
190 } catch (RCUTrailer::Error& e) {
191 // We must forward the position in such cases in order to not end up in an infinity loop
192 if (mCurrentPosition + RDHDecoder::getOffsetToNext(mRawHeader) < mRawMemoryBuffer.size()) {
193 mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
194 } else {
195 mCurrentPosition = mRawMemoryBuffer.size();
196 }
197 // Page is not consistent - must be skipped
199 }
200 } else {
201 // Not a trailer word = copy page as it is
202 payloadWithoutTrailer = mRawBuffer.getDataWords(); // No trailer to be chopped
203 }
204 } else {
205 payloadWithoutTrailer = mRawBuffer.getDataWords(); // No trailer to be chopped
206 }
207
208 mRawPayload.appendPayloadWords(payloadWithoutTrailer);
209 mRawPayload.increasePageCount();
210 }
211 mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
212}
213
215{
216 if (!mRawHeaderInitialized) {
218 }
219 return mRawHeader;
220}
221
223{
224 if (!mPayloadInitialized) {
226 }
227 return mRawBuffer;
228}
Definition of the RAW Data Header.
Error handling of the RCU trailer.
Definition RCUTrailer.h:80
void reset()
Reset the RCU trailer.
void setPayloadSize(uint32_t size)
set the payload size in number of DDL (32-bit) words
Definition RCUTrailer.h:174
static RCUTrailer constructFromPayloadWords(const gsl::span< const uint32_t > payloadwords)
Decode RCU trailer from payload.
uint32_t getPayloadSize() const
Get size of the payload as number of DDL (32-bit) words.
Definition RCUTrailer.h:154
static bool checkLastTrailerWord(uint32_t trailerword)
Check whether the word is a valid last trailer word.
std::vector< uint32_t > encode() const
Encode RCU trailer as array of DDL (32-bit) words.
bool isInitialized() const
checlks whether the RCU trailer is initialzied
Definition RCUTrailer.h:374
Buffer for EMCAL raw pages.
Definition RawBuffer.h:30
void readFromMemoryBuffer(const gsl::span< const char > rawmemory)
Read page from raw memory buffer.
Definition RawBuffer.cxx:46
const gsl::span< const uint32_t > getDataWords() const
Get all data words from the raw buffer.
Definition RawBuffer.h:72
void flush()
Flush the buffer Does not overwrite the word buffer but just resets the counter and iterator.
Definition RawBuffer.cxx:19
Error handling of the raw reader.
@ TRAILER_INCOMPLETE
Incomplete trailer words (i.e. registers)
@ HEADER_DECODING
Header cannot be decoded (format incorrect)
@ TRAILER_DECODING
Inconsistent trailer in memory (several trailer words missing the trailer marker)
@ PAGE_NOTFOUND
Page was not found (page index outside range)
@ HEADER_INVALID
Header in memory not belonging to requested superpage.
@ PAGE_START_INVALID
Page position starting outside payload size.
@ PAYLOAD_DECODING
Payload cannot be decoded (format incorrect)
@ PAYLOAD_INVALID
Payload in memory not belonging to requested superpage.
void reset()
Resetting payload words and page counter.
void increasePageCount()
Increase the page counter of the current payload.
Definition RawPayload.h:63
void appendPayloadWords(const gsl::span< const uint32_t > payloadwords)
Append many words to the current payload (usually of a given DMA page)
bool hasNext() const
check if more pages are available in the raw file
const o2::header::RDHAny & getRawHeader() const
access to the raw header of the current page
RawReaderMemory(const gsl::span< const char > rawmemory)
Constructor.
void setRawMemory(const gsl::span< const char > rawmemory)
set new raw memory chunk
const RawBuffer & getRawBuffer() const
access to the raw buffer (single DMA page)
void init()
Initialize the raw stream.
void next()
Read next payload from the stream.
void nextPage(bool resetPayload=true)
Read the next page from the stream (single DMA page)
o2::header::RDHAny decodeRawHeader(const void *headerwords)
Decode raw header words.
static constexpr ID EMC
Definition DAQID.h:44
static bool checkRDH(const RDHv4 &rdh, bool verbose=true, bool checkZeros=false)
Definition RDHUtils.cxx:133
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:58