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>
17#include <fairlogger/Logger.h>
18
19using namespace o2::phos;
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>()) {
38 LOG(error) << "Wrong header version " << headerversion;
40 }
41 return {*reinterpret_cast<const o2::header::RDHAny*>(payloadwords)};
42}
43
45{
46 mCurrentPosition = 0;
47 mRawHeaderInitialized = false;
48 mPayloadInitialized = false;
49 mRawBuffer.flush();
50 mNumData = mRawMemoryBuffer.size() / 8192; // assume fixed 8 kB pages
51}
52
54{
55 // Reads pages till RCU trailer found
56 // Several 8kB pages can be concatenated
57 // RCU trailer expected at the end of payload
58 // but not at the end of each page
59 mRawPayload.reset();
60 mCurrentTrailer.reset();
61 bool isDataTerminated = false;
62 do {
63 nextPage(false);
64 if (hasNext()) {
65 try {
66 auto nextheader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
67
68 // check continuing payload based on the bc/orbit ID
69 auto currentbc = RDHDecoder::getTriggerBC(mRawHeader),
70 nextbc = RDHDecoder::getTriggerBC(nextheader);
71 auto currentorbit = RDHDecoder::getTriggerOrbit(mRawHeader),
72 nextorbit = RDHDecoder::getTriggerOrbit(nextheader);
73 if (currentbc != nextbc || currentorbit != nextorbit) {
74 isDataTerminated = true;
75 } else {
76 auto nextpagecounter = RDHDecoder::getPageCounter(nextheader);
77 if (nextpagecounter == 0) {
78 isDataTerminated = true;
79 } else {
80 isDataTerminated = false;
81 }
82 }
83 } catch (...) {
85 }
86 } else {
87 isDataTerminated = true;
88 }
89 // Check if the data continues
90 } while (!isDataTerminated);
91 if (mRawBuffer.getNDataWords() > 0) {
92 try {
93 mCurrentTrailer.constructFromPayloadWords(mRawBuffer.getDataWords());
94 } catch (RCUTrailer::Error& e) {
96 // OS: According to expert old error of PHOS SRU firmware, not
97 // expected to be fixed soon, hence denoted to warning to
98 // not alarm the shifters
99 LOG(warn) << "Trailer decoding error: " << e.what();
100 } else {
101 LOG(error) << "Trailer decoding error: " << e.what();
102 }
104 }
105 }
106}
107//=============================================
108void RawReaderMemory::nextPage(bool doResetPayload)
109{
110 if (!hasNext()) {
111 return;
112 }
113 if (doResetPayload) {
114 mRawPayload.reset();
115 }
116 mRawHeaderInitialized = false;
117 mPayloadInitialized = false;
118
119 // Read RDH header
120 try {
121 mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
122 while (RDHDecoder::getOffsetToNext(mRawHeader) == RDHDecoder::getHeaderSize(mRawHeader) &&
123 mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader) < mRawMemoryBuffer.size()) {
124 // No Payload - jump to next rawheader
125 // This will eventually move, depending on whether for events without payload in the SRU we send the RCU trailer
126 mCurrentPosition += RDHDecoder::getHeaderSize(mRawHeader);
127 mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition);
128 }
129 mRawHeaderInitialized = true;
130 } catch (...) {
132 }
133 if (mCurrentPosition + RDHDecoder::getMemorySize(mRawHeader) > mRawMemoryBuffer.size()) {
134 // Payload incomplete
136 }
137
138 mRawBuffer.readFromMemoryBuffer(gsl::span<const char>(mRawMemoryBuffer.data() + mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader),
139 RDHDecoder::getMemorySize(mRawHeader) - RDHDecoder::getHeaderSize(mRawHeader)));
140 gsl::span<const uint32_t> payloadWithoutTrailer(mRawBuffer.getDataWords().data(), mRawBuffer.getNDataWords());
141 mRawPayload.appendPayloadWords(payloadWithoutTrailer);
142 mRawPayload.increasePageCount();
143
144 mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader);
145}
146
148{
149 if (!mRawHeaderInitialized) {
150 LOG(error) << "Raw header not initialized";
152 }
153 return mRawHeader;
154}
Error handling of the.
Definition RCUTrailer.h:61
@ DECODING_INVALID
Invalid words during decoding.
ErrorType_t getErrorType() const noexcept
Access to error code.
Definition RCUTrailer.h:89
const char * what() const noexcept override
Access to the error message.
Definition RCUTrailer.h:85
void reset()
Reset the RCU trailer.
static RCUTrailer constructFromPayloadWords(const gsl::span< const uint32_t > payloadwords)
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:61
void flush()
Flush the buffer Does not overwrite the word buffer but just resets the counter and iterator.
Definition RawBuffer.cxx:19
int getNDataWords() const
Get the number of data words read for the superpage.
Definition RawBuffer.h:57
@ HEADER_DECODING
Header cannot be decoded (format incorrect)
@ HEADER_INVALID
Header in memory not belonging to requested superpage.
@ PAYLOAD_DECODING
Payload cannot be decoded (format incorrect)
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)
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
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)
bool hasNext() const
check if more pages are available in the raw file
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:58
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"