Project
Loading...
Searching...
No Matches
BadChannelCalibrator.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
14#include "Framework/Logger.h"
17#include "MathUtils/fit.h"
18#include <algorithm>
19#include <cassert>
20#include <iostream>
21#include <iterator>
22#include <numeric>
23#include <limits>
24#include <sstream>
25
27{
28
29void BadChannelCalibrator::initOutput()
30{
31 mPedestalsVector.clear();
32 mBadChannelsVector.clear();
33}
34
35bool BadChannelCalibrator::readyToSend(std::string& reason) const
36{
37 reason = "";
38
39 // let's check our hypothesis about this object (nslots=1) is actually true
40 auto nslots = getNSlots();
41 if (nslots != 1) {
42 LOGP(error, "nslots={} while it is expected to be 1", nslots);
43 return false;
44 }
45
46 auto& slot = getFirstSlot();
47 bool statIsEnough = hasEnoughData(slot);
48 if (statIsEnough) {
49 reason = "enough statistics";
50 const o2::mch::calibration::PedestalData* pedData = slot.getContainer();
51 }
52 return statIsEnough;
53}
54
55void BadChannelCalibrator::finalize()
56{
57 // let's check our hypothesis about this object (nslots=1) is actually true
58 auto nslots = getNSlots();
59 if (nslots != 1) {
60 LOGP(fatal, "nslots={} while it is expected to be 1", nslots);
61 }
62
63 auto& slot = getSlot(0);
64 finalizeSlot(slot);
65}
66
67bool BadChannelCalibrator::hasEnoughData(const Slot& slot) const
68{
69 static auto loggerStart = std::chrono::high_resolution_clock::now();
70 static auto loggerEnd = loggerStart;
71 const int minNofEntries = BadChannelCalibratorParam::Instance().minRequiredNofEntriesPerChannel;
73 auto nofChannels = pedData->size();
74 const int requiredChannels = static_cast<int>(BadChannelCalibratorParam::Instance().minRequiredCalibratedFraction * nofChannels);
75
76 auto nofCalibrated = std::count_if(pedData->cbegin(), pedData->cend(),
77 [&](const PedestalChannel& c) { return c.mEntries > minNofEntries; });
78
79 bool hasEnough = nofCalibrated > requiredChannels;
80
81 // logging of calibration statistics
82 loggerEnd = std::chrono::high_resolution_clock::now();
83 std::chrono::duration<double, std::milli> loggerElapsed = loggerEnd - loggerStart;
84 if (mLoggingInterval > 0 && loggerElapsed.count() > mLoggingInterval) {
85 int minEntriesPerChannel{std::numeric_limits<int>::max()};
86 int maxEntriesPerChannel{0};
87 uint64_t averageEntriesPerChannel = 0;
88 std::for_each(pedData->cbegin(), pedData->cend(),
89 [&](const PedestalChannel& c) {
90 if (c.mEntries == 0) {
91 return;
92 }
93 if (c.mEntries > maxEntriesPerChannel) {
94 maxEntriesPerChannel = c.mEntries;
95 }
96 if (c.mEntries < minEntriesPerChannel) {
97 minEntriesPerChannel = c.mEntries;
98 }
99 averageEntriesPerChannel += c.mEntries;
100 });
101 if (nofChannels > 0) {
102 averageEntriesPerChannel /= nofChannels;
103 }
104 LOGP(warning, "channel stats: min={} max={} average={}", minEntriesPerChannel, maxEntriesPerChannel, averageEntriesPerChannel);
105 LOGP(warning,
106 "nofChannelWithEnoughStat(>{})={} nofChannels={} requiredChannels={} hasEnough={}",
107 minNofEntries, nofCalibrated, nofChannels, requiredChannels, hasEnough);
108 loggerStart = std::chrono::high_resolution_clock::now();
109 }
110
111 return hasEnough;
112}
113
114void BadChannelCalibrator::finalizeSlot(Slot& slot)
115{
116 // Extract results for the single slot
117 auto pedestalThreshold = BadChannelCalibratorParam::Instance().maxPed;
118 auto noiseThreshold = BadChannelCalibratorParam::Instance().maxNoise;
119
120 mPedestalsVector.clear();
121 mBadChannelsVector.clear();
122
124 LOG(warning) << "Finalize slot " << slot.getTFStart() << " <= TF <= " << slot.getTFEnd();
125
126 // keep track of first TimeFrame
127 if (slot.getTFStart() < mTFStart) {
128 mTFStart = slot.getTFStart();
129 }
130
131 for (const auto& ped : *pedestalData) {
132 if (ped.mEntries == 0) {
133 continue;
134 }
135 mPedestalsVector.emplace_back(ped);
136 bool bad = true;
137 if (ped.mPedestal < pedestalThreshold) {
138 if (ped.getRms() < noiseThreshold) {
139 bad = false;
140 }
141 }
142 if (bad) {
143 LOG(info) << ped;
144 mBadChannelsVector.emplace_back(ped.dsChannelId);
145 }
146 }
147}
148
150 BadChannelCalibrator::emplaceNewSlot(bool front, TFType tstart, TFType tend)
151{
152 const int nThreads = static_cast<int>(BadChannelCalibratorParam::Instance().nThreads);
153 auto& cont = getSlots();
154 auto& slot = front ? cont.emplace_front(tstart, tend) : cont.emplace_back(tstart, tend);
155 slot.setContainer(std::make_unique<PedestalData>());
156 slot.getContainer()->setNThreads(nThreads);
157 return slot;
158}
159
160} // namespace o2::mch::calibration
MCH calibrator to produce a bad channel map, using pedestal data.
Utils and constants for calibration and related workflows.
uint32_t c
Definition RawData.h:2
TFType getTFEnd() const
Definition TimeSlot.h:47
const Container * getContainer() const
Definition TimeSlot.h:53
TFType getTFStart() const
Definition TimeSlot.h:46
bool hasEnoughData(const Slot &slot) const final
Compute and store the mean and RMS of the pedestal digit amplitudes.
Pedestal mean and sigma for one channel.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"