Project
Loading...
Searching...
No Matches
NoiseCalibratorSpec.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
13
14#include "CCDB/CcdbApi.h"
23
24#include <fairlogger/Logger.h>
29
30using namespace o2::framework;
31using namespace o2::utils;
32
33namespace o2
34{
35namespace mft
36{
37
38NoiseCalibratorSpec::NoiseCalibratorSpec(bool useDigits, std::shared_ptr<o2::base::GRPGeomRequest> req)
39 : mDigits(useDigits), mCCDBRequest(req)
40{
41}
42
44{
46 auto probT = ic.options().get<float>("prob-threshold");
47 auto probTRelErr = ic.options().get<float>("prob-rel-err");
48 LOGP(info, "Setting the probability threshold to {} with relative error {}", probT, probTRelErr);
49 mStopMeOnly = ic.options().get<bool>("stop-me-only");
50 mPath = ic.options().get<std::string>("path-CCDB");
51 mPathMerge = ic.options().get<std::string>("path-CCDB-merge");
52
53 mMeta = ic.options().get<std::string>("meta");
54 mStart = ic.options().get<int64_t>("tstart");
55 mEnd = ic.options().get<int64_t>("tend");
56
57 mCalibrator = std::make_unique<CALIBRATOR>(probT, probTRelErr);
58
59 mPathDcs = ic.options().get<std::string>("path-DCS");
60 mOutputType = ic.options().get<std::string>("send-to-server");
61 mNoiseMapForDcs.clear();
62 api.init("http://alice-ccdb.cern.ch");
63}
64
66{
67 updateTimeDependentParams(pc);
68 if (mDigits) {
69 const auto digits = pc.inputs().get<gsl::span<o2::itsmft::Digit>>("digits");
70 const auto rofs = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("digitsROF");
71 const auto tfcounter = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get("digitsROF").header)->startTime;
72
73 if (mCalibrator->processTimeFrame(tfcounter, digits, rofs)) {
74 LOG(info) << "Minimum number of noise counts has been reached !";
75 if (mOutputType.compare("CCDB") == 0) {
76 LOG(info) << "Sending an object to Production-CCDB";
77 sendOutputCcdb(pc.outputs());
78 LOG(info) << "Sending an object to Production-CCDBMerge";
79 sendOutputCcdbMerge(pc.outputs());
80 } else if (mOutputType.compare("DCS") == 0) {
81 LOG(info) << "Sending an object to DCS-CCDB";
82 sendOutputDcs(pc.outputs());
83 } else {
84 LOG(info) << "Sending an object to Production-CCDB and DCS-CCDB";
85 sendOutputCcdbDcs(pc.outputs());
86 }
87 pc.services().get<ControlService>().readyToQuit(mStopMeOnly ? QuitRequest::Me : QuitRequest::All);
88 }
89 } else {
90 const auto compClusters = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("compClusters");
91 gsl::span<const unsigned char> patterns = pc.inputs().get<gsl::span<unsigned char>>("patterns");
92 const auto rofs = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
93 const auto tfcounter = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get("ROframes").header)->startTime;
94
95 if (mCalibrator->processTimeFrame(tfcounter, compClusters, patterns, rofs)) {
96 LOG(info) << "Minimum number of noise counts has been reached !";
97 if (mOutputType.compare("CCDB") == 0) {
98 LOG(info) << "Sending an object to Production-CCDB";
99 sendOutputCcdb(pc.outputs());
100 LOG(info) << "Sending an object to Production-CCDBMerge";
101 sendOutputCcdbMerge(pc.outputs());
102 } else if (mOutputType.compare("DCS") == 0) {
103 LOG(info) << "Sending an object to DCS-CCDB";
104 sendOutputDcs(pc.outputs());
105 } else {
106 LOG(info) << "Sending an object to Production-CCDB and DCS-CCDB";
107 sendOutputCcdbDcs(pc.outputs());
108 }
109 pc.services().get<ControlService>().readyToQuit(mStopMeOnly ? QuitRequest::Me : QuitRequest::All);
110 }
111 }
112}
113
114void NoiseCalibratorSpec::setOutputDcs(const o2::itsmft::NoiseMap& payload)
115{
116 for (int iChip = 0; iChip < 936; ++iChip) {
117 for (int iRow = 0; iRow < 512; ++iRow) {
118 for (int iCol = 0; iCol < 1024; ++iCol) {
119
120 if (!payload.isNoisy(iChip, iRow, iCol)) {
121 continue;
122 }
123 std::array<int, 3> noise = {iChip, iRow, iCol};
124 mNoiseMapForDcs.emplace_back(noise);
125 }
126 }
127 }
128}
129
130void NoiseCalibratorSpec::sendOutputCcdbDcs(DataAllocator& output)
131{
132
133 LOG(info) << "CCDB-DCS mode";
134
135 static bool done = false;
136 if (done) {
137 return;
138 }
139 done = true;
140
141 mCalibrator->finalize();
142
143 long tstart = mStart;
144 if (tstart == -1) {
146 }
147 long tend = mEnd;
148 if (tend == -1) {
149 constexpr long SECONDSPERYEAR = 365 * 24 * 60 * 60;
150 tend = o2::ccdb::getFutureTimestamp(SECONDSPERYEAR);
151 }
152
153 std::map<std::string, std::string> meta;
154 auto toKeyValPairs = [&meta](std::vector<std::string> const& tokens) {
155 for (auto& token : tokens) {
156 auto keyval = Str::tokenize(token, '=', false);
157 if (keyval.size() != 2) {
158 LOG(error) << "Illegal command-line key/value string: " << token;
159 continue;
160 }
161 Str::trim(keyval[1]);
162 meta[keyval[0]] = keyval[1];
163 }
164 };
165 toKeyValPairs(Str::tokenize(mMeta, ';', true));
166
167 long startTF, endTF;
168
169 const auto& payload = mCalibrator->getNoiseMap();
170 // const auto& payload = mCalibrator->getNoiseMap(starTF, endTF); //For TimeSlot calibration
171
172 o2::ccdb::CcdbObjectInfo info(mPath, "NoiseMap", "noise.root", meta, tstart, tend);
173 auto flName = o2::ccdb::CcdbApi::generateFileName("noise");
174 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
175 info.setFileName(flName);
176 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName()
177 << " of size " << image->size()
178 << " bytes, valid for " << info.getStartValidityTimestamp()
179 << " : " << info.getEndValidityTimestamp();
180
182 output.snapshot(Output{clbUtils::gDataOriginCDBPayload, "MFT_NoiseMap", 0}, *image.get());
183 output.snapshot(Output{clbUtils::gDataOriginCDBWrapper, "MFT_NoiseMap", 0}, info);
184
185 setOutputDcs(payload);
186
187 o2::ccdb::CcdbObjectInfo infoDcs(mPathDcs, "NoiseMap", "noise.root", meta, tstart, tend);
188 auto flNameDcs = o2::ccdb::CcdbApi::generateFileName("noise");
189 auto imageDcs = o2::ccdb::CcdbApi::createObjectImage(&mNoiseMapForDcs, &infoDcs);
190 infoDcs.setFileName(flNameDcs);
191 LOG(info) << "Sending object " << infoDcs.getPath() << "/" << infoDcs.getFileName()
192 << " of size " << imageDcs->size()
193 << " bytes, valid for " << infoDcs.getStartValidityTimestamp()
194 << " : " << infoDcs.getEndValidityTimestamp();
195
196 using clbUtilsDcs = o2::calibration::Utils;
197 output.snapshot(Output{clbUtilsDcs::gDataOriginCDBPayload, "MFT_NoiseMap", 1}, *imageDcs.get());
198 output.snapshot(Output{clbUtilsDcs::gDataOriginCDBWrapper, "MFT_NoiseMap", 1}, infoDcs);
199}
200
201void NoiseCalibratorSpec::sendOutputCcdb(DataAllocator& output)
202{
203
204 LOG(info) << "CCDB mode";
205
206 static bool done = false;
207 if (done) {
208 return;
209 }
210 done = true;
211
212 mCalibrator->finalize();
213
214 long tstart = mStart;
215 if (tstart == -1) {
217 }
218 long tend = mEnd;
219 if (tend == -1) {
220 constexpr long SECONDSPERYEAR = 365 * 24 * 60 * 60;
221 tend = o2::ccdb::getFutureTimestamp(SECONDSPERYEAR);
222 }
223
224 std::map<std::string, std::string> meta;
225 auto toKeyValPairs = [&meta](std::vector<std::string> const& tokens) {
226 for (auto& token : tokens) {
227 auto keyval = Str::tokenize(token, '=', false);
228 if (keyval.size() != 2) {
229 LOG(error) << "Illegal command-line key/value string: " << token;
230 continue;
231 }
232 Str::trim(keyval[1]);
233 meta[keyval[0]] = keyval[1];
234 }
235 };
236 toKeyValPairs(Str::tokenize(mMeta, ';', true));
237
238 long startTF, endTF;
239
240 const auto& payload = mCalibrator->getNoiseMap();
241 // const auto& payload = mCalibrator->getNoiseMap(starTF, endTF); //For TimeSlot calibration
242
243 o2::ccdb::CcdbObjectInfo info(mPath, "NoiseMap", "noise.root", meta, tstart, tend);
244 auto flName = o2::ccdb::CcdbApi::generateFileName("noise");
245 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
246 info.setFileName(flName);
247 LOG(info) << "Sending object CCDB " << info.getPath() << "/" << info.getFileName()
248 << " of size " << image->size()
249 << " bytes, valid for " << info.getStartValidityTimestamp()
250 << " : " << info.getEndValidityTimestamp();
251
253 output.snapshot(Output{clbUtils::gDataOriginCDBPayload, "MFT_NoiseMap", 0}, *image.get());
254 output.snapshot(Output{clbUtils::gDataOriginCDBWrapper, "MFT_NoiseMap", 0}, info);
255}
256
257void NoiseCalibratorSpec::sendOutputCcdbMerge(DataAllocator& output)
258{
259
260 LOG(info) << "CCDB-Merge mode";
261
262 static bool done = false;
263 if (done) {
264 return;
265 }
266 done = true;
267
268 mCalibrator->finalize();
269
270 long tstart = mStart;
271 if (tstart == -1) {
273 }
274 long tend = mEnd;
275 if (tend == -1) {
276 constexpr long SECONDSPERYEAR = 365 * 24 * 60 * 60;
277 tend = o2::ccdb::getFutureTimestamp(SECONDSPERYEAR);
278 }
279
280 std::map<std::string, std::string> meta;
281 auto toKeyValPairs = [&meta](std::vector<std::string> const& tokens) {
282 for (auto& token : tokens) {
283 auto keyval = Str::tokenize(token, '=', false);
284 if (keyval.size() != 2) {
285 LOG(error) << "Illegal command-line key/value string: " << token;
286 continue;
287 }
288 Str::trim(keyval[1]);
289 meta[keyval[0]] = keyval[1];
290 }
291 };
292 toKeyValPairs(Str::tokenize(mMeta, ';', true));
293
294 long startTF, endTF;
295
296 auto payload = mCalibrator->getNoiseMap();
297 // const auto& payload = mCalibrator->getNoiseMap(starTF, endTF); //For TimeSlot calibration
298 map<string, string> headers;
299 map<std::string, std::string> filter;
300 auto* payloadPrev1 = api.retrieveFromTFileAny<o2::itsmft::NoiseMap>(mPath, filter, -1, &headers);
301 long validtime = std::stol(headers["Valid-From"]);
302 auto mergedPL = payload;
303 if (validtime > 0) {
304 validtime = validtime - 1;
305 auto* payloadPrev2 = api.retrieveFromTFileAny<o2::itsmft::NoiseMap>(mPath, filter, validtime, &headers);
306 auto bufferPL = payloadPrev2->merge(payloadPrev1);
307 mergedPL = payload.merge(&bufferPL);
308 }
309 o2::ccdb::CcdbObjectInfo info(mPathMerge, "NoiseMap", "noise.root", meta, tstart, tend);
310 auto flName = o2::ccdb::CcdbApi::generateFileName("noise");
311 auto image = o2::ccdb::CcdbApi::createObjectImage(&mergedPL, &info);
312 info.setFileName(flName);
313 LOG(info) << "Sending object ccdb-merge " << info.getPath() << "/" << info.getFileName()
314 << " of size " << image->size()
315 << " bytes, valid for " << info.getStartValidityTimestamp()
316 << " : " << info.getEndValidityTimestamp();
317
319 output.snapshot(Output{clbUtils::gDataOriginCDBPayload, "MFT_NoiseMap", 0}, *image.get());
320 output.snapshot(Output{clbUtils::gDataOriginCDBWrapper, "MFT_NoiseMap", 0}, info);
321}
322
323void NoiseCalibratorSpec::sendOutputDcs(DataAllocator& output)
324{
325
326 LOG(info) << "DCS mode";
327
328 static bool done = false;
329 if (done) {
330 return;
331 }
332 done = true;
333
334 mCalibrator->finalize();
335
336 long tstart = mStart;
337 if (tstart == -1) {
339 }
340 long tend = mEnd;
341 if (tend == -1) {
342 constexpr long SECONDSPERYEAR = 365 * 24 * 60 * 60;
343 tend = o2::ccdb::getFutureTimestamp(SECONDSPERYEAR);
344 }
345
346 std::map<std::string, std::string> meta;
347 auto toKeyValPairs = [&meta](std::vector<std::string> const& tokens) {
348 for (auto& token : tokens) {
349 auto keyval = Str::tokenize(token, '=', false);
350 if (keyval.size() != 2) {
351 LOG(error) << "Illegal command-line key/value string: " << token;
352 continue;
353 }
354 Str::trim(keyval[1]);
355 meta[keyval[0]] = keyval[1];
356 }
357 };
358 toKeyValPairs(Str::tokenize(mMeta, ';', true));
359
360 long startTF, endTF;
361
362 const auto& payload = mCalibrator->getNoiseMap();
363 // const auto& payload = mCalibrator->getNoiseMap(starTF, endTF); //For TimeSlot calibration
364
365 setOutputDcs(payload);
366
367 o2::ccdb::CcdbObjectInfo infoDcs(mPathDcs, "NoiseMap", "noise.root", meta, tstart, tend);
368 auto flNameDcs = o2::ccdb::CcdbApi::generateFileName("noise");
369 auto imageDcs = o2::ccdb::CcdbApi::createObjectImage(&mNoiseMapForDcs, &infoDcs);
370 infoDcs.setFileName(flNameDcs);
371 LOG(info) << "Sending object " << infoDcs.getPath() << "/" << infoDcs.getFileName()
372 << " of size " << imageDcs->size()
373 << " bytes, valid for " << infoDcs.getStartValidityTimestamp()
374 << " : " << infoDcs.getEndValidityTimestamp();
375
376 using clbUtilsDcs = o2::calibration::Utils;
377 output.snapshot(Output{clbUtilsDcs::gDataOriginCDBPayload, "MFT_NoiseMap", 0}, *imageDcs.get());
378 output.snapshot(Output{clbUtilsDcs::gDataOriginCDBWrapper, "MFT_NoiseMap", 0}, infoDcs);
379}
380
382{
383 if (mOutputType.compare("CCDB") == 0) {
384 LOG(info) << "Sending an object to Production-CCDB";
385 sendOutputCcdb(ec.outputs());
386 LOG(info) << "Sending an object to Production-CCDB-Merge";
387 sendOutputCcdbMerge(ec.outputs());
388 } else if (mOutputType.compare("DCS") == 0) {
389 LOG(info) << "Sending an object to DCS-CCDB";
390 sendOutputDcs(ec.outputs());
391 } else {
392 LOG(info) << "Sending an object to Production-CCDB and DCS-CCDB";
393 sendOutputCcdbDcs(ec.outputs());
394 sendOutputCcdbMerge(ec.outputs());
395 }
396}
397
399void NoiseCalibratorSpec::updateTimeDependentParams(ProcessingContext& pc)
400{
402 if (!mDigits) {
403 pc.inputs().get<o2::itsmft::TopologyDictionary*>("cldict"); // just to trigger the finaliseCCDB
404 }
405}
406
409{
411 if (matcher == ConcreteDataMatcher("MFT", "CLUSDICT", 0)) {
412 LOG(info) << "cluster dictionary updated";
413 mCalibrator->setClusterDictionary((const o2::itsmft::TopologyDictionary*)obj);
414 }
415}
416
418{
420 std::vector<InputSpec> inputs;
421 if (useDigits) {
422 inputs.emplace_back("digits", detOrig, "DIGITS", 0, Lifetime::Timeframe);
423 inputs.emplace_back("digitsROF", detOrig, "DIGITSROF", 0, Lifetime::Timeframe);
424 } else {
425 inputs.emplace_back("compClusters", detOrig, "COMPCLUSTERS", 0, Lifetime::Timeframe);
426 inputs.emplace_back("patterns", detOrig, "PATTERNS", 0, Lifetime::Timeframe);
427 inputs.emplace_back("ROframes", detOrig, "CLUSTERSROF", 0, Lifetime::Timeframe);
428 inputs.emplace_back("cldict", "MFT", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("MFT/Calib/ClusterDictionary"));
429 }
430 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
431 false, // GRPECS=true
432 false, // GRPLHCIF
433 false, // GRPMagField
434 false, // askMatLUT
436 inputs);
438 std::vector<OutputSpec> outputs;
439 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBPayload, "MFT_NoiseMap"}, Lifetime::Sporadic);
440 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBWrapper, "MFT_NoiseMap"}, Lifetime::Sporadic);
441
442 return DataProcessorSpec{
443 "mft-noise-calibrator",
444 inputs,
445 outputs,
446 AlgorithmSpec{adaptFromTask<NoiseCalibratorSpec>(useDigits, ccdbRequest)},
447 Options{
448 {"prob-threshold", VariantType::Float, 1.e-6f, {"Probability threshold for noisy pixels"}},
449 {"prob-rel-err", VariantType::Float, 0.2f, {"Relative error on channel noise to apply the threshold"}},
450 {"tstart", VariantType::Int64, -1ll, {"Start of validity timestamp"}},
451 {"tend", VariantType::Int64, -1ll, {"End of validity timestamp"}},
452 {"path-CCDB", VariantType::String, "/MFT/Calib/NoiseMap", {"Path to write to in CCDB"}},
453 {"path-CCDB-merge", VariantType::String, "/MFT/Calib/NoiseMapMerged", {"Path to write merged file to in CCDB"}},
454 {"path-DCS", VariantType::String, "/MFT/Config/NoiseMap", {"Path to write to in DCS"}},
455 {"meta", VariantType::String, "", {"meta data to write in CCDB"}},
456 {"send-to-server", VariantType::String, "CCDB-DCS", {"meta data to write in DCS-CCDB"}},
457 {"stop-me-only", VariantType::Bool, false, {"At sufficient statistics stop only this device, otherwise whole workflow"}}}};
458}
459
460} // namespace mft
461} // namespace o2
Definition of the ITS/MFT clusterer settings.
Definition of the ITSMFT compact cluster.
Definition of the ITSMFT digit.
Definition of the Names Generator class.
Utils and constants for calibration and related workflows.
bool done
Definition of the ITSMFT ROFrame (trigger) record.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
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::string generateFileName(const std::string &inp)
Definition CcdbApi.cxx:798
void init(std::string const &hosts)
Definition CcdbApi.cxx:165
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
std::enable_if<!std::is_base_of< o2::conf::ConfigurableParam, T >::value, T * >::type retrieveFromTFileAny(std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp=-1, std::map< std::string, std::string > *headers=nullptr, std::string const &etag="", const std::string &createdNotAfter="", const std::string &createdNotBefore="") const
Definition CcdbApi.h:660
ConfigParamRegistry const & options()
Definition InitContext.h:33
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.
NoiseMap class for the ITS and MFT.
Definition NoiseMap.h:39
NoiseMap merge(const NoiseMap *prev)
Definition NoiseMap.h:205
bool isNoisy(int chip, int row, int col) const
Definition NoiseMap.h:151
NoiseCalibratorSpec(bool digits=false, std::shared_ptr< o2::base::GRPGeomRequest > req={})
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
GLeglImageOES image
Definition glcorearb.h:4021
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
constexpr o2::header::DataOrigin gDataOriginMFT
Definition DataHeader.h:572
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
long getFutureTimestamp(int secondsInFuture)
returns the timestamp in long corresponding to "now + secondsInFuture"
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< ConfigParamSpec > Options
DataProcessorSpec getNoiseCalibratorSpec(bool useDigits)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
static void trim(std::string &s)
Definition StringUtils.h:71
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits