Project
Loading...
Searching...
No Matches
RawPixelDecoder.h
Go to the documentation of this file.
1// Copyright 2019-2026 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#ifndef ALICEO2_ITSMFT_RAWPIXELDECODER_H_
15#define ALICEO2_ITSMFT_RAWPIXELDECODER_H_
16
17#include <unordered_map>
18#include <array>
19#include <TStopwatch.h>
20#include "Framework/Logger.h"
21#include "Framework/InputSpec.h"
26#include "Headers/DataHeader.h"
34
35namespace o2
36{
37namespace framework
38{
39class InputRecord;
40class TimingInfo;
41} // namespace framework
42
43namespace itsmft
44{
45class ChipPixelData;
46
47template <class Mapping>
48class RawPixelDecoder final : public PixelReader
49{
51
52 public:
54 ~RawPixelDecoder() final = default;
55 void setFormat(GBTLink::Format f) {}
56 void init() final {}
57 bool getNextChipData(ChipPixelData& chipData) final;
58 ChipPixelData* getNextChipData(std::vector<ChipPixelData>& chipDataVec) final;
61 void collectROFCableData(int iru);
62 int decodeNextTrigger() final;
63
64 template <class DigitContainer, class ROFContainer>
65 int fillDecodedDigits(DigitContainer& digits, ROFContainer& rofs);
66
67 template <class STATVEC>
68 void fillChipsStatus(STATVEC& chipStatus);
69
70 template <class CalibContainer>
71 void fillCalibData(CalibContainer& calib);
72
73 template <class LinkErrors, class DecErrors, class ErrMsgs>
74 void collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos);
75
76 const RUDecodeData* getRUDecode(int ruSW) const { return mRUEntry[ruSW] < 0 ? nullptr : &mRUDecodeVec[mRUEntry[ruSW]]; }
77 const GBTLink* getGBTLink(int i) const { return i < 0 ? nullptr : &mGBTLinks[i]; }
78 int getNLinks() const { return mGBTLinks.size(); }
79
80 auto getUserDataOrigin() const { return mUserDataOrigin; }
81 void setUserDataOrigin(header::DataOrigin orig) { mUserDataOrigin = orig; }
82
83 auto getUserDataDescription() const { return mUserDataDescription; }
84 void setUserDataDescription(header::DataDescription desc) { mUserDataDescription = desc; }
85
86 void setNThreads(int n);
87 int getNThreads() const { return mNThreads; }
88
89 void setFillCalibData(bool v) { mFillCalibData = v; }
90 bool getFillCalibData() const { return mFillCalibData; }
91
92 void setVerbosity(int v);
93 int getVerbosity() const { return mVerbosity; }
94
95 void setInputFilter(std::vector<o2::framework::InputSpec> filter) { mInputFilter = std::move(filter); }
96 const auto& getInputFilter() const noexcept { return mInputFilter; }
97
98 void setAlwaysParseTrigger(bool v) { mAlwaysParseTrigger = v; }
99 bool getAlwaysParseTrigger() const { return mAlwaysParseTrigger; }
100
101 void printReport(bool decstat = true, bool skipNoErr = true) const;
102 size_t produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo);
103
104 void clearStat(bool resetRaw = false);
105
106 TStopwatch& getTimerTFStart() { return mTimerTFStart; }
107 TStopwatch& getTimerDecode() { return mTimerDecode; }
108 TStopwatch& getTimerExtract() { return mTimerFetchData; }
109 uint32_t getNChipsFiredROF() const { return mNChipsFiredROF; }
110 uint32_t getNPixelsFiredROF() const { return mNPixelsFiredROF; }
111 size_t getNChipsFired() const { return mNChipsFired; }
112 size_t getNPixelsFired() const { return mNPixelsFired; }
113
114 void setAllowEmptyROFs(bool v) { mAlloEmptyROFs = v; }
115 bool getAllowEmptyROFs() const { return mAlloEmptyROFs; }
116
117 void setVerifyDecoder(bool v) { mVerifyDecoder = v; }
118 bool getVerifyDecoder() const { return mVerifyDecoder; }
119
120 void setInstanceID(size_t i) { mInstanceID = i; }
121 void setNInstances(size_t n) { mNInstances = n; }
122 auto getInstanceID() const { return mInstanceID; }
123 auto getNInstances() const { return mNInstances; }
124
125 void setRawDumpDirectory(const std::string& s) { mRawDumpDirectory = s; }
126 auto getRawDumpDirectory() const { return mRawDumpDirectory; }
127
128 std::vector<PhysTrigger>& getExternalTriggers() { return mExtTriggers; }
129 const std::vector<PhysTrigger>& getExternalTriggers() const { return mExtTriggers; }
130
131 void setSkipRampUpData(bool v = true) { mSkipRampUpData = v; }
132 bool getSkipRampUpData() const { return mSkipRampUpData; }
133 auto getNROFsProcessed() const { return mROFCounter; }
134
135 struct LinkEntry {
136 int entry = -1;
137 };
138
139 uint16_t getSquashingDepth() { return 0; }
140 bool doIRMajorityPoll();
141 bool isRampUpStage() const { return mROFRampUpStage; }
142 void reset();
143
144 private:
145 void setupLinks(o2::framework::InputRecord& inputsm);
146 int getRUEntrySW(int ruSW) const { return mRUEntry[ruSW]; }
147 RUDecodeData* getRUDecode(int ruSW) { return &mRUDecodeVec[mRUEntry[ruSW]]; }
148 GBTLink* getGBTLink(int i) { return i < 0 ? nullptr : &mGBTLinks[i]; }
149 RUDecodeData& getCreateRUDecode(int ruSW);
150
151 static constexpr uint16_t NORUDECODED = 0xffff; // this must be > than max N RUs
152
153 std::vector<o2::framework::InputSpec> mInputFilter; // input spec filter
154 std::vector<GBTLink> mGBTLinks; // active links pool
155 std::unordered_map<uint32_t, LinkEntry> mSubsSpec2LinkID; // link subspec to link entry in the pool mapping
156 std::vector<RUDecodeData> mRUDecodeVec; // set of active RUs
157 std::array<short, Mapping::getNRUs()> mRUEntry; // entry of the RU with given SW ID in the mRUDecodeVec
158 std::vector<ChipPixelData*> mOrderedChipsPtr; // special ordering helper used for the MFT (its chipID is not contiguous in RU)
159 std::vector<PhysTrigger> mExtTriggers; // external triggers
160 GBTLink* mLinkForTriggers = nullptr; // link assigned to collect the triggers
161 std::string mSelfName{}; // self name
162 std::string mRawDumpDirectory; // destination directory for dumps
163 header::DataOrigin mUserDataOrigin = o2::header::gDataOriginInvalid; // alternative user-provided data origin to pick
164 header::DataDescription mUserDataDescription = o2::header::gDataDescriptionInvalid; // alternative user-provided description to pick
165 uint16_t mCurRUDecodeID = NORUDECODED; // index of currently processed RUDecode container
166 int mLastReadChipID = -1; // chip ID returned by previous getNextChipData call, used for ordering checks
167 int mNLinksInTF = 0; // number of links seen in the TF
168 Mapping mMAP; // chip mapping
169 std::unordered_map<o2::InteractionRecord, int> mIRPoll; // poll for links IR used for synchronization
170 bool mFillCalibData = false; // request to fill calib data from GBT
171 bool mAlloEmptyROFs = false; // do not skip empty ROFs
172 bool mROFRampUpStage = false; // are we still in the ROF ramp up stage?
173 bool mSkipRampUpData = false;
174 bool mVerifyDecoder = false;
175 bool mAlwaysParseTrigger = false;
176 int mVerbosity = 0;
177 int mNThreads = 1; // number of decoding threads
178 // statistics
179 o2::itsmft::ROFRecord::ROFtype mROFCounter = 0; // RSTODO is this needed? eliminate from ROFRecord ?
180 uint32_t mNChipsFiredROF = 0; // counter within the ROF
181 uint32_t mNPixelsFiredROF = 0; // counter within the ROF
182 uint32_t mNLinksDone = 0; // number of links reached end of data
183 size_t mNChipsFired = 0; // global counter
184 size_t mNPixelsFired = 0; // global counter
185 size_t mNExtTriggers = 0; // global counter
186 size_t mInstanceID = 0; // pipeline instance
187 size_t mNInstances = 1; // total number of pipelines
188 TStopwatch mTimerTFStart;
189 TStopwatch mTimerDecode;
190 TStopwatch mTimerFetchData;
191};
192
195template <class Mapping>
196template <class DigitContainer, class ROFContainer>
197int RawPixelDecoder<Mapping>::fillDecodedDigits(DigitContainer& digits, ROFContainer& rofs)
198{
199 if (mInteractionRecord.isDummy()) {
200 return 0; // nothing was decoded
201 }
202 mTimerFetchData.Start(false);
203 int ref = digits.size();
204 for (unsigned int iru = 0; iru < mRUDecodeVec.size(); iru++) {
205 for (int ic = 0; ic < mRUDecodeVec[iru].nChipsFired; ic++) {
206 const auto& chip = mRUDecodeVec[iru].chipsData[ic];
207 for (const auto& hit : mRUDecodeVec[iru].chipsData[ic].getData()) {
208 digits.emplace_back(chip.getChipID(), hit.getRow(), hit.getCol());
209 }
210 }
211 }
212 int nFilled = digits.size() - ref;
213 rofs.emplace_back(mInteractionRecord, mROFCounter, ref, nFilled);
214 mTimerFetchData.Stop();
215 return nFilled;
216}
217
220template <>
221template <class DigitContainer, class ROFContainer>
222int RawPixelDecoder<ChipMappingMFT>::fillDecodedDigits(DigitContainer& digits, ROFContainer& rofs)
223{
224 if (mInteractionRecord.isDummy()) {
225 return 0; // nothing was decoded
226 }
227 mTimerFetchData.Start(false);
228 int ref = digits.size();
229 for (auto chipData = mOrderedChipsPtr.rbegin(); chipData != mOrderedChipsPtr.rend(); ++chipData) {
230 assert(mLastReadChipID < (*chipData)->getChipID());
231 mLastReadChipID = (*chipData)->getChipID();
232 for (const auto& hit : (*chipData)->getData()) {
233 digits.emplace_back(mLastReadChipID, hit.getRow(), hit.getCol());
234 }
235 }
236 int nFilled = digits.size() - ref;
237 rofs.emplace_back(mInteractionRecord, mROFCounter, ref, nFilled);
238 mTimerFetchData.Stop();
239 return nFilled;
240}
241
244template <class Mapping>
245template <class STATVEC>
247{
248 if (mInteractionRecord.isDummy() || mROFRampUpStage) {
249 return; // nothing was decoded
250 }
251 for (unsigned int iru = 0; iru < mRUDecodeVec.size(); iru++) {
252 for (auto chID : mRUDecodeVec[iru].seenChipIDs) {
253 chipStatus[chID] = 1;
254 }
255 }
256}
257
260template <class Mapping>
261template <class CalibContainer>
263{
264 if (!mInteractionRecord.isDummy()) {
265 auto curSize = calib.size();
266 calib.resize(curSize + Mapping::getNRUs());
267 for (unsigned int iru = 0; iru < mRUDecodeVec.size(); iru++) {
268 calib[curSize + mRUDecodeVec[iru].ruSWID] = mRUDecodeVec[iru].calibData;
269 }
270 }
271}
272
274template <class Mapping>
275template <class LinkErrors, class DecErrors, class ErrMsgs>
276void RawPixelDecoder<Mapping>::collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos)
277{
278 for (auto& lnk : mGBTLinks) {
279 if (lnk.gbtErrStatUpadated) {
280 linkErrors.push_back(lnk.statistics);
281 lnk.gbtErrStatUpadated = false;
282 }
283 }
284 size_t nerr = 0, nerrMsg = 0;
285 for (auto& ru : mRUDecodeVec) {
286 nerr += ru.chipErrorsTF.size();
287 nerrMsg += ru.errMsgVecTF.size();
288 }
289 if (nerr || nerrMsg) {
290 decErrors.reserve(nerr);
291 errInfos.reserve(nerrMsg);
292 for (auto& ru : mRUDecodeVec) {
293 for (const auto& err : ru.chipErrorsTF) {
294 decErrors.emplace_back(ChipError{err.first, err.second.first, err.second.second}); // id, nerrors, errorFlags
295 }
296 for (auto& err : ru.errMsgVecTF) {
297 errInfos.push_back(err);
298 }
299 ru.chipErrorsTF.clear();
300 ru.errMsgVecTF.clear();
301 }
302 }
303}
304
307
308} // namespace itsmft
309} // namespace o2
310
311#endif /* ALICEO2_ITSMFT_RAWPIXELDECODER_H */
int32_t i
Definition of the ITSMFT ROFrame (trigger) record.
Transient data classes for single pixel and set of pixels from current chip.
Abstract class for Alpide data reader class.
Definition of the RAW Data Header.
Declaration of the Readout Unite decoder class.
Checks validity of hardware address (HW) and transform it to digit AbsId index.
The input API of the Data Processing Layer This class holds the inputs which are valid for processing...
PixelReader class for the ITSMFT.
Definition PixelReader.h:34
unsigned int ROFtype
Definition ROFRecord.h:38
void setInputFilter(std::vector< o2::framework::InputSpec > filter)
void fillCalibData(CalibContainer &calib)
const auto & getInputFilter() const noexcept
const std::vector< PhysTrigger > & getExternalTriggers() const
void setFormat(GBTLink::Format f)
void fillChipsStatus(STATVEC &chipStatus)
const RUDecodeData * getRUDecode(int ruSW) const
void setRawDumpDirectory(const std::string &s)
void startNewTF(o2::framework::InputRecord &inputs)
void setUserDataOrigin(header::DataOrigin orig)
size_t produceRawDataDumps(int dump, const o2::framework::TimingInfo &tinfo)
void printReport(bool decstat=true, bool skipNoErr=true) const
bool getNextChipData(ChipPixelData &chipData) final
const GBTLink * getGBTLink(int i) const
void setUserDataDescription(header::DataDescription desc)
void setSkipRampUpData(bool v=true)
void clearStat(bool resetRaw=false)
std::vector< PhysTrigger > & getExternalTriggers()
uint32_t getNPixelsFiredROF() const
void collectDecodingErrors(LinkErrors &linkErrors, DecErrors &decErrors, ErrMsgs &errInfos)
int fillDecodedDigits(DigitContainer &digits, ROFContainer &rofs)
~RawPixelDecoder() final=default
uint32_t getNChipsFiredROF() const
void dump(const std::string what, DPMAP m, int verbose)
Definition dcs-ccdb.cxx:79
GLdouble n
Definition glcorearb.h:1982
GLuint entry
Definition glcorearb.h:5735
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLint ref
Definition glcorearb.h:291
constexpr o2::header::DataDescription gDataDescriptionInvalid
Definition DataHeader.h:597
constexpr o2::header::DataOrigin gDataOriginInvalid
Definition DataHeader.h:561
Descriptor< gSizeDataDescriptionString > DataDescription
Definition DataHeader.h:551
RAWDataHeaderV7 RAWDataHeader
Descriptor< gSizeDataOriginString > DataOrigin
Definition DataHeader.h:550
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::vector< Digit > digits