diff --git a/Detectors/EMCAL/base/src/EMCALBaseLinkDef.h b/Detectors/EMCAL/base/src/EMCALBaseLinkDef.h index c80b7825b65f7..865b3fd0d5e6d 100644 --- a/Detectors/EMCAL/base/src/EMCALBaseLinkDef.h +++ b/Detectors/EMCAL/base/src/EMCALBaseLinkDef.h @@ -18,6 +18,7 @@ #pragma link C++ class o2::emcal::Geometry + ; #pragma link C++ class o2::emcal::Mapper + ; #pragma link C++ class o2::emcal::MappingHandler + ; +#pragma link C++ class o2::emcal::RCUTrailer + ; #pragma link C++ class o2::emcal::ClusterFactory < o2::emcal::Cell> + ; #pragma link C++ class o2::emcal::ClusterFactory < o2::emcal::Digit> + ; diff --git a/Detectors/EMCAL/base/src/RCUTrailer.cxx b/Detectors/EMCAL/base/src/RCUTrailer.cxx index d7451cfbb02c5..4188c1de80561 100644 --- a/Detectors/EMCAL/base/src/RCUTrailer.cxx +++ b/Detectors/EMCAL/base/src/RCUTrailer.cxx @@ -36,8 +36,8 @@ void RCUTrailer::reset() void RCUTrailer::constructFromRawPayload(const gsl::span payloadwords) { reset(); - int index = payloadwords.size() - 1; - auto word = payloadwords[index]; + int index = payloadwords.size(); + auto word = payloadwords[--index]; if ((word >> 30) != 3) throw Error(Error::ErrorType_t::DECODING_INVALID, "Last RCU trailer word not found!"); mFirmwareVersion = (word >> 16) & 0xFF; @@ -49,6 +49,7 @@ void RCUTrailer::constructFromRawPayload(const gsl::span payload throw Error(Error::ErrorType_t::SIZE_INVALID, fmt::format("Invalid trailer size found (%d bytes) !", trailerSize * 4).data()); mTrailerSize = trailerSize; + trailerSize -= 2; // Cut first and last trailer words as they are handled separately for (; trailerSize > 0; trailerSize--) { word = payloadwords[--index]; if ((word >> 30) != 2) { @@ -153,6 +154,7 @@ void RCUTrailer::setL1Phase(double l1phase) std::vector RCUTrailer::encode() const { std::vector encoded; + encoded.emplace_back(mPayloadSize); encoded.emplace_back(mAltroCFG2 | 7 << 26); encoded.emplace_back(mAltroCFG1 | 6 << 26); encoded.emplace_back(mActiveFECsB | 5 << 26); @@ -161,7 +163,7 @@ std::vector RCUTrailer::encode() const encoded.emplace_back(mERRREG2 | 2 << 26); encoded.emplace_back(mFECERRB >> 7 | (mFECERRA >> 7) << 13 | 1 << 26); - uint32_t lasttrailerword = 3 << 30 | mFirmwareVersion << 16 | mRCUId << 7 | encoded.size(); + uint32_t lasttrailerword = 3 << 30 | mFirmwareVersion << 16 | mRCUId << 7 | (encoded.size() + 1); encoded.emplace_back(lasttrailerword); return encoded; diff --git a/Detectors/EMCAL/reconstruction/CMakeLists.txt b/Detectors/EMCAL/reconstruction/CMakeLists.txt index c52c191fdae11..514822ba1ec5a 100644 --- a/Detectors/EMCAL/reconstruction/CMakeLists.txt +++ b/Detectors/EMCAL/reconstruction/CMakeLists.txt @@ -9,11 +9,9 @@ # submit itself to any jurisdiction. o2_add_library(EMCALReconstruction - SOURCES src/RawReaderFile.cxx - src/RawReaderMemory.cxx + SOURCES src/RawReaderMemory.cxx src/RawBuffer.cxx src/RawHeaderStream.cxx - src/RAWDataHeader.cxx src/RawPayload.cxx src/AltroDecoder.cxx src/Bunch.cxx @@ -30,17 +28,16 @@ o2_add_library(EMCALReconstruction AliceO2::InfoLogger O2::DataFormatsEMCAL O2::DetectorsBase + O2::DetectorsRaw O2::EMCALBase) o2_target_root_dictionary( EMCALReconstruction - HEADERS include/EMCALReconstruction/RawReaderFile.h - include/EMCALReconstruction/RawReaderMemory.h + HEADERS include/EMCALReconstruction/RawReaderMemory.h include/EMCALReconstruction/AltroDecoder.h include/EMCALReconstruction/RawPayload.h include/EMCALReconstruction/Bunch.h include/EMCALReconstruction/Channel.h - include/EMCALReconstruction/RAWDataHeader.h include/EMCALReconstruction/CaloFitResults.h include/EMCALReconstruction/CaloRawFitter.h include/EMCALReconstruction/CaloRawFitterStandard.h diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/AltroDecoder.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/AltroDecoder.h index 7b453c05e969d..00720e2c5ad65 100644 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/AltroDecoder.h +++ b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/AltroDecoder.h @@ -17,12 +17,7 @@ #include "EMCALBase/RCUTrailer.h" #include "EMCALReconstruction/Bunch.h" #include "EMCALReconstruction/Channel.h" - -// for template specification -#include "EMCALReconstruction/RawReaderFile.h" #include "EMCALReconstruction/RawReaderMemory.h" -#include "EMCALReconstruction/RAWDataHeader.h" -#include "Headers/RAWDataHeader.h" namespace o2 { @@ -84,13 +79,13 @@ class AltroDecoderError : public std::exception /// the payload, altro header and RCU trailer contents. /// /// Based on AliAltroRawStreamV3 and AliCaloRawStreamV3 by C. Cheshkov -template + class AltroDecoder { public: /// \brief Constructor /// \param reader Raw reader instance to be decoded - AltroDecoder(RawReader& reader); + AltroDecoder(RawReaderMemory& reader); /// \brief Destructor ~AltroDecoder() = default; @@ -130,7 +125,7 @@ class AltroDecoder /// In case of failure an exception is thrown. void checkRCUTrailer(); - RawReader& mRawReader; ///< underlying raw reader + RawReaderMemory& mRawReader; ///< underlying raw reader RCUTrailer mRCUTrailer; ///< RCU trailer std::vector mChannels; ///< vector of channels in the raw stream bool mChannelsInitialized = false; ///< check whether the channels are initialized @@ -138,12 +133,6 @@ class AltroDecoder ClassDefNV(AltroDecoder, 1); }; -// template specifications -using AltroDecoderMemoryRDHvE = AltroDecoder>; -using AltroDecoderMemoryRDHv4 = AltroDecoder>; -using AltroDecoderFileRDHvE = AltroDecoder>; -using AltroDecoderFileRDHv4 = AltroDecoder>; - } // namespace emcal } // namespace o2 diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RAWDataHeader.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RAWDataHeader.h deleted file mode 100644 index 652e1c41a9677..0000000000000 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RAWDataHeader.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef ALICEO2_EMCAL_RAwDATAHEADER_H -#define ALICEO2_EMCAL_RAwDATAHEADER_H - -#include -#include -#include "Rtypes.h" - -namespace o2 -{ -namespace emcal -{ -struct RAWDataHeader { - union { - uint32_t word0 = 0xFFFFFFFF; // size of the raw data in bytes - }; - - union { - uint32_t word1 = 3 << 24; // bunch crossing, L1 trigger message and format version - struct { - uint32_t triggerBC : 14; ///< bunch crossing [0-13] - uint32_t triggermessageL1 : 8; ///< L1 trigger message [14-21] - uint32_t zero11 : 2; ///< Unassigned [22-23] - uint32_t version : 8; ///< Version [24-31] - }; - }; - - union { - uint32_t word2 = 0; //< Size and offset - struct { - uint32_t offsetToNext : 16; ///< offset [0-15] - uint32_t memorySize : 16; ///< size [16-31] - }; - }; - - union { - uint32_t word3 = 0; ///< Number of packets and linkID - struct { - uint8_t linkID : 8; ///< Link ID [0-7] - uint8_t packetCounter : 8; ///< Number of packets [8-15] - uint16_t zero31 : 16; ///< Unassigned [16-31] - }; - }; - - union { - uint32_t word4 = 0x10000; // status & error bits and mini event ID - struct { - uint32_t triggerOrbit : 12; ///< mini event ID [0-11] - uint32_t status : 16; ///< status & error bits [12-27] - uint32_t zero41 : 4; ///< Unassigned [28-31] - }; - }; - - union { - uint32_t word5; ///< First word of the tirgger types - struct { - uint32_t triggerType : 32; ///< low trigger types [0-49] - }; - }; - - union { - uint32_t word6; ///< Second word of the trigger types - struct { - uint32_t triggerTypesHigh : 18; ///< Second part of the trigger types [0-17] - uint32_t triggerTypesNext50 : 14; ///< First part of the trigger types next 50 [18-31] - }; - }; - - union { - uint32_t word7; ///< Third word of the trigger types - struct { - uint32_t triggerTypesNext50Middle : 32; ///< Second part of the trigger types next 50 - }; - }; - - union { - uint32_t word8; ///< Fourth word of the trigger types - struct { - uint32_t triggerTypesNext50High : 4; ///< Third part of the trigger types next 50 [0-3] - uint32_t zero81 : 24; ///< Unassigned [4-27] - uint32_t roi : 4; ///< First part of the roi [28-31] - }; - }; - - union { - uint32_t word9; ///< Second word of the roi - struct { - uint32_t roiHigh : 32; ///< Second part of the roi - }; - }; -}; - -std::istream& operator>>(std::istream& in, o2::emcal::RAWDataHeader& header); -std::ostream& operator<<(std::ostream& out, const o2::emcal::RAWDataHeader& header); - -} // namespace emcal - -} // namespace o2 - -#endif // _O2_EMCAL_RAwDATAHEADER_H__ \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderFile.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderFile.h deleted file mode 100644 index 9dedf2c087656..0000000000000 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderFile.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -#ifndef ALICEO2_EMCAL_RAWREADERFILE_H -#define ALICEO2_EMCAL_RAWREADERFILE_H - -#include -#include -#include -#include -#include - -#include "Rtypes.h" -#include "RStringView.h" - -#include "Headers/RAWDataHeader.h" -#include "EMCALReconstruction/RawBuffer.h" -#include "EMCALReconstruction/RAWDataHeader.h" -#include "EMCALReconstruction/RawPayload.h" - -namespace o2 -{ - -namespace emcal -{ - -/// \class RawReaderFile -/// \brief Reader for raw data produced by the ReadoutCard from a binary file -/// \ingroup EMCALreconstruction -/// \author Markus Fasel , Oak Ridge National Laboratory -/// \since Aug. 12, 2019 -/// -/// -template -class RawReaderFile -{ - public: - /// \brief Constructor - /// - /// Opening the raw file and determining its size and the number - /// of pages. - RawReaderFile(const std::string_view filename); - - /// \brief Destructor - /// - /// Closing the raw file - ~RawReaderFile(); - - /// \brief Read next payload from the stream - /// - /// Read the next pages until the stop bit is found. - void next(); - - /// \brief Read the next page from the stream (single DMA page) - /// \param resetPayload If true the raw payload is reset - /// \throw Error if the page cannot be read or header or payload cannot be deocded - /// - /// Function reading a single DMA page from the stream. It is called - /// inside the next() function for reading payload from multiple DMA - /// pages. As the function cannot handle payload from multiple pages - /// it should not be called directly by the user. - void nextPage(bool resetPayload = true); - - /// \brief Read page with a given index - /// \param page Index of the page to be decoded - /// \throw RawDecodingError if the page cannot be read or header or payload cannot be deocded - /// - /// The reader will try to read the page with a certain index. In - /// case the page cannot be decoded (page index outside range, - /// decoding of header or payload failed), and excpetion is raised. - void readPage(int page); - - /// \brief access to the raw header of the current page - /// \return Raw header of the current page - /// \throw Error with HEADER_INVALID if the header was not decoded - const RawHeader& getRawHeader() const; - - /// \brief access to the raw buffer (single DMA page) - /// \return Raw buffer of the current page - /// \throw Error with PAYLOAD_INCALID if payload was not decoded - const RawBuffer& getRawBuffer() const; - - /// \brief access to the full raw payload (single or multiple DMA pages) - /// \return Raw Payload of the data until the stop bit is received. - const RawPayload& getPayload() const { return mRawPayload; } - - /// \brief Return size of the payload - /// \return size of the payload - int getPayloadSize() const { return mRawPayload.getPayloadSize(); } - - /// \brief get the size of the file in bytes - /// \return size of the file in byte - int getFileSize() const noexcept { return mFileSize; } - - /// \brief get the number of pages in the file - /// \return number of pages in the file - int getNumberOfPages() const noexcept { return mNumData; } - - /// \brief check if more pages are available in the raw file - /// \return true if there is a next page - bool hasNext() const { return mCurrentPosition < mNumData; } - - static void readFile(const std::string_view filename); - - protected: - /// \brief Init the raw reader - /// - /// Opening the raw file and determining the number of superpages - void init(); - - /// \brief Decode the Raw Data Header - /// \throw RawDecodingError with HEADER_DECODING in case the header decoding failed - /// - /// Decoding the raw header. Function assumes that the pointer - /// is at the beginning of the raw header - void readHeader(); - - /// \brief Decode the payload - /// \throw RawDecodingError with PAYLOAD_DECODING in case the payload decoding failed - /// - /// Decoding the payload. The function assumes that the pointer is at - /// the beginning of the payload of the page. Needs the raw header of the - /// page to be decoded before in order to determine size of the payload - /// and offset. - void readPayload(); - - bool isStop(const o2::emcal::RAWDataHeader& hdr) { return true; } - bool isStop(const o2::header::RAWDataHeaderV4& hdr) { return hdr.stop; } - - private: - std::string mInputFileName; ///< Name of the input file - std::ifstream mDataFile; ///< Stream of the inputfile - RawHeader mRawHeader; ///< Raw header - RawBuffer mRawBuffer; ///< Raw buffer - RawPayload mRawPayload; ///< Raw payload (can consist of multiple pages) - int mCurrentPosition = 0; ///< Current page in file - int mFileSize = 0; ///< Size of the file in bytes - int mNumData = 0; ///< Number of pages - bool mRawHeaderInitialized = false; ///< RDH for current page initialized - bool mPayloadInitialized = false; ///< Payload for current page initialized - - ClassDefNV(RawReaderFile, 1); -}; - -// template specifications -using RawReaderFileRDHvE = RawReaderFile; -using RawReaderFileRDHv4 = RawReaderFile; - -} // namespace emcal - -} // namespace o2 -#endif diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderMemory.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderMemory.h index 208c73f0c4319..c6d544e0529ff 100644 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderMemory.h +++ b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RawReaderMemory.h @@ -13,10 +13,11 @@ #include #include +#include "EMCALBase/RCUTrailer.h" #include "EMCALReconstruction/RawBuffer.h" -#include "EMCALReconstruction/RAWDataHeader.h" #include "EMCALReconstruction/RawPayload.h" #include "Headers/RAWDataHeader.h" +#include "Headers/RDHAny.h" namespace o2 { @@ -31,7 +32,6 @@ namespace emcal /// \since Nov. 14, 2019 /// /// -template class RawReaderMemory { public: @@ -72,7 +72,7 @@ class RawReaderMemory /// \brief access to the raw header of the current page /// \return Raw header of the current page /// \throw RawDecodingError with HEADER_INVALID if the header was not decoded - const RawHeader& getRawHeader() const; + const o2::header::RDHAny& getRawHeader() const; /// \brief access to the raw buffer (single DMA page) /// \return Raw buffer of the current page @@ -105,14 +105,15 @@ class RawReaderMemory /// Rewind stream to the first entry void init(); - bool isStop(const o2::emcal::RAWDataHeader& hdr) { return true; } - bool isStop(const o2::header::RAWDataHeaderV4& hdr) { return hdr.stop; } + o2::header::RDHAny decodeRawHeader(const void* headerwords); private: gsl::span mRawMemoryBuffer; ///< Memory block with multiple DMA pages RawBuffer mRawBuffer; ///< Raw buffer - RawHeader mRawHeader; ///< Raw header + o2::header::RDHAny mRawHeader; ///< Raw header RawPayload mRawPayload; ///< Raw payload (can consist of multiple pages) + RCUTrailer mCurrentTrailer; ///< RCU trailer + uint64_t mTrailerPayloadWords = 0; ///< Payload words in common trailer int mCurrentPosition = 0; ///< Current page in file int mNumData = 0; ///< Number of pages bool mRawHeaderInitialized = false; ///< RDH for current page initialized @@ -121,10 +122,6 @@ class RawReaderMemory ClassDefNV(RawReaderMemory, 1); }; -// For template specifications -using RawReaderMemoryRDHvE = RawReaderMemory; -using RawReaderMemoryRDHv4 = RawReaderMemory; - } // namespace emcal } // namespace o2 diff --git a/Detectors/EMCAL/reconstruction/macros/RawFitterTESTs.C b/Detectors/EMCAL/reconstruction/macros/RawFitterTESTs.C index 25695221d817b..deb09a48db3fd 100644 --- a/Detectors/EMCAL/reconstruction/macros/RawFitterTESTs.C +++ b/Detectors/EMCAL/reconstruction/macros/RawFitterTESTs.C @@ -15,6 +15,7 @@ #include #include "RStringView.h" #include +#include "DetectorsRaw/RawFileReader.h" #include "EMCALReconstruction/CaloFitResults.h" #include "EMCALReconstruction/Bunch.h" #include "EMCALReconstruction/CaloRawFitterStandard.h" @@ -38,7 +39,12 @@ void RawFitterTESTs() inputDir = aliceO2env; inputDir += "/share/Detectors/EMC/files/"; - o2::emcal::RawReaderFile rawreader(inputDir + "emcal.raw"); + o2::raw::RawFileReader reader; + reader.setDefaultDataOrigin(o2::header::gDataOriginEMC); + reader.setDefaultDataDescription(o2::header::gDataDescriptionRawData); + reader.setDefaultReadoutCardType(o2::raw::RawFileReader::RORC); + reader.addFile(inputDir + "emcal.raw"); + reader.init(); // define the standard raw fitter //o2::emcal::CaloRawFitterStandard RawFitter; @@ -46,28 +52,45 @@ void RawFitterTESTs() RawFitter.setAmpCut(NoiseThreshold); RawFitter.setL1Phase(0.); - // loop over all the DMA pages - while (rawreader.hasNext()) { + while (1) { + int tfID = reader.getNextTFToRead(); + if (tfID >= reader.getNTimeFrames()) { + std::cerr << "nothing left to read after " << tfID << " TFs read"; + break; + } + std::vector dataBuffer; // where to put extracted data + for (int il = 0; il < reader.getNLinks(); il++) { + auto& link = reader.getLink(il); + std::cout << "Decoding link " << il << std::endl; + + auto sz = link.getNextTFSize(); // size in bytes needed for the next TF of this link + dataBuffer.resize(sz); + link.readNextTF(dataBuffer.data()); - rawreader.next(); - std::cout << "next page \n"; + // Parse + o2::emcal::RawReaderMemory parser(dataBuffer); + while (parser.hasNext()) { + parser.next(); + std::cout << "next page \n"; - //std::cout< decoder(rawreader); - decoder.decode(); + // use the altro decoder to decode the raw data, and extract the RCU trailer + o2::emcal::AltroDecoder decoder(parser); + decoder.decode(); - std::cout << decoder.getRCUTrailer() << std::endl; + std::cout << decoder.getRCUTrailer() << std::endl; - // Loop over all the channels - for (auto& chan : decoder.getChannels()) { + // Loop over all the channels + for (auto& chan : decoder.getChannels()) { - // define the conatiner for the fit results, and perform the raw fitting using the stadnard raw fitter - o2::emcal::CaloFitResults fitResults = RawFitter.evaluate(chan.getBunches(), 0, 0); + // define the conatiner for the fit results, and perform the raw fitting using the stadnard raw fitter + o2::emcal::CaloFitResults fitResults = RawFitter.evaluate(chan.getBunches(), 0, 0); - // print the fit output - std::cout << "The Time is : " << fitResults.getTime() << " And the Amplitude is : " << fitResults.getAmp() << std::endl; + // print the fit output + std::cout << "The Time is : " << fitResults.getTime() << " And the Amplitude is : " << fitResults.getAmp() << std::endl; + } + } } } } diff --git a/Detectors/EMCAL/reconstruction/run/rawReaderFile.cxx b/Detectors/EMCAL/reconstruction/run/rawReaderFile.cxx index 70808de706187..e899dfe00b0ab 100644 --- a/Detectors/EMCAL/reconstruction/run/rawReaderFile.cxx +++ b/Detectors/EMCAL/reconstruction/run/rawReaderFile.cxx @@ -8,27 +8,26 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file rawReaderFile.cxx +/// \file rawReaderFileNew.cxx /// \author Markus Fasel , Oak Ridge National Laboratory #include #include -#include "Headers/RAWDataHeader.h" -#include "EMCALReconstruction/RawHeaderStream.h" -#include "EMCALReconstruction/RAWDataHeader.h" -#include "EMCALReconstruction/RawReaderFile.h" +#include "DetectorsRaw/RawFileReader.h" #include "EMCALReconstruction/AltroDecoder.h" +#include "EMCALReconstruction/RawReaderMemory.h" +#include "FairLogger.h" namespace bpo = boost::program_options; -using namespace o2::emcal; +//using namespace o2::emcal; int main(int argc, char** argv) { bpo::variables_map vm; bpo::options_description opt_general("Usage:\n " + std::string(argv[0]) + " \n" - " Tool will decode the GBTx data for SAMPA 0\n" + " Tool will decode the DDLx data for EMCAL 0\n" "Commands / Options"); bpo::options_description opt_hidden(""); bpo::options_description opt_all; @@ -39,7 +38,6 @@ int main(int argc, char** argv) add_option("help,h", "Print this help message"); add_option("verbose,v", bpo::value()->default_value(0), "Select verbosity level [0 = no output]"); add_option("version", "Print version information"); - add_option("rdh,r", bpo::value()->default_value(3), "RAW Data Header version (3 - CDHv3, 4 - RDHv4)"); add_option("input-file,i", bpo::value()->required(), "Specifies input file."); add_option("debug,d", bpo::value()->default_value(0), "Select debug output level [0 = no debug output]"); @@ -67,34 +65,52 @@ int main(int argc, char** argv) exit(2); } - auto decode = [](auto reader) { - while (reader.hasNext()) { - reader.next(); - std::cout << reader.getRawHeader(); - o2::emcal::AltroDecoder decoder(reader); - decoder.decode(); - std::cout << decoder.getRCUTrailer() << std::endl; - for (auto& chan : decoder.getChannels()) { - std::cout << "Hw address: " << chan.getHardwareAddress() << std::endl; - for (auto& bunch : chan.getBunches()) { - std::cout << "BunchLength: " << int(bunch.getBunchLength()) << std::endl; - auto adcs = bunch.getADC(); - int time = bunch.getStartTime(); - for (int i = adcs.size() - 1; i >= 0; i--) { - std::cout << "Timebin " << time << ", ADC " << adcs[i] << std::endl; - time--; + auto rawfilename = vm["input-file"].as(); + + o2::raw::RawFileReader reader; + reader.setDefaultDataOrigin(o2::header::gDataOriginEMC); + reader.setDefaultDataDescription(o2::header::gDataDescriptionRawData); + reader.setDefaultReadoutCardType(o2::raw::RawFileReader::RORC); + reader.addFile(rawfilename); + reader.init(); + + while (1) { + int tfID = reader.getNextTFToRead(); + if (tfID >= reader.getNTimeFrames()) { + LOG(INFO) << "nothing left to read after " << tfID << " TFs read"; + break; + } + std::vector dataBuffer; // where to put extracted data + for (int il = 0; il < reader.getNLinks(); il++) { + auto& link = reader.getLink(il); + std::cout << "Decoding link " << il << std::endl; + + auto sz = link.getNextTFSize(); // size in bytes needed for the next TF of this link + dataBuffer.resize(sz); + link.readNextTF(dataBuffer.data()); + + // Parse + o2::emcal::RawReaderMemory parser(dataBuffer); + while (parser.hasNext()) { + parser.next(); + o2::emcal::AltroDecoder decoder(parser); + decoder.decode(); + + std::cout << decoder.getRCUTrailer() << std::endl; + for (auto& chan : decoder.getChannels()) { + std::cout << "Hw address: " << chan.getHardwareAddress() << std::endl; + for (auto& bunch : chan.getBunches()) { + std::cout << "BunchLength: " << int(bunch.getBunchLength()) << std::endl; + auto adcs = bunch.getADC(); + int time = bunch.getStartTime(); + for (int i = adcs.size() - 1; i >= 0; i--) { + std::cout << "Timebin " << time << ", ADC " << adcs[i] << std::endl; + time--; + } } } } } - }; - - auto rawfilename = vm["input-file"].as(); - auto rawHeaderVersion = vm["rdh"].as(); - if (rawHeaderVersion == 4) { - decode(o2::emcal::RawReaderFileRDHv4(rawfilename)); - } else { - decode(o2::emcal::RawReaderFileRDHvE(rawfilename)); + reader.setNextTFToRead(++tfID); } - return 0; -} +} \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/src/AltroDecoder.cxx b/Detectors/EMCAL/reconstruction/src/AltroDecoder.cxx index 6c42966a68640..1d1eca3495ccc 100644 --- a/Detectors/EMCAL/reconstruction/src/AltroDecoder.cxx +++ b/Detectors/EMCAL/reconstruction/src/AltroDecoder.cxx @@ -8,36 +8,28 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. #include -#include -#include #include #include "InfoLogger/InfoLogger.hxx" -#include "Headers/RAWDataHeader.h" #include "EMCALReconstruction/AltroDecoder.h" -#include "EMCALReconstruction/RAWDataHeader.h" -#include "EMCALReconstruction/RawReaderFile.h" #include "EMCALReconstruction/RawReaderMemory.h" using namespace o2::emcal; -template -AltroDecoder::AltroDecoder(RawReader& reader) : mRawReader(reader), - mRCUTrailer(), - mChannels(), - mChannelsInitialized(false) +AltroDecoder::AltroDecoder(RawReaderMemory& reader) : mRawReader(reader), + mRCUTrailer(), + mChannels(), + mChannelsInitialized(false) { } -template -void AltroDecoder::decode() +void AltroDecoder::decode() { readRCUTrailer(); checkRCUTrailer(); readChannels(); } -template -void AltroDecoder::readRCUTrailer() +void AltroDecoder::readRCUTrailer() { try { auto payloadwordsOrig = mRawReader.getPayload().getPayloadWords(); @@ -50,19 +42,16 @@ void AltroDecoder::readRCUTrailer() } } -template -void AltroDecoder::checkRCUTrailer() +void AltroDecoder::checkRCUTrailer() { } -template -void AltroDecoder::readChannels() +void AltroDecoder::readChannels() { mChannelsInitialized = false; mChannels.clear(); int currentpos = 0; auto& buffer = mRawReader.getPayload().getPayloadWords(); - std::array bunchwords; while (currentpos < buffer.size() - mRCUTrailer.getTrailerSize()) { auto currentword = buffer[currentpos++]; if (currentword >> 30 != 1) { @@ -74,8 +63,8 @@ void AltroDecoder::readChannels() currentchannel.setBadChannel((currentword >> 29) & 0x1); /// decode all words for channel - int numberofsamples = 0, - numberofwords = (currentchannel.getPayloadSize() + 2) / 3; + int numberofwords = (currentchannel.getPayloadSize() + 2) / 3; + std::vector bunchwords; for (int iword = 0; iword < numberofwords; iword++) { currentword = buffer[currentpos++]; if ((currentword >> 30) != 0) { @@ -85,9 +74,9 @@ void AltroDecoder::readChannels() currentpos--; continue; } - bunchwords[numberofsamples++] = (currentword >> 20) & 0x3FF; - bunchwords[numberofsamples++] = (currentword >> 10) & 0x3FF; - bunchwords[numberofsamples++] = currentword & 0x3FF; + bunchwords.push_back((currentword >> 20) & 0x3FF); + bunchwords.push_back((currentword >> 10) & 0x3FF); + bunchwords.push_back(currentword & 0x3FF); } // decode bunches @@ -96,30 +85,23 @@ void AltroDecoder::readChannels() int bunchlength = bunchwords[currentsample] - 2, // remove words for bunchlength and starttime starttime = bunchwords[currentsample + 1]; auto& currentbunch = currentchannel.createBunch(bunchlength, starttime); - currentbunch.initFromRange(gsl::span(&bunchwords[currentsample + 2], std::min(bunchlength, numberofsamples - currentsample - 2))); + currentbunch.initFromRange(gsl::span(&bunchwords[currentsample + 2], std::min((unsigned long)bunchlength, bunchwords.size() - currentsample - 2))); currentsample += bunchlength + 2; } } mChannelsInitialized = true; } -template -const RCUTrailer& AltroDecoder::getRCUTrailer() const +const RCUTrailer& AltroDecoder::getRCUTrailer() const { if (!mRCUTrailer.isInitialized()) throw AltroDecoderError(AltroDecoderError::ErrorType_t::RCU_TRAILER_ERROR, "RCU trailer was not initialized"); return mRCUTrailer; } -template -const std::vector& AltroDecoder::getChannels() const +const std::vector& AltroDecoder::getChannels() const { if (!mChannelsInitialized) throw AltroDecoderError(AltroDecoderError::ErrorType_t::CHANNEL_ERROR, "Channels not initizalized"); return mChannels; -} - -template class o2::emcal::AltroDecoder>; -template class o2::emcal::AltroDecoder>; -template class o2::emcal::AltroDecoder>; -template class o2::emcal::AltroDecoder>; \ No newline at end of file +} \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/src/EMCALReconstructionLinkDef.h b/Detectors/EMCAL/reconstruction/src/EMCALReconstructionLinkDef.h index f52ae19d5d116..2a5f25a56e4c0 100644 --- a/Detectors/EMCAL/reconstruction/src/EMCALReconstructionLinkDef.h +++ b/Detectors/EMCAL/reconstruction/src/EMCALReconstructionLinkDef.h @@ -14,18 +14,12 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::emcal::RawReaderFile < o2::emcal::RAWDataHeader> + ; -#pragma link C++ class o2::emcal::RawReaderFile < o2::header::RAWDataHeaderV4> + ; -#pragma link C++ class o2::emcal::RawReaderMemory < o2::emcal::RAWDataHeader> + ; -#pragma link C++ class o2::emcal::RawReaderMemory < o2::header::RAWDataHeaderV4> + ; -#pragma link C++ class o2::emcal::AltroDecoder < o2::emcal::RawReaderFile < o2::emcal::RAWDataHeader>> + ; -#pragma link C++ class o2::emcal::AltroDecoder < o2::emcal::RawReaderFile < o2::header::RAWDataHeaderV4>> + ; -#pragma link C++ class o2::emcal::AltroDecoder < o2::emcal::RawReaderMemory < o2::emcal::RAWDataHeader>> + ; -#pragma link C++ class o2::emcal::AltroDecoder < o2::emcal::RawReaderMemory < o2::header::RAWDataHeaderV4>> + ; + +#pragma link C++ class o2::emcal::RawReaderMemory + ; +#pragma link C++ class o2::emcal::AltroDecoder + ; #pragma link C++ class o2::emcal::RawPayload + ; #pragma link C++ class o2::emcal::Bunch + ; #pragma link C++ class o2::emcal::Channel + ; -#pragma link C++ class o2::emcal::RCUTrailer + ; #pragma link C++ class o2::emcal::CaloFitResults + ; #pragma link C++ class o2::emcal::CaloRawFitter + ; #pragma link C++ class o2::emcal::CaloRawFitterStandard + ; diff --git a/Detectors/EMCAL/reconstruction/src/RAWDataHeader.cxx b/Detectors/EMCAL/reconstruction/src/RAWDataHeader.cxx deleted file mode 100644 index 3e4e3fab514c5..0000000000000 --- a/Detectors/EMCAL/reconstruction/src/RAWDataHeader.cxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include -#include -#include "EMCALReconstruction/RAWDataHeader.h" - -using namespace o2::emcal; - -std::ostream& o2::emcal::operator<<(std::ostream& stream, const o2::emcal::RAWDataHeader& header) -{ - stream << "EMCAL CRORC RAW Header:\n" - << " Size (WORD0): " << header.word0 << "(" << std::hex << header.word0 << std::dec << ")\n" - << " WORD1: " << header.word1 << "(" << std::hex << header.word1 << std::dec << ")\n" - << " Version: " << int(header.version) << "\n" - << " L1 Trigger Message: " << int(header.triggermessageL1) << "\n" - << " EventID1: " << header.triggerBC << "\n" - << " Offset and size (WORD2): " << header.word2 << "(" << std::hex << header.word2 << std::dec << ")\n" - << " Offset: " << header.offsetToNext << "\n" - << " Size: " << header.memorySize << "\n" - << " Package counter and link ID (WORD3): (" << std::hex << header.word3 << std::dec << ")\n" - << " Packet counter: " << int(header.packetCounter) << "\n" - << " Link ID: " << int(header.linkID) << "\n" - << " Status and mini eventID: " << header.word4 << " (" << std::hex << header.word4 << std::dec << ")\n" - << " Status: " << header.status << "\n" - << " Mini EventID: " << header.triggerOrbit << "\n" - /* - << " Trigger Classes: ( " << std::hex << header.words5[0] << " " << header.words5[1] << " " << header.words5[2] << std::dec << ")\n" - << " First 50: " << std::bitset(header.triggerType) << "\n" - << " Second 50: " << std::bitset(header.triggerTypeNext50) << "\n" - << " ROI: (" << std::hex << header.words5[3] << " " << header.words5[4] << std::dec << ")\n" - << " ROI: " << std::bitset(header.roi) << "\n" - */ - << "End Header" << std::endl; - return stream; -} - -std::istream& o2::emcal::operator>>(std::istream& stream, o2::emcal::RAWDataHeader& header) -{ - //std::cout << "called, 10 words" << std::endl; - uint32_t message[10]; - auto address = reinterpret_cast(message); - for (int i = 0; i < 10; i++) { - stream.read(address + i * sizeof(uint32_t) / sizeof(char), sizeof(message[i])); - //std::cout << "Word " << i << ": " << std::hex << message[i] << std::dec << std::endl; - } - header.word0 = message[0]; - header.word1 = message[1]; - header.word2 = message[2]; - header.word3 = message[3]; - header.word4 = message[4]; - header.word5 = message[5]; - header.word6 = message[6]; - header.word7 = message[7]; - header.word8 = message[8]; - header.word9 = message[9]; - return stream; -} \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/src/RawBuffer.cxx b/Detectors/EMCAL/reconstruction/src/RawBuffer.cxx index 932ccd4464087..1da3635891218 100644 --- a/Detectors/EMCAL/reconstruction/src/RawBuffer.cxx +++ b/Detectors/EMCAL/reconstruction/src/RawBuffer.cxx @@ -47,12 +47,14 @@ void RawBuffer::readFromMemoryBuffer(const gsl::span rawmemory) flush(); auto address = reinterpret_cast(rawmemory.data()); for (auto iword = 0; iword < rawmemory.size() / sizeof(uint32_t); iword++) { - if ((address[iword] & 0xFFF) == 0x082) { - // Termination word - // should normally not be decoded in case the payload size - // is determined correctly - break; - } + // Run2 code, probably not needed for run3 + // if ((address[iword] & 0xFFF) == 0x082) { + // Termination word + // should normally not be decoded in case the payload size + // is determined correctly + //std::cout << "Found termination word" << std::endl; + //break; + // } mDataWords[mNDataWords++] = address[iword]; } } diff --git a/Detectors/EMCAL/reconstruction/src/RawReaderFile.cxx b/Detectors/EMCAL/reconstruction/src/RawReaderFile.cxx deleted file mode 100644 index d2fd6fdf1573e..0000000000000 --- a/Detectors/EMCAL/reconstruction/src/RawReaderFile.cxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -#include -#include -#include - -#include "EMCALBase/RCUTrailer.h" -#include "EMCALReconstruction/RawHeaderStream.h" -#include "EMCALReconstruction/RawReaderFile.h" -#include "EMCALReconstruction/RawDecodingError.h" - -using namespace o2::emcal; - -#define CHECK_BIT(var, pos) ((var) & (1 << (pos))) - -bool isStop(const o2::emcal::RAWDataHeader& hdr) -{ - return true; -} -bool isStop(const o2::header::RAWDataHeaderV4& hdr) { return hdr.stop; } - -template -RawReaderFile::RawReaderFile(const std::string_view filename) : mInputFileName(filename), - mDataFile(), - mRawHeader() -{ - init(); -} -template -RawReaderFile::~RawReaderFile() -{ - mDataFile.close(); -} - -template -void RawReaderFile::init() -{ - mDataFile.open(mInputFileName, std::ifstream::binary); - if (!mDataFile.good()) - throw std::runtime_error("Unable to open or access file " + mInputFileName); - // get length of file in bytes - mDataFile.seekg(0, mDataFile.end); - mFileSize = mDataFile.tellg(); - mDataFile.seekg(0, mDataFile.beg); - // the file is supposed to contain N x 8kB packets. So the number of packets - // can be determined by the file-size. Ideally, this is not required but the - // information is derived directly from the header size and payload size. - // *** to be adapted to header info *** - mNumData = mFileSize / (8 * 1024); -} - -template -void RawReaderFile::next() -{ - mRawPayload.reset(); - bool isDataTerminated = false; - do { - nextPage(false); - // check if we find a valid RCU trailer - // the payload must be at the end of the buffer - // if not present and error will be thrown - try { - RCUTrailer::constructFromPayloadWords(mRawBuffer.getDataWords()); - isDataTerminated = true; - } catch (...) { - } - } while (!isDataTerminated); -} - -template -void RawReaderFile::nextPage(bool doResetPayload) -{ - if (mCurrentPosition >= mNumData) - throw RawDecodingError(RawDecodingError::ErrorType_t::PAGE_NOTFOUND); - if (doResetPayload) - mRawPayload.reset(); - auto start = mDataFile.tellg(); - readHeader(); - readPayload(); - mRawPayload.appendPayloadWords(mRawBuffer.getDataWords()); - mRawPayload.increasePageCount(); - mDataFile.seekg(int(start) + mRawHeader.offsetToNext); - mCurrentPosition++; -} - -template -void RawReaderFile::readPage(int page) -{ - mRawHeaderInitialized = false; - mPayloadInitialized = false; - if (page >= mNumData) - throw RawDecodingError(RawDecodingError::ErrorType_t::PAGE_NOTFOUND); - mDataFile.seekg(page * 8192); - auto start = mDataFile.tellg(); - readHeader(); - readPayload(); - mDataFile.seekg(int(start) + mRawHeader.offsetToNext); - mCurrentPosition = page; -} - -template -void RawReaderFile::readHeader() -{ - try { - // assume the seek is at the header position - mDataFile >> mRawHeader; - } catch (...) { - throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING); - } - mRawHeaderInitialized = true; -} - -template -void RawReaderFile::readPayload() -{ - try { - // assume the seek is at the payload position - mRawBuffer.readFromStream(mDataFile, mRawHeader.memorySize - sizeof(mRawHeader)); - } catch (...) { - throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_DECODING); - } - mPayloadInitialized = true; -} - -template -const RawHeader& RawReaderFile::getRawHeader() const -{ - if (!mRawHeaderInitialized) - throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_INVALID); - return mRawHeader; -} - -template -const RawBuffer& RawReaderFile::getRawBuffer() const -{ - if (!mPayloadInitialized) - throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_INVALID); - return mRawBuffer; -} - -template -void RawReaderFile::readFile(const std::string_view filename) -{ - RawReaderFile reader(filename); - for (int ipage = 0; ipage < reader.getNumberOfPages(); ipage++) { - reader.nextPage(); - std::cout << reader.getRawHeader(); - } -} - -template class o2::emcal::RawReaderFile; -template class o2::emcal::RawReaderFile; \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/src/RawReaderMemory.cxx b/Detectors/EMCAL/reconstruction/src/RawReaderMemory.cxx index d596bc564cc32..418b6261713ae 100644 --- a/Detectors/EMCAL/reconstruction/src/RawReaderMemory.cxx +++ b/Detectors/EMCAL/reconstruction/src/RawReaderMemory.cxx @@ -10,28 +10,39 @@ #include #include -#include "EMCALBase/RCUTrailer.h" -#include "EMCALReconstruction/RawHeaderStream.h" #include "EMCALReconstruction/RawReaderMemory.h" #include "EMCALReconstruction/RawDecodingError.h" +#include "DetectorsRaw/RDHUtils.h" using namespace o2::emcal; -template -RawReaderMemory::RawReaderMemory(gsl::span rawmemory) : mRawMemoryBuffer(rawmemory) +using RDHDecoder = o2::raw::RDHUtils; + +RawReaderMemory::RawReaderMemory(gsl::span rawmemory) : mRawMemoryBuffer(rawmemory) { init(); } -template -void RawReaderMemory::setRawMemory(const gsl::span rawmemory) +void RawReaderMemory::setRawMemory(const gsl::span rawmemory) { mRawMemoryBuffer = rawmemory; init(); } -template -void RawReaderMemory::init() +o2::header::RDHAny RawReaderMemory::decodeRawHeader(const void* payloadwords) +{ + auto headerversion = RDHDecoder::getVersion(payloadwords); + if (headerversion == 4) { + return o2::header::RDHAny(*reinterpret_cast(payloadwords)); + } else if (headerversion == 5) { + return o2::header::RDHAny(*reinterpret_cast(payloadwords)); + } else if (headerversion == 6) { + return o2::header::RDHAny(*reinterpret_cast(payloadwords)); + } + throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING); +} + +void RawReaderMemory::init() { mCurrentPosition = 0; mRawHeaderInitialized = false; @@ -40,26 +51,36 @@ void RawReaderMemory::init() mNumData = mRawMemoryBuffer.size() / 8192; // assume fixed 8 kB pages } -template -void RawReaderMemory::next() +void RawReaderMemory::next() { mRawPayload.reset(); + mCurrentTrailer.reset(); bool isDataTerminated = false; do { nextPage(false); - // check if we find a valid RCU trailer - // the payload must be at the end of the buffer - // if not present and error will be thrown - try { - RCUTrailer::constructFromPayloadWords(mRawBuffer.getDataWords()); + if (hasNext()) { + auto nextheader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition); + /** + * eventually in the future check continuing payload based on the bc/orbit ID + auto currentbc = RDHDecoder::getTriggerBC(mRawHeader), + nextbc = RDHDecoder::getTriggerBC(nextheader); + auto currentorbit = RDHDecoder::getTriggerOrbit(mRawHeader), + nextorbit = RDHDecoder::getTriggerOrbit(nextheader); + **/ + auto nextpagecounter = RDHDecoder::getPageCounter(nextheader); + if (nextpagecounter == 0) { + isDataTerminated = true; + } else + isDataTerminated = false; + } else isDataTerminated = true; - } catch (...) { - } + // Check if the data continues } while (!isDataTerminated); + // add combined trailer to payload + mRawPayload.appendPayloadWords(mCurrentTrailer.encode()); } -template -void RawReaderMemory::nextPage(bool doResetPayload) +void RawReaderMemory::nextPage(bool doResetPayload) { if (!hasNext()) throw RawDecodingError(RawDecodingError::ErrorType_t::PAGE_NOTFOUND); @@ -67,68 +88,71 @@ void RawReaderMemory::nextPage(bool doResetPayload) mRawPayload.reset(); mRawHeaderInitialized = false; mPayloadInitialized = false; - // Use std::string stream as byte stream - std::string headerwords(mRawMemoryBuffer.data() + mCurrentPosition, sizeof(RawHeader) / sizeof(char)); - std::stringstream headerstream(headerwords); // Read header try { - headerstream >> mRawHeader; + mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition); + RDHDecoder::printRDH(mRawHeader); mRawHeaderInitialized = true; } catch (...) { throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING); } - if (mCurrentPosition + sizeof(RawHeader) + mRawHeader.memorySize >= mRawMemoryBuffer.size()) { + if (mCurrentPosition + RDHDecoder::getMemorySize(mRawHeader) >= mRawMemoryBuffer.size()) { // Payload incomplete throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_DECODING); } else { - mRawBuffer.readFromMemoryBuffer(gsl::span(mRawMemoryBuffer.data() + mCurrentPosition + sizeof(RawHeader), mRawHeader.memorySize)); - mRawPayload.appendPayloadWords(mRawBuffer.getDataWords()); + mRawBuffer.readFromMemoryBuffer(gsl::span(mRawMemoryBuffer.data() + mCurrentPosition + RDHDecoder::getHeaderSize(mRawHeader), RDHDecoder::getMemorySize(mRawHeader) - RDHDecoder::getHeaderSize(mRawHeader))); + + // Read off and chop trailer + // + // Every page gets a trailer. The trailers from the single pages need to be removed. + // There will be a combined trailer which keeps the sum of the payloads for all trailers. + // This will be appended to the chopped payload. + auto trailer = RCUTrailer::constructFromPayloadWords(mRawBuffer.getDataWords()); + if (!mCurrentTrailer.isInitialized()) { + mCurrentTrailer = trailer; + } else { + mCurrentTrailer.setPayloadSize(mCurrentTrailer.getPayloadSize() + trailer.getPayloadSize()); + } + gsl::span payloadWithoutTrailer(mRawBuffer.getDataWords().data(), mRawBuffer.getDataWords().size() - trailer.getTrailerSize()); + + mRawPayload.appendPayloadWords(payloadWithoutTrailer); mRawPayload.increasePageCount(); } - mCurrentPosition += mRawHeader.offsetToNext; /// Assume fixed 8 kB page size + mCurrentPosition += RDHDecoder::getOffsetToNext(mRawHeader); /// Assume fixed 8 kB page size } -template -void RawReaderMemory::readPage(int page) +void RawReaderMemory::readPage(int page) { int currentposition = 8192 * page; if (currentposition >= mRawMemoryBuffer.size()) throw RawDecodingError(RawDecodingError::ErrorType_t::PAGE_NOTFOUND); mRawHeaderInitialized = false; mPayloadInitialized = false; - // Use std::string stream as byte stream - std::string headerwords(mRawMemoryBuffer.data() + currentposition, sizeof(RawHeader) / sizeof(char)); - std::stringstream headerstream(headerwords); // Read header try { - headerstream >> mRawHeader; + mRawHeader = decodeRawHeader(mRawMemoryBuffer.data() + mCurrentPosition); mRawHeaderInitialized = true; } catch (...) { throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_DECODING); } - if (currentposition + sizeof(RawHeader) + mRawHeader.memorySize >= mRawMemoryBuffer.size()) { + if (currentposition + RDHDecoder::getHeaderSize(mRawHeader) + RDHDecoder::getMemorySize(mRawHeader) >= mRawMemoryBuffer.size()) { // Payload incomplete throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_DECODING); } else { - mRawBuffer.readFromMemoryBuffer(gsl::span(mRawMemoryBuffer.data() + currentposition + sizeof(RawHeader), mRawHeader.memorySize)); + mRawBuffer.readFromMemoryBuffer(gsl::span(mRawMemoryBuffer.data() + currentposition + RDHDecoder::getHeaderSize(mRawHeader), RDHDecoder::getMemorySize(mRawHeader))); } } -template -const RawHeader& RawReaderMemory::getRawHeader() const +const o2::header::RDHAny& RawReaderMemory::getRawHeader() const { if (!mRawHeaderInitialized) throw RawDecodingError(RawDecodingError::ErrorType_t::HEADER_INVALID); return mRawHeader; } -template -const RawBuffer& RawReaderMemory::getRawBuffer() const +const RawBuffer& RawReaderMemory::getRawBuffer() const { if (!mPayloadInitialized) throw RawDecodingError(RawDecodingError::ErrorType_t::PAYLOAD_INVALID); return mRawBuffer; } - -template class o2::emcal::RawReaderMemory; -template class o2::emcal::RawReaderMemory; \ No newline at end of file diff --git a/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx b/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx index ab15eb00b48bf..eab0613681186 100644 --- a/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx +++ b/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx @@ -15,6 +15,7 @@ #include "Framework/ControlService.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" +#include "DetectorsRaw/RDHUtils.h" #include "EMCALBase/Geometry.h" #include "EMCALBase/Mapper.h" #include "EMCALReconstruction/CaloFitResults.h" @@ -59,7 +60,7 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx) //o2::emcal::RawReaderMemory rawreader(gsl::span(rawData.payload, o2::framework::DataRefUtils::getPayloadSize(rawData))); - o2::emcal::RawReaderMemory rawreader(o2::framework::DataRefUtils::as(rawData)); + o2::emcal::RawReaderMemory rawreader(o2::framework::DataRefUtils::as(rawData)); bool first = true; uint16_t currentTrigger = 0; @@ -70,37 +71,40 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx) rawreader.next(); - auto header = rawreader.getRawHeader(); + auto& header = rawreader.getRawHeader(); + auto triggerBC = o2::raw::RDHUtils::getTriggerBC(header); + auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(header); + auto feeID = o2::raw::RDHUtils::getFEEID(header); if (!first) { // check if it is the first event in the payload - std::cout << " triggerBC " << header.triggerBC << " current Trigger " << currentTrigger << std::endl; - if (header.triggerBC > currentTrigger) { //new event + std::cout << " triggerBC " << triggerBC << " current Trigger " << currentTrigger << std::endl; + if (triggerBC > currentTrigger) { //new event mOutputTriggerRecords.emplace_back(o2::InteractionRecord(currentTrigger, currentorbit), firstEntry, mOutputCells.size() - 1); firstEntry = mOutputCells.size(); - currentTrigger = header.triggerBC; - currentorbit = header.triggerOrbit; + currentTrigger = triggerBC; + currentorbit = triggerOrbit; } //new event } else { //first - currentTrigger = header.triggerBC; + currentTrigger = triggerBC; std::cout << " first is true and I set triggerBC to currentTrigger " << currentTrigger << std::endl; - currentorbit = header.triggerOrbit; + currentorbit = triggerOrbit; std::cout << " and set first to false " << std::endl; first = false; } - if (header.feeId > 40) + if (feeID > 40) continue; //skip STU ddl //std::cout< decoder(rawreader); + o2::emcal::AltroDecoder decoder(rawreader); decoder.decode(); std::cout << decoder.getRCUTrailer() << std::endl; - o2::emcal::Mapper map = mMapper->getMappingForDDL(header.feeId); + o2::emcal::Mapper map = mMapper->getMappingForDDL(feeID); // Loop over all the channels for (auto& chan : decoder.getChannels()) { @@ -108,7 +112,7 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx) int iRow = map.getRow(chan.getHardwareAddress()); int iCol = map.getColumn(chan.getHardwareAddress()); ChannelType_t chantype = map.getChannelType(chan.getHardwareAddress()); - int iSM = header.feeId / 2; + int iSM = feeID / 2; int CellID = mGeometry->GetAbsCellIdFromCellIndexes(iSM, iRow, iCol);