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"
22
23#include "Framework/Logger.h"
29
30using namespace o2::framework;
31
32namespace o2
33{
34namespace its
35{
36
38{
40 auto onepix = ic.options().get<bool>("1pix-only");
41 LOG(info) << "Fast 1=pixel calibration: " << onepix;
42 auto probT = ic.options().get<float>("prob-threshold");
43 auto probTRelErr = ic.options().get<float>("prob-rel-err");
44 mNoiseCutIB = ic.options().get<float>("cut-ib");
45 LOGP(info, "Setting the probability threshold to {} with relative error {}", probT, probTRelErr);
46 mStopMeOnly = ic.options().get<bool>("stop-me-only");
47 mCalibrator = std::make_unique<CALIBRATOR>(onepix, probT, probTRelErr);
48 mCalibrator->setNThreads(ic.options().get<int>("nthreads"));
49 mValidityDays = ic.options().get<int>("validity-days");
50 if (mValidityDays < 1) {
51 mValidityDays = 1;
52 }
53}
54
56{
57 const auto& tinfo = pc.services().get<o2::framework::TimingInfo>();
58 static bool firstCall = true;
59 if (tinfo.globalRunNumberChanged) { // new run is starting
60 mRunStopRequested = false;
61 mInitOnceDone = false;
62 mStrobeCounter = 0;
63 mDataSizeStat = 0;
64 mNClustersProc = 0;
65 if (firstCall) {
66 mCalibrator->reset();
67 }
68 }
69 if (mRunStopRequested) {
70 return;
71 }
72 updateTimeDependentParams(pc);
73 mTimer.Start(false);
74 bool done = false;
75 if (firstCall) {
76 firstCall = false;
77 mCalibrator->setInstanceID((int)pc.services().get<const o2::framework::DeviceSpec>().inputTimesliceId);
78 mCalibrator->setNInstances((int)pc.services().get<const o2::framework::DeviceSpec>().maxInputTimeslices);
79 if (mMode == ProcessingMode::Accumulate) {
80 mCalibrator->setMinROFs(mCalibrator->getMinROFs() / mCalibrator->getNInstances());
81 }
82 }
83
84 if (mMode == ProcessingMode::Full || mMode == ProcessingMode::Accumulate) {
85 if (mUseClusters) {
86 const auto compClusters = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("compClusters");
87 gsl::span<const unsigned char> patterns = pc.inputs().get<gsl::span<unsigned char>>("patterns");
88 const auto rofs = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
89 mNClustersProc += compClusters.size();
90 mDataSizeStat +=
91 rofs.size() * sizeof(o2::itsmft::ROFRecord) + patterns.size() +
92 compClusters.size() * sizeof(o2::itsmft::CompClusterExt);
93 done = mCalibrator->processTimeFrameClusters(compClusters, patterns, rofs);
94 } else {
95 const auto digits = pc.inputs().get<gsl::span<o2::itsmft::Digit>>("digits");
96 const auto rofs = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
97 mNClustersProc += digits.size();
98 mDataSizeStat += digits.size() * sizeof(o2::itsmft::Digit) + rofs.size() * sizeof(o2::itsmft::ROFRecord);
99 done = mCalibrator->processTimeFrameDigits(digits, rofs);
100 }
101 } else {
102 const auto extMap = pc.inputs().get<o2::itsmft::NoiseMap*>("mapspart");
103 gsl::span<const int> partInfo = pc.inputs().get<gsl::span<int>>("mapspartInfo");
104 mCalibrator->addMap(*extMap.get());
105 done = (++mNPartsDone == partInfo[1]);
106 mStrobeCounter += partInfo[2];
107 mCalibrator->setNStrobes(mStrobeCounter);
108 LOGP(important, "Received accumulated map {} of {} with {} ROFs, total number of maps = {} and strobes = {}", partInfo[0] + 1, partInfo[1], partInfo[2], mNPartsDone, mCalibrator->getNStrobes());
109 }
110 if (done || pc.transitionState() == TransitionHandlingState::Requested) {
111 if (done) {
112 LOG(important) << "Minimum number of noise counts has been reached !";
113 } else {
114 LOG(important) << "Run stop is requested, sending output";
115 }
116 if (mMode == ProcessingMode::Full || mMode == ProcessingMode::Normalize) {
117 sendOutput(pc.outputs());
118 // pc.services().get<ControlService>().readyToQuit(mStopMeOnly ? QuitRequest::Me : QuitRequest::All);
119 } else {
120 sendAccumulatedMap(pc.outputs());
121 // pc.services().get<o2::framework::ControlService>().endOfStream();
122 }
123 mRunStopRequested = true;
124 }
125
126 mTimer.Stop();
127}
128
129void NoiseCalibratorSpec::sendAccumulatedMap(DataAllocator& output)
130{
131 output.snapshot(Output{"ITS", "NOISEMAPPART", (unsigned int)mCalibrator->getInstanceID()}, mCalibrator->getNoiseMap());
132 std::vector<int> outInf;
133 outInf.push_back(mCalibrator->getInstanceID());
134 outInf.push_back(mCalibrator->getNInstances());
135 outInf.push_back(mCalibrator->getNStrobes());
136 output.snapshot(Output{"ITS", "NOISEMAPPARTINF", (unsigned int)mCalibrator->getInstanceID()}, outInf);
137 LOGP(important, "Sending accumulated map with {} ROFs processed", mCalibrator->getNStrobes());
138}
139
140void NoiseCalibratorSpec::sendOutput(DataAllocator& output)
141{
142 mCalibrator->finalize(mNoiseCutIB);
143
144 long tstart = o2::ccdb::getCurrentTimestamp();
145 long tend = o2::ccdb::getFutureTimestamp(3600 * 24 * mValidityDays);
146#ifdef TIME_SLOT_CALIBRATION
147 const auto& payload = mCalibrator->getNoiseMap(tstart, tend);
148#else
149 const auto& payload = mCalibrator->getNoiseMap();
150#endif
151
152 // Preparing the object for production CCDB and sending it
153 std::map<std::string, std::string> md;
154
155 o2::ccdb::CcdbObjectInfo info("ITS/Calib/NoiseMap", "NoiseMap", "noise.root", md, tstart, tend);
156
157 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
158 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName()
159 << " of size " << image->size()
160 << " bytes, valid for " << info.getStartValidityTimestamp()
161 << " : " << info.getEndValidityTimestamp();
162
163 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "ITS_NOISE", 0}, *image.get());
164 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "ITS_NOISE", 0}, info);
165 LOG(info) << "sending of o2::itsmft::NoiseMap done";
166
167 // Preparing the object for DCS CCDB and sending it to output
168 for (int ichip = 0; ichip < o2::itsmft::ChipMappingITS::getNChips(); ichip++) {
169 const std::map<int, int>* chipmap = payload.getChipMap(ichip);
170 if (chipmap) {
171 for (std::map<int, int>::const_iterator it = chipmap->begin(); it != chipmap->end(); ++it) {
172 addDatabaseEntry(ichip, payload.key2Row(it->first), payload.key2Col(it->first));
173 }
174 }
175 }
176
177 o2::ccdb::CcdbObjectInfo info_dcs("ITS/Calib/NOISE", "NoiseMap", "noise_scan.root", md, tstart, tend); // to DCS CCDB
178 auto image_dcs = o2::ccdb::CcdbApi::createObjectImage(&mNoiseMapDCS, &info_dcs);
179 info_dcs.setFileName("noise_scan.root");
180 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "ITS_NOISE", 1}, *image_dcs.get());
181 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "ITS_NOISE", 1}, info_dcs);
182 LOG(info) << "sending of DCSConfigObject done";
183
184 // Timer
185 LOGP(info, "Timing: {:.2f} CPU / {:.2f} Real s. in {} TFs for {} {} / {:.2f} GB",
186 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1,
187 mUseClusters ? "clusters" : "digits",
188 mNClustersProc, double(mDataSizeStat) / (1024L * 1024L * 1024L));
189}
190
191void NoiseCalibratorSpec::addDatabaseEntry(int chip, int row, int col)
192{
193 o2::dcs::addConfigItem(mNoiseMapDCS, "O2ChipID", std::to_string(chip));
194 o2::dcs::addConfigItem(mNoiseMapDCS, "ChipDbID", std::to_string(mConfDBmap->at(chip)));
195 o2::dcs::addConfigItem(mNoiseMapDCS, "Dcol", "-1"); // dummy, just to keep the same format between digital scan and noise scan (easier dcs scripts)
196 o2::dcs::addConfigItem(mNoiseMapDCS, "Row", std::to_string(row));
197 o2::dcs::addConfigItem(mNoiseMapDCS, "Col", std::to_string(col));
198}
199
201{
202 if (mRunStopRequested) {
203 return;
204 }
205 if (mMode == ProcessingMode::Accumulate) {
206 sendAccumulatedMap(ec.outputs());
207 } else {
208 sendOutput(ec.outputs());
209 }
210 mRunStopRequested = true;
211}
212
214void NoiseCalibratorSpec::updateTimeDependentParams(ProcessingContext& pc)
215{
217 if (!mInitOnceDone) {
218 mInitOnceDone = true;
219 if (mUseClusters) {
220 pc.inputs().get<o2::itsmft::TopologyDictionary*>("cldict"); // just to trigger the finaliseCCDB
221 }
222 if (mMode == ProcessingMode::Full || mMode == ProcessingMode::Normalize) {
223 pc.inputs().get<std::vector<int>*>("confdbmap");
224 }
225 }
226}
227
230{
232 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
233 LOG(info) << "cluster dictionary updated";
234 mCalibrator->setClusterDictionary((const o2::itsmft::TopologyDictionary*)obj);
235 return;
236 }
237
238 if (matcher == ConcreteDataMatcher("ITS", "CONFDBMAP", 0)) {
239 LOG(info) << "confDB map updated";
240 mConfDBmap = (std::vector<int>*)obj;
241 return;
242 }
243}
244
245DataProcessorSpec getNoiseCalibratorSpec(bool useClusters, int pmode)
246{
248 std::string name = "its-noise-calibrator";
251 } else if (pmode == int(NoiseCalibratorSpec::ProcessingMode::Accumulate)) {
253 } else if (pmode == int(NoiseCalibratorSpec::ProcessingMode::Normalize)) {
255 name = "its-noise-calibrator_Norm";
256 } else {
257 LOG(fatal) << "Unknown processing mode " << pmode;
258 }
259
260 std::vector<InputSpec> inputs;
261 std::vector<OutputSpec> outputs;
262
264 if (useClusters) {
265 inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe);
266 inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe);
267 inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe);
268 inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary"));
269 } else {
270 inputs.emplace_back("digits", "ITS", "DIGITS", 0, Lifetime::Timeframe);
271 inputs.emplace_back("ROframes", "ITS", "DIGITSROF", 0, Lifetime::Timeframe);
272 }
273 } else {
274 useClusters = false; // not needed for normalization
275 inputs.emplace_back("mapspart", ConcreteDataTypeMatcher{"ITS", "NOISEMAPPART"}, Lifetime::Sporadic); // for normalization of multiple inputs only
276 inputs.emplace_back("mapspartInfo", ConcreteDataTypeMatcher{"ITS", "NOISEMAPPARTINF"}, Lifetime::Sporadic); // for normalization of multiple inputs only
277 }
279 inputs.emplace_back("confdbmap", "ITS", "CONFDBMAP", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/Confdbmap"));
280
281 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "ITS_NOISE"}, Lifetime::Sporadic);
282 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "ITS_NOISE"}, Lifetime::Sporadic);
283 } else { // in accumulation mode the output is a map
284 outputs.emplace_back(ConcreteDataTypeMatcher{"ITS", "NOISEMAPPART"}, Lifetime::Sporadic);
285 outputs.emplace_back(ConcreteDataTypeMatcher{"ITS", "NOISEMAPPARTINF"}, Lifetime::Sporadic);
286 }
287 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
288 false, // GRPECS=true
289 false, // GRPLHCIF
290 false, // GRPMagField
291 false, // askMatLUT
293 inputs);
294
295 return DataProcessorSpec{
296 name,
297 inputs,
298 outputs,
299 AlgorithmSpec{adaptFromTask<NoiseCalibratorSpec>(md, useClusters, ccdbRequest)},
300 Options{
301 {"1pix-only", VariantType::Bool, false, {"Fast 1-pixel calibration only (cluster input only)"}},
302 {"prob-threshold", VariantType::Float, 3.e-6f, {"Probability threshold for noisy pixels"}},
303 {"prob-rel-err", VariantType::Float, 0.2f, {"Relative error on channel noise to apply the threshold"}},
304 {"cut-ib", VariantType::Float, -1.f, {"Special cut to apply to Inner Barrel"}},
305 {"nthreads", VariantType::Int, 1, {"Number of map-filling threads"}},
306 {"validity-days", VariantType::Int, 3, {"Validity on days from upload time"}},
307 {"stop-me-only", VariantType::Bool, false, {"At sufficient statistics stop only this device, otherwise whole workflow"}}}};
308}
309
310} // namespace its
311} // namespace o2
Definition of the ITSMFT compact cluster.
Definition of the ClusterTopology class.
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
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
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.
TransitionHandlingState transitionState() const
void run(ProcessingContext &pc) final
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
static constexpr int getNChips()
number of chips per barrel
Digit class for the ITS.
Definition Digit.h:30
NoiseMap class for the ITS and MFT.
Definition NoiseMap.h:39
GLeglImageOES image
Definition glcorearb.h:4021
GLuint const GLchar * name
Definition glcorearb.h:781
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
long getFutureTimestamp(int secondsInFuture)
returns the timestamp in long corresponding to "now + secondsInFuture"
void addConfigItem(DCSconfigObject_t &configVector, std::string key, const T value)
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 useClusters, int pmode=0)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
size_t maxInputTimeslices
The maximum number of time pipelining for this device.
Definition DeviceSpec.h:70
size_t inputTimesliceId
The time pipelining id of this particular device.
Definition DeviceSpec.h:68
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits
std::vector< int > row