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
12#include <sstream>
13#include <string>
14#include <fairlogger/Logger.h>
17
18using namespace o2::cpv;
19
21
22RawReaderMemory::RawReaderMemory(gsl::span<const char> rawmemory) : mRawMemoryBuffer(rawmemory)
23{
24 init();
25}
26
27void RawReaderMemory::setRawMemory(const gsl::span<const char> rawmemory)
28{
29 mRawMemoryBuffer = rawmemory;
30 init();
31}
32
34{
35 auto headerversion = RDHUtils::getVersion(payloadwords);
36 if (headerversion < RDHUtils::getVersion<o2::header::RDHLowest>() || headerversion > RDHUtils::getVersion<o2::header::RDHHighest>()) {
37 LOG(error) << "Wrong header version " << headerversion;
39 }
40 return {*reinterpret_cast<const o2::header::RDHAny*>(payloadwords)};
41}
42
44{
45 mCurrentPosition = 0;
46 mRawHeaderInitialized = false;
47 mPayloadInitialized = false;
48 mCurrentHBFOrbit = 0;
49 mStopBitWasNotFound = false;
50 mIsJustInited = true;
51}
52
53// Read the next pages until the stop bit is found or new HBF reached
54// it means we read 1 HBF per next() call
56{
57 mRawPayload.clear();
58 bool isStopBitFound = false;
59 do {
61 if (e == RawErrorType_t::kPAGE_NOTFOUND || // nothing left to read...
62 e == RawErrorType_t::kRDH_DECODING || // incorrect rdh -> fatal error
63 e == RawErrorType_t::kPAYLOAD_INCOMPLETE || // we reached end of mRawMemoryBuffer but payload size from rdh tells to read more
64 e == RawErrorType_t::kSTOPBIT_NOTFOUND || // new HBF orbit started but no stop bit found, need to return
65 e == RawErrorType_t::kNOT_CPV_RDH || // not cpv rdh -> most probably
66 e == RawErrorType_t::kOFFSET_TO_NEXT_IS_0) { // offset to next package is 0 -> do not know how to read next
67 throw e; // some principal error occured -> stop reading.
68 }
69 isStopBitFound = RDHUtils::getStop(mRawHeader);
70 } while (!isStopBitFound);
71
73}
74
75// Read the next ONLY ONE page from the stream (single DMA page)
76// note: 1 raw header per page
78{
79 if (!hasNext()) {
81 }
82 mRawHeaderInitialized = false;
83 mPayloadInitialized = false;
84
85 // Read RDH header
86 o2::header::RDHAny rawHeader;
87 try {
88 rawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
89 if (RDHUtils::getOffsetToNext(rawHeader) == 0) { // dont' know how to read next -> skip to next HBF
91 }
92 if (RDHUtils::getSourceID(rawHeader) != 0x8) {
93 // Not a CPV RDH
94 mCurrentPosition += RDHUtils::getOffsetToNext(rawHeader); // not cpv rdh -> skip to next HBF
96 }
97 // Check validity of data format
98 auto dataFormat = RDHUtils::getDataFormat(rawHeader);
99 if (dataFormat != 0x0 && dataFormat != 0x2) { // invalid data format
101 }
102 // save first RDH of the HBF
103 if (mIsJustInited || mStopBitWasNotFound) { // reading first time after init() or stopbit was not found
104 mCurrentHBFOrbit = RDHUtils::getHeartBeatOrbit(rawHeader);
105 mDataFormat = dataFormat; // save data format
106 mRawHeader = rawHeader; // save RDH of first page as mRawHeader
107 mRawHeaderInitialized = true;
108 mStopBitWasNotFound = false; // reset this flag as we start to read again
109 mIsJustInited = false;
110 } else if (mCurrentHBFOrbit != RDHUtils::getHeartBeatOrbit(rawHeader)) {
111 // next HBF started but we didn't find stop bit.
112 mStopBitWasNotFound = true;
113 mCurrentPosition += RDHUtils::getOffsetToNext(rawHeader); // moving on
114 return RawErrorType_t::kSTOPBIT_NOTFOUND; // Stop bit was not found -> skip to next HBF
115 }
116 } catch (...) {
117 return RawErrorType_t::kRDH_DECODING; // this is fatal error -> skip whole TF
118 }
119 mRawHeader = rawHeader; // save RDH of current page as mRawHeader
120 mRawHeaderInitialized = true;
121
122 auto tmp = mRawMemoryBuffer.data();
123 int start = (mCurrentPosition + RDHUtils::getHeaderSize(mRawHeader));
124 int end = (mCurrentPosition + RDHUtils::getMemorySize(mRawHeader));
125 if (mDataFormat == 0x2) { // remove padding
126 int padding = (end - start) % 10;
127 end -= padding;
128 }
129 bool isPayloadIncomplete = false;
130 if (mCurrentPosition + RDHUtils::getMemorySize(mRawHeader) > mRawMemoryBuffer.size()) {
131 // Payload incomplete
132 isPayloadIncomplete = true;
133 end = mRawMemoryBuffer.size(); // OK, lets read it anyway. Maybe there still are some completed events...
134 }
135 for (auto iword = start; iword < end; iword++) {
136 mRawPayload.push_back(tmp[iword]);
137 }
138 mPayloadInitialized = true;
139
140 mCurrentPosition += RDHUtils::getOffsetToNext(mRawHeader); // Assume fixed 8 kB page size
141 if (isPayloadIncomplete) {
142 return RawErrorType_t::kPAYLOAD_INCOMPLETE; // skip to next HBF
143 }
144 return RawErrorType_t::kOK;
145}
uint16_t padding
RawErrorType_t next()
Read next payload from the stream.
RawErrorType_t nextPage()
Read the next page from the stream (single DMA page)
RawReaderMemory(const gsl::span< const char > rawmemory)
Constructor.
void setRawMemory(const gsl::span< const char > rawmemory)
set new raw memory chunk
void init()
Initialize the raw stream.
bool hasNext() const
check if more pages are available in the raw file
o2::header::RDHAny decodeRawHeader(const void *headerwords)
GLuint GLuint end
Definition glcorearb.h:469
GLuint start
Definition glcorearb.h:469
@ kOK
NoError.
@ kOFFSET_TO_NEXT_IS_0
@ kPAYLOAD_INCOMPLETE
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:58
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"