Project
Loading...
Searching...
No Matches
PedestalProcessorDevice.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
14#include "EMCALBase/Geometry.h"
20
21#include <fairlogger/Logger.h>
22
23using namespace o2::emcal;
24
26{
27 LOG(debug) << "[EMCALRawToCellConverter - init] Initialize converter ";
28 if (!mGeometry) {
29 mGeometry = Geometry::GetInstanceFromRunNumber(300000);
30 }
31 if (!mGeometry) {
32 LOG(error) << "Failure accessing geometry";
33 }
34
35 if (!mMapper) {
36 mMapper = std::unique_ptr<MappingHandler>(new o2::emcal::MappingHandler);
37 }
38 if (!mMapper) {
39 LOG(error) << "Failed to initialize mapper";
40 }
41}
42
44{
45 constexpr auto originEMC = o2::header::gDataOriginEMC;
46 constexpr auto descRaw = o2::header::gDataDescriptionRawData;
47
48 mPedestalData.reset();
49
50 if (isLostTimeframe(ctx)) {
51 sendData(ctx, mPedestalData);
52 return;
53 }
54
55 std::vector<framework::InputSpec> filter{{"filter", framework::ConcreteDataTypeMatcher(originEMC, descRaw)}};
56 for (const auto& rawData : framework::InputRecordWalker(ctx.inputs(), filter)) {
57 // Skip SOX headers
58 auto rdhblock = reinterpret_cast<const o2::header::RDHAny*>(rawData.payload);
59 if (o2::raw::RDHUtils::getHeaderSize(rdhblock) == static_cast<int>(o2::framework::DataRefUtils::getPayloadSize(rawData))) {
60 continue;
61 }
62
63 o2::emcal::RawReaderMemory rawreader(framework::DataRefUtils::as<const char>(rawData));
64 rawreader.setRangeSRUDDLs(0, 39);
65
66 // loop over all the DMA pages
67 while (rawreader.hasNext()) {
68 try {
69 rawreader.next();
70 } catch (RawDecodingError& e) {
71 LOG(error) << e.what();
73 // We must break in case of header decoding as the offset to the next payload is lost
74 // consequently the parser does not know where to continue leading to an infinity loop
75 break;
76 }
77 // We must skip the page as payload is not consistent
78 // otherwise the next functions will rethrow the exceptions as
79 // the page format does not follow the expected format
80 continue;
81 }
82 for (const auto& e : rawreader.getMinorErrors()) {
83 LOG(warning) << "Found minor Raw decoder error in FEE " << e.getFEEID() << ": " << RawDecodingError::getErrorCodeTitles(RawDecodingError::ErrorTypeToInt(e.getErrorType()));
84 }
85
86 auto& header = rawreader.getRawHeader();
87 auto feeID = raw::RDHUtils::getFEEID(header);
88 auto triggerbits = raw::RDHUtils::getTriggerType(header);
89
90 if (feeID >= 40) {
91 continue; // skip STU ddl
92 }
93
94 // use the altro decoder to decode the raw data, and extract the RCU trailer
95 AltroDecoder decoder(rawreader);
96 // check the words of the payload exception in altrodecoder
97 try {
98 decoder.decode();
99 } catch (AltroDecoderError& e) {
100 LOG(error) << e.what();
101 continue;
102 }
103 for (const auto& e : decoder.getMinorDecodingErrors()) {
104 LOG(warning) << e.what();
105 }
106
107 try {
108
109 const auto& map = mMapper->getMappingForDDL(feeID);
110 uint16_t iSM = feeID / 2;
111
112 // Loop over all the channels
113 int nBunchesNotOK = 0;
114 for (auto& chan : decoder.getChannels()) {
115 int iRow, iCol;
116 ChannelType_t chantype;
117 try {
118 iRow = map.getRow(chan.getHardwareAddress());
119 iCol = map.getColumn(chan.getHardwareAddress());
120 chantype = map.getChannelType(chan.getHardwareAddress());
122 LOG(error) << ex.what();
123 continue;
124 }
125
127 continue;
128 }
129
130 int CellID = -1;
131 bool isLowGain = false;
132 try {
134 // high- / low-gain cell
135 CellID = getCellAbsID(iSM, iCol, iRow);
136 isLowGain = chantype == o2::emcal::ChannelType_t::LOW_GAIN;
137 } else {
138 CellID = geLEDMONAbsID(iSM, iCol); // Module index encoded in colum for LEDMONs
139 isLowGain = iRow == 0; // For LEDMONs gain type is encoded in the row (0 - low gain, 1 - high gain)
140 }
141 } catch (ModuleIndexException& e) {
142 LOG(error) << e.what();
143 continue;
144 }
145
146 // Fill pedestal object
147 for (auto& bunch : chan.getBunches()) {
148 for (auto e : bunch.getADC()) {
149 mPedestalData.fillADC(e, CellID, isLowGain, chantype == o2::emcal::ChannelType_t::LEDMON);
150 }
151 }
152 }
153 } catch (o2::emcal::MappingHandler::DDLInvalid& ddlerror) {
154 // Unable to catch mapping
155 LOG(error) << ddlerror.what();
156 }
157 }
158 }
159
160 sendData(ctx, mPedestalData);
161}
162
163int PedestalProcessorDevice::getCellAbsID(int supermoduleID, int column, int row) const
164{
165 auto [phishift, etashift] = mGeometry->ShiftOnlineToOfflineCellIndexes(supermoduleID, row, column);
166 int cellID = mGeometry->GetAbsCellIdFromCellIndexes(supermoduleID, phishift, etashift);
167 if (cellID > 17664 || cellID < 0) {
168 throw ModuleIndexException(cellID, column, row, etashift, phishift);
169 }
170 return cellID;
171}
172
173int PedestalProcessorDevice::geLEDMONAbsID(int supermoduleID, int moduleID) const
174{
175 if (moduleID >= o2::emcal::EMCAL_LEDREFS || moduleID < 0) {
176 throw ModuleIndexException(moduleID);
177 }
178 return supermoduleID * o2::emcal::EMCAL_LEDREFS + moduleID;
179}
180
182{
183 constexpr auto originEMC = header::gDataOriginEMC;
184 o2::framework::InputSpec dummy{"dummy",
187 0xDEADBEEF}};
188 static size_t contDeadBeef = 0; // number of times 0xDEADBEEF was seen continuously
189 for (const auto& ref : o2::framework::InputRecordWalker(ctx.inputs(), {dummy})) {
190 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
192 if (payloadSize == 0) {
194 if (++contDeadBeef <= maxWarn) {
195 LOGP(alarm, "Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
196 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
197 contDeadBeef == maxWarn ? fmt::format(". {} such inputs in row received, stopping reporting", contDeadBeef) : "");
198 }
199 return true;
200 }
201 }
202 contDeadBeef = 0; // if good data, reset the counter
203 return false;
204}
205
207{
208 constexpr auto originEMC = o2::header::gDataOriginEMC;
209 ctx.outputs().snapshot(framework::Output{originEMC, "PEDDATA", 0}, data);
210}
211
213{
214 constexpr auto originEMC = o2::header::gDataOriginEMC;
215 std::vector<o2::framework::InputSpec> inputs{{"stf", o2::framework::ConcreteDataTypeMatcher{originEMC, o2::header::gDataDescriptionRawData}, o2::framework::Lifetime::Timeframe}};
216 std::vector<o2::framework::OutputSpec> outputs;
217 outputs.emplace_back(originEMC, "PEDDATA", 0, o2::framework::Lifetime::Timeframe);
218 if (askDistSTF) {
219 inputs.emplace_back("stdDist", "FLP", "DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
220 }
221
223 "PedestalProcessor",
224 inputs,
225 outputs,
226 o2::framework::AlgorithmSpec{o2::framework::adaptFromTask<PedestalProcessorDevice>()},
228}
A helper class to iteratate over all parts of all input routes.
std::ostringstream debug
Error handling of the ALTRO Decoder.
Decoder of the ALTRO data in the raw page.
void decode()
Decode the ALTRO stream.
const std::vector< Channel > & getChannels() const
Get the reference to the channel container.
const std::vector< MinorAltroDecodingError > & getMinorDecodingErrors() const
Get list of minor decoding errors.
static Geometry * GetInstanceFromRunNumber(Int_t runNumber, const std::string_view="", const std::string_view mcname="TGeant3", const std::string_view mctitle="")
Instanciate geometry depending on the run number. Mostly used in analysis and MC anchors.
Definition Geometry.cxx:219
std::tuple< int, int > ShiftOnlineToOfflineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
Adapt cell indices in supermodule to online indexing.
Int_t GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
Transition from super module number (nSupMod) and cell indexes (ieta,iphi) to cell absolute ID number...
Definition Geometry.cxx:791
Error handling requests for unknown hardware addresses.
Definition Mapper.h:85
const char * what() const noexcept override
Access to error message.
Definition Mapper.h:103
Error handling for invalid DDL IDs (not in range for EMCAL)
Definition Mapper.h:321
const char * what() const noexcept final
Access to the error message of the exception.
Definition Mapper.h:330
Handler providing the correct mapping for the given DDL.
Definition Mapper.h:313
Exchange container between PedestalProcessorDevice and PedestalAggregatorDevice.
void fillADC(unsigned short adc, unsigned short tower, bool lowGain, bool LEDMON)
Fill ADC value for certain channel.
int getCellAbsID(int supermoduleID, int column, int row) const
bool isLostTimeframe(framework::ProcessingContext &ctx) const
void init(framework::InitContext &ctx) final
void run(framework::ProcessingContext &ctx) final
int geLEDMONAbsID(int supermoduleID, int moduleID) const
void sendData(framework::ProcessingContext &ctx, const PedestalProcessorData &data) const
Error handling of the raw reader.
const char * what() const noexcept override
Providing error message of the exception.
static const char * getErrorCodeTitles(ErrorType_t errortype)
Get title of error type.
@ HEADER_DECODING
Header cannot be decoded (format incorrect)
@ HEADER_INVALID
Header in memory not belonging to requested superpage.
static int ErrorTypeToInt(RawDecodingError::ErrorType_t errortype)
Convert error type to error code number.
ErrorType_t getErrorType() const
Get the type identifier of the error handled with this exception.
Reader for raw data produced by the Readout application in in-memory format.
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
void setRangeSRUDDLs(uint16_t minDDL, uint16_t maxDDL)
Set range for DDLs from SRU (for RCU trailer merging)
void next()
Read next payload from the stream.
gsl::span< const MinorError > getMinorErrors() const
Get minor (non-crashing) raw decoding errors.
void snapshot(const Output &spec, T const &object)
A helper class to iteratate over all parts of all input routes.
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
GLboolean * data
Definition glcorearb.h:298
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
constexpr o2::header::DataDescription gDataDescriptionRawData
Definition DataHeader.h:597
constexpr o2::header::DataOrigin gDataOriginEMC
Definition DataHeader.h:565
@ EMCAL_LEDREFS
Number of LEDs (reference/monitors) per module for EMCAL; one per StripModule.
Definition Constants.h:27
ChannelType_t
Type of a raw data channel.
Definition Constants.h:33
@ HIGH_GAIN
High gain channel.
Definition Constants.h:35
@ LOW_GAIN
Low gain channel.
Definition Constants.h:34
@ LEDMON
LED monitor channel.
Definition Constants.h:37
framework::DataProcessorSpec getPedestalProcessorDevice(bool askDistSTF)
std::vector< ConfigParamSpec > Options
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row