Project
Loading...
Searching...
No Matches
ChannelCalibratorSpec.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
16
18
19#include <array>
20#include <vector>
21#include <gsl/gsl>
23#include "Framework/InputSpec.h"
24#include "Framework/Logger.h"
25#include "Framework/Task.h"
28#include "CCDB/CcdbObjectInfo.h"
39
40#include "TObjString.h"
41
42namespace of = o2::framework;
43
44namespace o2
45{
46namespace mid
47{
48
50{
51 public:
52 ChannelCalibratorDeviceDPL(const FEEIdConfig& feeIdConfig, const CrateMasks& crateMasks, std::shared_ptr<o2::base::GRPGeomRequest> req) : mCCDBRequest(req)
53 {
54 mRefMasks = makeDefaultMasksFromCrateConfig(feeIdConfig, crateMasks);
55 }
56
58 {
60 mCalibrators[0].setThreshold(ChannelCalibratorParam::Instance().maxNoise);
61 mCalibrators[1].setThreshold(ChannelCalibratorParam::Instance().maxDead);
62
63 for (auto& calib : mCalibrators) {
64 calib.setSlotLength(calibration::INFINITE_TF);
65 calib.setUpdateAtTheEndOfRunOnly();
66 }
67 }
68
70 {
71 if (matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "FAKE_DEAD", 0)) {
72 LOG(info) << "Update fake dead channels";
73 auto* fakeDead = static_cast<std::vector<ColumnData>*>(obj);
74 if (fakeDead) {
75 mFakeDead = *fakeDead;
76 }
77 return;
78 }
79
81 return;
82 }
83 }
84
86 {
87 if (mHasAlreadySent) {
88 return;
89 }
90
91 updateTimeDependentParams(pc);
92
93 std::array<gsl::span<const ColumnData>, 2> calibData{pc.inputs().get<gsl::span<ColumnData>>("mid_noise"), pc.inputs().get<gsl::span<ColumnData>>("mid_dead")};
94 auto deadRof = pc.inputs().get<gsl::span<ROFRecord>>("mid_dead_rof");
95 std::array<double, 2> timeOrTriggers{o2::base::GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF() * o2::constants::lhc::LHCOrbitNS * 1e-9, static_cast<double>(deadRof.size())};
96 mNCalibTriggers += deadRof.size();
97
98 for (size_t idx = 0; idx < calibData.size(); ++idx) {
99 o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCalibrators[idx].getCurrentTFInfo());
100 mCalibrators[idx].addTimeOrTriggers(timeOrTriggers[idx]);
101 mCalibrators[idx].process(calibData[idx]);
102 }
103 if (!ChannelCalibratorParam::Instance().onlyAtEndOfStream) {
104 if (mNCalibTriggers > ChannelCalibratorParam::Instance().nCalibTriggers) {
105 // Periodically send the list of bad channels.
106 // This prevents issues with sending at EOR since it is extremely sensitive to DPL optimization
107 LOG(info) << "Ready to send data";
108 finalise(pc.outputs());
109 mHasAlreadySent = true;
110 }
111 } else {
112 if (pc.transitionState() == of::TransitionHandlingState::Requested) {
113 LOG(info) << "Run stop requested, finalizing";
114 finalise(pc.outputs());
115 mHasAlreadySent = true;
116 }
117 }
118 }
119
121 {
122 if (mHasAlreadySent) {
123 return;
124 }
125 LOG(info) << "EOS sent, finalizing";
126 finalise(ec.outputs());
127 }
128
129 private:
130 std::array<ChannelCalibrator, 2> mCalibrators{};
131 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
132 std::vector<ColumnData> mRefMasks{};
133 std::vector<ColumnData> mFakeDead{};
134 bool mHasAlreadySent = false;
135 unsigned long int mNCalibTriggers = 0;
136
137 void updateTimeDependentParams(o2::framework::ProcessingContext& pc)
138 {
139 // Triggers finalizeCCDB
141 static bool initOnceDone = false;
142 if (!initOnceDone) {
143 initOnceDone = true;
144 pc.inputs().get<std::vector<ColumnData>*>("mid_fake_dead");
145 }
146 }
147
148 void finalise(of::DataAllocator& output)
149 {
150 for (auto& calib : mCalibrators) {
151 calib.checkSlotsToFinalize(ChannelCalibrator::INFINITE_TF);
152 }
153 sendOutput(output);
154 }
155
156 std::vector<ColumnData> removeFakeDead(std::vector<ColumnData> dead)
157 {
158 ChannelMasksHandler fakeDeadHandler;
159 for (auto& col : mFakeDead) {
160 fakeDeadHandler.switchOffChannels(col);
161 }
162 std::vector<ColumnData> realDead;
163 for (auto& col : dead) {
164 fakeDeadHandler.applyMask(col);
165 if (!col.isEmpty()) {
166 realDead.emplace_back(col);
167 }
168 }
169 return realDead;
170 }
171
172 void sendOutput(of::DataAllocator& output)
173 {
174 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
175
176 auto dead = removeFakeDead(mCalibrators[1].getBadChannels());
177
178 output.snapshot(of::Output{header::gDataOriginMID, "NOISY_CHANNELS", 0}, mCalibrators[0].getBadChannels());
179 output.snapshot(of::Output{header::gDataOriginMID, "DEAD_CHANNELS", 0}, dead);
180
181 ChannelCalibratorFinalizer finalizer;
182 finalizer.setReferenceMasks(mRefMasks);
183 finalizer.process(mCalibrators[0].getBadChannels(), dead);
184 sendOutput(output, finalizer.getBadChannels(), mCalibrators[1].getCurrentTFInfo(), "MID/Calib/BadChannels", 0);
185
186 TObjString masks(finalizer.getMasksAsString().c_str());
187 sendOutput(output, masks, mCalibrators[1].getCurrentTFInfo(), "MID/Calib/ElectronicsMasks", 1);
188
189 output.snapshot(of::Output{header::gDataOriginMID, "BAD_CHANNELS", 0}, finalizer.getBadChannels());
190
191 for (auto& calib : mCalibrators) {
192 calib.initOutput(); // reset the outputs once they are already sent
193 }
194 }
195
196 template <typename T>
197 void sendOutput(of::DataAllocator& output, const T& payload, const o2::dataformats::TFIDInfo& tfInfo, const char* path, header::DataHeader::SubSpecificationType subSpec)
198 {
200 std::map<std::string, std::string> md;
202 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
203 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
204 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
205 output.snapshot(of::Output{o2::calibration::Utils::gDataOriginCDBPayload, "MID_BAD_CHANNELS", subSpec}, *image.get()); // vector<char>
206 output.snapshot(of::Output{o2::calibration::Utils::gDataOriginCDBWrapper, "MID_BAD_CHANNELS", subSpec}, info); // root-serialized
207 }
208};
209
211{
212 std::vector<of::InputSpec> inputSpecs;
213 inputSpecs.emplace_back("mid_noise", header::gDataOriginMID, "NOISE");
214 inputSpecs.emplace_back("mid_noise_rof", header::gDataOriginMID, "NOISEROF");
215 inputSpecs.emplace_back("mid_dead", header::gDataOriginMID, "DEAD");
216 inputSpecs.emplace_back("mid_dead_rof", header::gDataOriginMID, "DEADROF");
217 inputSpecs.emplace_back("mid_fake_dead", header::gDataOriginMID, "FAKE_DEAD", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/FakeDeadChannels"));
218 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime
219 true, // GRPECS=true
220 false, // GRPLHCIF
221 false, // GRPMagField
222 false, // askMatLUT
224 inputSpecs);
225 std::vector<of::OutputSpec> outputSpecs;
226 outputSpecs.emplace_back(o2::calibration::Utils::gDataOriginCDBPayload, "MID_BAD_CHANNELS", 0, of::Lifetime::Sporadic);
227 outputSpecs.emplace_back(o2::calibration::Utils::gDataOriginCDBWrapper, "MID_BAD_CHANNELS", 0, of::Lifetime::Sporadic);
228 outputSpecs.emplace_back(o2::calibration::Utils::gDataOriginCDBPayload, "MID_BAD_CHANNELS", 1, of::Lifetime::Sporadic);
229 outputSpecs.emplace_back(o2::calibration::Utils::gDataOriginCDBWrapper, "MID_BAD_CHANNELS", 1, of::Lifetime::Sporadic);
230 outputSpecs.emplace_back(header::gDataOriginMID, "NOISY_CHANNELS", 0, of::Lifetime::Sporadic);
231 outputSpecs.emplace_back(header::gDataOriginMID, "DEAD_CHANNELS", 0, of::Lifetime::Sporadic);
232 outputSpecs.emplace_back(header::gDataOriginMID, "BAD_CHANNELS", 0, of::Lifetime::Sporadic);
233
235 "MIDChannelCalibrator",
236 {inputSpecs},
237 {outputSpecs},
238 of::AlgorithmSpec{of::adaptFromTask<o2::mid::ChannelCalibratorDeviceDPL>(feeIdConfig, crateMasks, ccdbRequest)}};
239}
240} // namespace mid
241} // namespace o2
MID noise and dead channels calibrator finalizer.
Noise and dead channels calibrator spec for MID.
MID noise and dead channels calibrator.
MID channels masks handler.
Converter from ColumnData to raw local boards.
Strip pattern (aka digits)
Utils and constants for calibration and related workflows.
Helper for geometry and GRP related CCDB requests.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of the MID event record.
Function to produce the MID masks.
uint32_t col
Definition RawData.h:4
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
long getEndValidityTimestamp() const
const std::string & getPath() const
static constexpr long DAY
long getStartValidityTimestamp() const
const std::string & getFileName() const
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.
TransitionHandlingState transitionState() const
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
void run(of::ProcessingContext &pc)
void endOfStream(of::EndOfStreamContext &ec)
ChannelCalibratorDeviceDPL(const FEEIdConfig &feeIdConfig, const CrateMasks &crateMasks, std::shared_ptr< o2::base::GRPGeomRequest > req)
GLeglImageOES image
Definition glcorearb.h:4021
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
constexpr o2::header::DataOrigin gDataOriginMID
Definition DataHeader.h:573
constexpr TFType INFINITE_TF
Definition TimeSlot.h:30
constexpr double LHCOrbitNS
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ColumnData > makeDefaultMasksFromCrateConfig(const FEEIdConfig &feeIdConfig=FEEIdConfig(), const CrateMasks &crateMasks=CrateMasks())
framework::DataProcessorSpec getChannelCalibratorSpec(const FEEIdConfig &feeIdConfig, const CrateMasks &crateMasks)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static void fillTFIDInfo(o2::framework::ProcessingContext &pc, o2::dataformats::TFIDInfo &ti)
static void prepareCCDBobjectInfo(T &obj, o2::ccdb::CcdbObjectInfo &info, const std::string &path, const std::map< std::string, std::string > &md, long start, long end=-1)
Definition Utils.h:91
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
uint32_t SubSpecificationType
Definition DataHeader.h:620
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"