102 updateTimeDependentParams(ctx);
104 auto now = std::chrono::system_clock::now();
105 if (mIsMuteDecoderErrors) {
106 if (((now - mTimeWhenMuted) / std::chrono::minutes(1)) >= 10) {
107 mIsMuteDecoderErrors =
false;
108 if (mDecoderErrorsCounterWhenMuted) {
109 LOG(error) <<
"RawToDigitConverterSpec::run() : " << mDecoderErrorsCounterWhenMuted <<
" errors happened while it was muted ((";
111 mDecoderErrorsCounterWhenMuted = 0;
114 if (((now - mStartTime) / std::chrono::minutes(1)) > mMinutesPassed) {
115 mMinutesPassed = (now - mStartTime) / std::chrono::minutes(1);
116 LOG(
debug) <<
"minutes passed: " << mMinutesPassed;
117 mDecoderErrorsPerMinute = 0;
121 std::map<o2::InteractionRecord, std::shared_ptr<std::vector<o2::cpv::Digit>>> digitBuffer;
122 mOutputHWErrors.clear();
126 static size_t contDeadBeef = 0;
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) :
"");
138 mOutputDigits.clear();
140 mOutputTriggerRecords.clear();
142 mOutputHWErrors.clear();
151 std::vector<o2::framework::InputSpec> rawFilter{
161 if (!mIsMuteDecoderErrors) {
162 LOG(error) <<
"Raw decoding error " << (
int)e;
167 mOutputHWErrors.emplace_back(-1, 0, 0, 0, e);
170 LOG(error) <<
"RDH decoding error. Skipping this TF";
183 auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(rdh);
184 auto mod = o2::raw::RDHUtils::getLinkID(rdh) + 2;
187 if (!mIsMuteDecoderErrors) {
188 LOG(error) <<
"RDH linkId corresponds to module " << mod <<
" which does not exist";
190 mOutputHWErrors.emplace_back(-1, mod, 0, 0,
kRDH_INVALID);
194 if (mIsMuteDecoderErrors) {
198 int decoderErrors = 0;
200 if (errs.ccId == -1) {
204 mDecoderErrorsPerMinute += decoderErrors;
207 if (mIsMuteDecoderErrors) {
208 mDecoderErrorsCounterWhenMuted += decoder.
getErrors().size();
210 if (mDecoderErrorsPerMinute > 10) {
211 LOG(warning) <<
"> 10 raw decoder error messages per minute, muting it for 10 minutes";
212 mIsMuteDecoderErrors =
true;
213 mTimeWhenMuted = std::chrono::system_clock::now();
220 mOutputHWErrors.emplace_back(-1, mod, 0, 0, err);
223 std::shared_ptr<std::vector<o2::cpv::Digit>> currentDigitContainer;
225 if (digilets.empty()) {
231 currentIR.
bc = itBCRecords.bc;
232 for (
unsigned int iDig = itBCRecords.firstDigit; iDig <= itBCRecords.lastDigit; iDig++) {
233 auto adch = digilets[iDig];
234 auto found = digitBuffer.find(currentIR);
235 if (found == digitBuffer.end()) {
236 currentDigitContainer = std::make_shared<std::vector<o2::cpv::Digit>>();
237 digitBuffer[currentIR] = currentDigitContainer;
239 currentDigitContainer = found->second;
243 unsigned short absId = ac.
Address;
245 if (!mIsPedestalData) {
247 if (mIsUsingBadMap) {
253 if (mIsUsingGainCalibration) {
259 currentDigitContainer->emplace_back(absId, amp, -1);
262 currentDigitContainer->emplace_back(absId, (
float)ac.
Charge, -1);
268 mOutputHWErrors.push_back(er);
274 mOutputDigits.clear();
276 mOutputTriggerRecords.clear();
285 mOutputDigits.clear();
286 mOutputTriggerRecords.clear();
289 for (
auto [
bc,
digits] : digitBuffer) {
290 if (
bc.differenceInBC({0, tfOrbitFirst}) < ctpOffsets.LM_L0) {
293 int prevDigitSize = mOutputDigits.size();
298 for (
auto digit : *
digits) {
299 mOutputDigits.push_back(digit);
303 mOutputTriggerRecords.emplace_back(
bc - ctpOffsets.LM_L0, prevDigitSize, mOutputDigits.size() - prevDigitSize);
307 LOG(info) <<
"[CPVRawToDigitConverter - run] Sending " << mOutputDigits.size() <<
" digits in " << mOutputTriggerRecords.size() <<
"trigger records.";
315 std::vector<o2::framework::InputSpec> inputs;
319 inputs.emplace_back(
"STFDist",
"FLP",
"DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
322 inputs.emplace_back(
"peds",
"CPV",
"CPV_Pedestals", 0, o2::framework::Lifetime::Condition,
o2::framework::ccdbParamSpec(
"CPV/Calib/Pedestals"));
323 if (useBadChannelMap) {
324 inputs.emplace_back(
"badmap",
"CPV",
"CPV_BadMap", 0, o2::framework::Lifetime::Condition,
o2::framework::ccdbParamSpec(
"CPV/Calib/BadChannelMap"));
326 if (useGainCalibration) {
327 inputs.emplace_back(
"gains",
"CPV",
"CPV_Gains", 0, o2::framework::Lifetime::Condition,
o2::framework::ccdbParamSpec(
"CPV/Calib/Gains"));
331 inputs.emplace_back(
"trigoffset",
"CTP",
"Trig_Offset", 0, o2::framework::Lifetime::Condition,
o2::framework::ccdbParamSpec(
"CTP/Config/TriggerOffsets"));
333 std::vector<o2::framework::OutputSpec> outputs;
334 outputs.emplace_back(
"CPV",
"DIGITS", 0, o2::framework::Lifetime::Timeframe);
335 outputs.emplace_back(
"CPV",
"DIGITTRIGREC", 0, o2::framework::Lifetime::Timeframe);
336 outputs.emplace_back(
"CPV",
"RAWHWERRORS", 0, o2::framework::Lifetime::Timeframe);
342 o2::framework::adaptFromTask<o2::cpv::reco_workflow::RawToDigitConverterSpec>(isPedestal, useBadChannelMap, useGainCalibration),
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.