Project
Loading...
Searching...
No Matches
RawDecoderSpec.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 <string>
13#include <fairlogger/Logger.h>
24
25using namespace o2::ctp::reco_workflow;
26
28{
29 mCheckConsistency = ctx.options().get<bool>("check-consistency");
30 mDecoder.setCheckConsistency(mCheckConsistency);
31 mDecodeinputs = ctx.options().get<bool>("ctpinputs-decoding");
32 mDecoder.setDecodeInps(mDecodeinputs);
33 mNTFToIntegrate = ctx.options().get<int>("ntf-to-average");
34 mVerbose = ctx.options().get<bool>("use-verbose-mode");
35 int maxerrors = ctx.options().get<int>("print-errors-num");
36 mDecoder.setVerbose(mVerbose);
37 mDecoder.setDoLumi(mDoLumi);
38 mDecoder.setDoDigits(mDoDigits);
39 mDecoder.setMAXErrors(maxerrors);
40 std::string lumiinp1 = ctx.options().get<std::string>("lumi-inp1");
41 std::string lumiinp2 = ctx.options().get<std::string>("lumi-inp2");
42 int inp1 = mDecoder.setLumiInp(1, lumiinp1);
43 int inp2 = mDecoder.setLumiInp(2, lumiinp2);
44 mOutputLumiInfo.inp1 = inp1;
45 mOutputLumiInfo.inp2 = inp2;
46 mMaxInputSize = ctx.options().get<int>("max-input-size");
47 mMaxInputSizeFatal = ctx.options().get<bool>("max-input-size-fatal");
48 LOG(info) << "CTP reco init done. Inputs decoding here:" << mDecodeinputs << " DoLumi:" << mDoLumi << " DoDigits:" << mDoDigits << " NTF:" << mNTFToIntegrate << " Lumi inputs:" << lumiinp1 << ":" << inp1 << " " << lumiinp2 << ":" << inp2 << " Max errors:" << maxerrors << " Max input size:" << mMaxInputSize << " MaxInputSizeFatal:" << mMaxInputSizeFatal << " CheckConsistency:" << mCheckConsistency;
49 // mOutputLumiInfo.printInputs();
50}
52{
53 auto clsEA = mDecoder.getClassErrorsA();
54 auto clsEB = mDecoder.getClassErrorsB();
55 auto cntCA = mDecoder.getClassCountersA();
56 auto cntCB = mDecoder.getClassCountersB();
57 int totClasses = 0;
58 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
59 mClsEA[i] += clsEA[i];
60 mClsEB[i] += clsEB[i];
61 mClsA[i] += cntCA[i];
62 mClsB[i] += cntCB[i];
63 totClasses += cntCA[i];
64 }
65 auto& TFOrbits = mDecoder.getTFOrbits();
66 std::sort(TFOrbits.begin(), TFOrbits.end());
67 size_t l = TFOrbits.size();
68 uint32_t o0 = 0;
69 if (l) {
70 o0 = TFOrbits[0];
71 }
72 int nmiss = 0;
73 int nprt = 0;
74 std::cout << "Missing orbits:";
75 for (int i = 1; i < l; i++) {
76 if ((TFOrbits[i] - o0) > 0x20) {
77 if (nprt < 20) {
78 std::cout << " " << o0 << "-" << TFOrbits[i];
79 }
80 nmiss += (TFOrbits[i] - o0) / 0x20;
81 nprt++;
82 }
83 o0 = TFOrbits[i];
84 }
85 std::cout << std::endl;
86 LOG(info) << "Number of non continous TF:" << nmiss << std::endl;
87 LOG(info) << "Lost in shiftInputs:" << mLostDueToShiftInps;
88 LOG(info) << "Lost in addDigit Inputs:" << mIRRejected << " Classes:" << mTCRRejected;
89 if (mErrorIR || mErrorTCR) {
90 LOG(error) << "# of IR errors:" << mErrorIR << " TCR errors:" << mErrorTCR << std::endl;
91 }
92 if (mCheckConsistency) {
93 LOG(info) << "Lost due to the shift Consistency Checker:" << mDecoder.getLostDueToShiftCls();
94 LOG(info) << "Total classes:" << totClasses;
95 auto ctpcfg = mDecoder.getCTPConfig();
96 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
97 std::string name = ctpcfg.getClassNameFromIndex(i);
98 if (mClsEA[i]) {
99 LOG(error) << " Class without inputs:";
100 }
101 LOG(important) << "CLASS:" << name << ":" << i << " Cls=>Inp:" << mClsA[i] << " Inp=>Cls:" << mClsB[i] << " ErrorsCls=>Inps:" << mClsEA[i] << " MissingInps=>Cls:" << mClsEB[i];
102 }
103 }
104}
106{
108 mOutputDigits.clear();
109 std::map<o2::InteractionRecord, CTPDigit> digits;
113 // setUpDummyLink
114 auto& inputs = ctx.inputs();
115 auto dummyOutput = [&ctx, this]() {
116 if (this->mDoDigits) {
117 ctx.outputs().snapshot(o2::framework::Output{"CTP", "DIGITS", 0}, this->mOutputDigits);
118 }
119 if (this->mDoLumi) {
120 ctx.outputs().snapshot(o2::framework::Output{"CTP", "LUMI", 0}, this->mOutputLumiInfo);
121 }
122 };
123 // if we see requested data type input with 0xDEADBEEF subspec and 0 payload this means that the "delayed message"
124 // mechanism created it in absence of real data from upstream. Processor should send empty output to not block the workflow
125 {
126 static size_t contDeadBeef = 0; // number of times 0xDEADBEEF was seen continuously
127 std::vector<InputSpec> dummy{InputSpec{"dummy", o2::framework::ConcreteDataMatcher{"CTP", "RAWDATA", 0xDEADBEEF}}};
128 for (const auto& ref : o2::framework::InputRecordWalker(inputs, dummy)) {
129 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
131 if (payloadSize == 0) {
133 if (++contDeadBeef <= maxWarn) {
134 LOGP(alarm, "Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
135 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
136 contDeadBeef == maxWarn ? fmt::format(". {} such inputs in row received, stopping reporting", contDeadBeef) : "");
137 }
138 dummyOutput();
139 return;
140 }
141 }
142 contDeadBeef = 0; // if good data, reset the counter
143 }
144 //
145 std::vector<LumiInfo> lumiPointsHBF1;
146 std::vector<InputSpec> filter{InputSpec{"filter", ConcreteDataTypeMatcher{"CTP", "RAWDATA"}, Lifetime::Timeframe}};
147 bool fatal_flag = 0;
148 if (mMaxInputSize > 0) {
149 size_t payloadSize = 0;
150 for (const auto& ref : o2::framework::InputRecordWalker(inputs, filter)) {
151 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
153 }
154 if (payloadSize > (size_t)mMaxInputSize) {
155 if (mMaxInputSizeFatal) {
156 fatal_flag = 1;
157 LOG(error) << "Input data size bigger than threshold: " << mMaxInputSize << " < " << payloadSize << " decoding TF and exiting.";
158 // LOG(fatal) << "Input data size:" << payloadSize; - fatal issued in decoder
159 } else {
160 LOG(error) << "Input data size:" << payloadSize << " sending dummy output";
161 dummyOutput();
162 return;
163 }
164 }
165 }
166 int ret = 0;
167 if (fatal_flag) {
168 ret = mDecoder.decodeRawFatal(inputs, filter);
169 } else {
170 ret = mDecoder.decodeRaw(inputs, filter, mOutputDigits, lumiPointsHBF1);
171 }
172 if (ret == 1) {
173 dummyOutput();
174 return;
175 }
176 if (mDoDigits) {
177 LOG(info) << "[CTPRawToDigitConverter - run] Writing " << mOutputDigits.size() << " digits. IR rejected:" << mDecoder.getIRRejected() << " TCR rejected:" << mDecoder.getTCRRejected();
178 ctx.outputs().snapshot(o2::framework::Output{"CTP", "DIGITS", 0}, mOutputDigits);
179 mLostDueToShiftInps += mDecoder.getLostDueToShiftInp();
180 mErrorIR += mDecoder.getErrorIR();
181 mErrorTCR += mDecoder.getErrorTCR();
182 mIRRejected += mDecoder.getIRRejected();
183 mTCRRejected += mDecoder.getTCRRejected();
184 }
185 if (mDoLumi) {
186 uint32_t tfCountsT = 0;
187 uint32_t tfCountsV = 0;
188 for (auto const& lp : lumiPointsHBF1) {
189 tfCountsT += lp.counts;
190 tfCountsV += lp.countsFV0;
191 }
192 // LOG(info) << "Lumi rate:" << tfCounts/(128.*88e-6);
193 // FT0
194 mHistoryT.push_back(tfCountsT);
195 mCountsT += tfCountsT;
196 if (mHistoryT.size() <= mNTFToIntegrate) {
197 mNHBIntegratedT += lumiPointsHBF1.size();
198 } else {
199 mCountsT -= mHistoryT.front();
200 mHistoryT.pop_front();
201 }
202 // FV0
203 mHistoryV.push_back(tfCountsV);
204 mCountsV += tfCountsV;
205 if (mHistoryV.size() <= mNTFToIntegrate) {
206 mNHBIntegratedV += lumiPointsHBF1.size();
207 } else {
208 mCountsV -= mHistoryV.front();
209 mHistoryV.pop_front();
210 }
211 //
212 if (mNHBIntegratedT || mNHBIntegratedV) {
213 mOutputLumiInfo.orbit = lumiPointsHBF1[0].orbit;
214 }
215 mOutputLumiInfo.counts = mCountsT;
216
217 mOutputLumiInfo.countsFV0 = mCountsV;
218 mOutputLumiInfo.nHBFCounted = mNHBIntegratedT;
219 mOutputLumiInfo.nHBFCountedFV0 = mNHBIntegratedV;
220 if (mVerbose) {
221 mOutputLumiInfo.printInputs();
222 LOGP(info, "Orbit {}: {}/{} counts inp1/inp2 in {}/{} HBFs -> lumi_inp1 = {:.3e}+-{:.3e} lumi_inp2 = {:.3e}+-{:.3e}", mOutputLumiInfo.orbit, mCountsT, mCountsV, mNHBIntegratedT, mNHBIntegratedV, mOutputLumiInfo.getLumi(), mOutputLumiInfo.getLumiError(), mOutputLumiInfo.getLumiFV0(), mOutputLumiInfo.getLumiFV0Error());
223 }
224 ctx.outputs().snapshot(o2::framework::Output{"CTP", "LUMI", 0}, mOutputLumiInfo);
225 }
226}
228{
229 if (!digits && !lumi) {
230 throw std::runtime_error("all outputs were disabled");
231 }
232 std::vector<o2::framework::InputSpec> inputs;
233 inputs.emplace_back("TF", o2::framework::ConcreteDataTypeMatcher{"CTP", "RAWDATA"}, o2::framework::Lifetime::Timeframe);
234 if (askDISTSTF) {
235 inputs.emplace_back("stdDist", "FLP", "DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
236 }
237
238 std::vector<o2::framework::OutputSpec> outputs;
239 inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/Config", 1));
240 inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/TriggerOffsets"));
241 if (digits) {
242 outputs.emplace_back("CTP", "DIGITS", 0, o2::framework::Lifetime::Timeframe);
243 }
244 if (lumi) {
245 outputs.emplace_back("CTP", "LUMI", 0, o2::framework::Lifetime::Timeframe);
246 }
248 "ctp-raw-decoder",
249 inputs,
250 outputs,
251 o2::framework::AlgorithmSpec{o2::framework::adaptFromTask<o2::ctp::reco_workflow::RawDecoderSpec>(digits, lumi)},
253 {"ntf-to-average", o2::framework::VariantType::Int, 90, {"Time interval for averaging luminosity in units of TF"}},
254 {"print-errors-num", o2::framework::VariantType::Int, 3, {"Max number of errors to print"}},
255 {"lumi-inp1", o2::framework::VariantType::String, "TVX", {"The first input used for online lumi. Name in capital."}},
256 {"lumi-inp2", o2::framework::VariantType::String, "VBA", {"The second input used for online lumi. Name in capital."}},
257 {"use-verbose-mode", o2::framework::VariantType::Bool, false, {"Verbose logging"}},
258 {"max-input-size", o2::framework::VariantType::Int, 0, {"Do not process input if bigger than max size, 0 - do not check"}},
259 {"max-input-size-fatal", o2::framework::VariantType::Bool, false, {"If true issue fatal error otherwise error only"}},
260 {"check-consistency", o2::framework::VariantType::Bool, false, {"If true checks digits consistency using ctp config"}},
261 {"ctpinputs-decoding", o2::framework::VariantType::Bool, false, {"Inputs alignment: true - raw decoder - has to be compatible with CTF decoder: allowed options: 10,01,00"}}}};
262}
264{
266 pc.inputs().get<o2::ctp::TriggerOffsetsParam*>("trigoffset");
267 const auto& trigOffsParam = o2::ctp::TriggerOffsetsParam::Instance();
268 LOG(info) << "updateing TroggerOffsetsParam: inputs L0_L1:" << trigOffsParam.L0_L1 << " classes L0_L1:" << trigOffsParam.L0_L1_classes;
269 const auto ctpcfg = pc.inputs().get<o2::ctp::CTPConfiguration*>("ctpconfig");
270 if (ctpcfg != nullptr) {
271 mDecoder.setCTPConfig(*ctpcfg);
272 LOG(info) << "ctpconfig for run done:" << mDecoder.getCTPConfig().getRunNumber();
273 }
274 }
275}
definition of CTPConfiguration and related CTP structures
int32_t i
A helper class to iteratate over all parts of all input routes.
std::string getClassNameFromIndex(int index)
std::array< uint64_t, o2::ctp::CTP_NCLASSES > getClassCountersA()
uint32_t getTCRRejected() const
std::array< uint64_t, o2::ctp::CTP_NCLASSES > getClassErrorsA()
std::array< uint64_t, o2::ctp::CTP_NCLASSES > getClassCountersB()
std::vector< uint32_t > & getTFOrbits()
void setCTPConfig(CTPConfiguration cfg)
int setLumiInp(int lumiinp, std::string inp)
void setDoDigits(bool digi)
int decodeRaw(o2::framework::InputRecord &inputs, std::vector< o2::framework::InputSpec > &filter, o2::pmr::vector< CTPDigit > &digits, std::vector< LumiInfo > &lumiPointsHBF1)
std::array< uint64_t, o2::ctp::CTP_NCLASSES > getClassErrorsB()
CTPConfiguration & getCTPConfig()
void setCheckConsistency(bool check)
void setDecodeInps(bool decodeinps)
void setDoLumi(bool lumi)
int decodeRawFatal(o2::framework::InputRecord &inputs, std::vector< o2::framework::InputSpec > &filter)
uint32_t getIRRejected() const
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void updateTimeDependentParams(framework::ProcessingContext &pc)
void init(framework::InitContext &ctx) final
Initializing the RawDecoderSpec.
void run(framework::ProcessingContext &ctx) final
Run conversion of raw data to cells.
A helper class to iteratate over all parts of all input routes.
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
o2::framework::DataProcessorSpec getRawDecoderSpec(bool askSTFDist, bool digits, bool lumi)
Creating DataProcessorSpec for the CTP.
Lifetime
Possible Lifetime of objects being exchanged by the DPL.
Definition Lifetime.h:18
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
void printInputs() const
Definition LumiInfo.cxx:20
uint64_t countsFV0
Definition LumiInfo.h:29
uint64_t counts
Definition LumiInfo.h:28
uint32_t nHBFCounted
Definition LumiInfo.h:26
float getLumiFV0Error() const
Definition LumiInfo.h:36
uint32_t nHBFCountedFV0
Definition LumiInfo.h:27
float getLumiError() const
Definition LumiInfo.h:35
float getLumi() const
Definition LumiInfo.h:32
float getLumiFV0() const
Definition LumiInfo.h:33
uint32_t orbit
Definition LumiInfo.h:25
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
LumiInfo lumi
std::vector< Digit > digits