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