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& TFOrbits = mDecoder.getTFOrbits();
54 std::sort(TFOrbits.begin(), TFOrbits.end());
55 size_t l = TFOrbits.size();
56 uint32_t o0 = 0;
57 if (l) {
58 o0 = TFOrbits[0];
59 }
60 int nmiss = 0;
61 int nprt = 0;
62 std::cout << "Missing orbits:";
63 for (int i = 1; i < l; i++) {
64 if ((TFOrbits[i] - o0) > 0x20) {
65 if (nprt < 20) {
66 std::cout << " " << o0 << "-" << TFOrbits[i];
67 }
68 nmiss += (TFOrbits[i] - o0) / 0x20;
69 nprt++;
70 }
71 o0 = TFOrbits[i];
72 }
73 std::cout << std::endl;
74 LOG(info) << "Number of non continous TF:" << nmiss << std::endl;
75 LOG(info) << "Lost in shiftInputs:" << mLostDueToShiftInps;
76 LOG(info) << "Lost in addDigit Inputs:" << mIRRejected << " Classes:" << mTCRRejected;
77 if (mErrorIR || mErrorTCR) {
78 LOG(error) << "# of IR errors:" << mErrorIR << " TCR errors:" << mErrorTCR << std::endl;
79 }
80 if (mCheckConsistency) {
81 LOG(info) << "Lost due to the shift Consistency Checker:" << mDecoder.getLostDueToShiftCls();
82 auto ctpcfg = mDecoder.getCTPConfig();
83 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
84 std::string name = ctpcfg.getClassNameFromIndex(i);
85 if (mClsEA[i]) {
86 LOG(error) << " Class without inputs:";
87 }
88 LOG(important) << "CLASS:" << name << ":" << i << " Cls=>Inp:" << mClsA[i] << " Inp=>Cls:" << mClsB[i] << " ErrorsCls=>Inps:" << mClsEA[i] << " MissingInps=>Cls:" << mClsEB[i];
89 }
90 }
91}
93{
95 mOutputDigits.clear();
96 std::map<o2::InteractionRecord, CTPDigit> digits;
100 // setUpDummyLink
101 auto& inputs = ctx.inputs();
102 auto dummyOutput = [&ctx, this]() {
103 if (this->mDoDigits) {
104 ctx.outputs().snapshot(o2::framework::Output{"CTP", "DIGITS", 0}, this->mOutputDigits);
105 }
106 if (this->mDoLumi) {
107 ctx.outputs().snapshot(o2::framework::Output{"CTP", "LUMI", 0}, this->mOutputLumiInfo);
108 }
109 };
110 // if we see requested data type input with 0xDEADBEEF subspec and 0 payload this means that the "delayed message"
111 // mechanism created it in absence of real data from upstream. Processor should send empty output to not block the workflow
112 {
113 static size_t contDeadBeef = 0; // number of times 0xDEADBEEF was seen continuously
114 std::vector<InputSpec> dummy{InputSpec{"dummy", o2::framework::ConcreteDataMatcher{"CTP", "RAWDATA", 0xDEADBEEF}}};
115 for (const auto& ref : o2::framework::InputRecordWalker(inputs, dummy)) {
116 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
118 if (payloadSize == 0) {
120 if (++contDeadBeef <= maxWarn) {
121 LOGP(alarm, "Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
122 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
123 contDeadBeef == maxWarn ? fmt::format(". {} such inputs in row received, stopping reporting", contDeadBeef) : "");
124 }
125 dummyOutput();
126 return;
127 }
128 }
129 contDeadBeef = 0; // if good data, reset the counter
130 }
131 //
132 std::vector<LumiInfo> lumiPointsHBF1;
133 std::vector<InputSpec> filter{InputSpec{"filter", ConcreteDataTypeMatcher{"CTP", "RAWDATA"}, Lifetime::Timeframe}};
134 bool fatal_flag = 0;
135 if (mMaxInputSize > 0) {
136 size_t payloadSize = 0;
137 for (const auto& ref : o2::framework::InputRecordWalker(inputs, filter)) {
138 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
140 }
141 if (payloadSize > (size_t)mMaxInputSize) {
142 if (mMaxInputSizeFatal) {
143 fatal_flag = 1;
144 LOG(error) << "Input data size bigger than threshold: " << mMaxInputSize << " < " << payloadSize << " decoding TF and exiting.";
145 // LOG(fatal) << "Input data size:" << payloadSize; - fatal issued in decoder
146 } else {
147 LOG(error) << "Input data size:" << payloadSize << " sending dummy output";
148 dummyOutput();
149 return;
150 }
151 }
152 }
153 int ret = 0;
154 if (fatal_flag) {
155 ret = mDecoder.decodeRawFatal(inputs, filter);
156 } else {
157 ret = mDecoder.decodeRaw(inputs, filter, mOutputDigits, lumiPointsHBF1);
158 }
159 if (ret == 1) {
160 dummyOutput();
161 return;
162 }
163 if (mDoDigits) {
164 LOG(info) << "[CTPRawToDigitConverter - run] Writing " << mOutputDigits.size() << " digits. IR rejected:" << mDecoder.getIRRejected() << " TCR rejected:" << mDecoder.getTCRRejected();
165 ctx.outputs().snapshot(o2::framework::Output{"CTP", "DIGITS", 0}, mOutputDigits);
166 mLostDueToShiftInps += mDecoder.getLostDueToShiftInp();
167 mErrorIR += mDecoder.getErrorIR();
168 mErrorTCR += mDecoder.getErrorTCR();
169 mIRRejected += mDecoder.getIRRejected();
170 mTCRRejected += mDecoder.getTCRRejected();
171 auto clsEA = mDecoder.getClassErrorsA();
172 auto clsEB = mDecoder.getClassErrorsB();
173 auto cntCA = mDecoder.getClassCountersA();
174 auto cntCB = mDecoder.getClassCountersB();
175 for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) {
176 mClsEA[i] += clsEA[i];
177 mClsEB[i] += clsEB[i];
178 mClsA[i] += cntCA[i];
179 mClsB[i] += cntCB[i];
180 }
181 }
182 if (mDoLumi) {
183 uint32_t tfCountsT = 0;
184 uint32_t tfCountsV = 0;
185 for (auto const& lp : lumiPointsHBF1) {
186 tfCountsT += lp.counts;
187 tfCountsV += lp.countsFV0;
188 }
189 // LOG(info) << "Lumi rate:" << tfCounts/(128.*88e-6);
190 // FT0
191 mHistoryT.push_back(tfCountsT);
192 mCountsT += tfCountsT;
193 if (mHistoryT.size() <= mNTFToIntegrate) {
194 mNHBIntegratedT += lumiPointsHBF1.size();
195 } else {
196 mCountsT -= mHistoryT.front();
197 mHistoryT.pop_front();
198 }
199 // FV0
200 mHistoryV.push_back(tfCountsV);
201 mCountsV += tfCountsV;
202 if (mHistoryV.size() <= mNTFToIntegrate) {
203 mNHBIntegratedV += lumiPointsHBF1.size();
204 } else {
205 mCountsV -= mHistoryV.front();
206 mHistoryV.pop_front();
207 }
208 //
209 if (mNHBIntegratedT || mNHBIntegratedV) {
210 mOutputLumiInfo.orbit = lumiPointsHBF1[0].orbit;
211 }
212 mOutputLumiInfo.counts = mCountsT;
213
214 mOutputLumiInfo.countsFV0 = mCountsV;
215 mOutputLumiInfo.nHBFCounted = mNHBIntegratedT;
216 mOutputLumiInfo.nHBFCountedFV0 = mNHBIntegratedV;
217 if (mVerbose) {
218 mOutputLumiInfo.printInputs();
219 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());
220 }
221 ctx.outputs().snapshot(o2::framework::Output{"CTP", "LUMI", 0}, mOutputLumiInfo);
222 }
223}
225{
226 if (!digits && !lumi) {
227 throw std::runtime_error("all outputs were disabled");
228 }
229 std::vector<o2::framework::InputSpec> inputs;
230 inputs.emplace_back("TF", o2::framework::ConcreteDataTypeMatcher{"CTP", "RAWDATA"}, o2::framework::Lifetime::Timeframe);
231 if (askDISTSTF) {
232 inputs.emplace_back("stdDist", "FLP", "DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
233 }
234
235 std::vector<o2::framework::OutputSpec> outputs;
236 inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/Config", 1));
237 inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/TriggerOffsets"));
238 if (digits) {
239 outputs.emplace_back("CTP", "DIGITS", 0, o2::framework::Lifetime::Timeframe);
240 }
241 if (lumi) {
242 outputs.emplace_back("CTP", "LUMI", 0, o2::framework::Lifetime::Timeframe);
243 }
245 "ctp-raw-decoder",
246 inputs,
247 outputs,
248 o2::framework::AlgorithmSpec{o2::framework::adaptFromTask<o2::ctp::reco_workflow::RawDecoderSpec>(digits, lumi)},
250 {"ntf-to-average", o2::framework::VariantType::Int, 90, {"Time interval for averaging luminosity in units of TF"}},
251 {"print-errors-num", o2::framework::VariantType::Int, 3, {"Max number of errors to print"}},
252 {"lumi-inp1", o2::framework::VariantType::String, "TVX", {"The first input used for online lumi. Name in capital."}},
253 {"lumi-inp2", o2::framework::VariantType::String, "VBA", {"The second input used for online lumi. Name in capital."}},
254 {"use-verbose-mode", o2::framework::VariantType::Bool, false, {"Verbose logging"}},
255 {"max-input-size", o2::framework::VariantType::Int, 0, {"Do not process input if bigger than max size, 0 - do not check"}},
256 {"max-input-size-fatal", o2::framework::VariantType::Bool, false, {"If true issue fatal error otherwise error only"}},
257 {"check-consistency", o2::framework::VariantType::Bool, false, {"If true checks digits consistency using ctp config"}},
258 {"ctpinputs-decoding", o2::framework::VariantType::Bool, false, {"Inputs alignment: true - raw decoder - has to be compatible with CTF decoder: allowed options: 10,01,00"}}}};
259}
261{
263 pc.inputs().get<o2::ctp::TriggerOffsetsParam*>("trigoffset");
264 const auto& trigOffsParam = o2::ctp::TriggerOffsetsParam::Instance();
265 LOG(info) << "updateing TroggerOffsetsParam: inputs L0_L1:" << trigOffsParam.L0_L1 << " classes L0_L1:" << trigOffsParam.L0_L1_classes;
266 const auto ctpcfg = pc.inputs().get<o2::ctp::CTPConfiguration*>("ctpconfig");
267 if (ctpcfg != nullptr) {
268 mDecoder.setCTPConfig(*ctpcfg);
269 LOG(info) << "ctpconfig for run done:" << mDecoder.getCTPConfig().getRunNumber();
270 }
271 }
272}
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.
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
Definition InitContext.h:33
A helper class to iteratate over all parts of all input routes.
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
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