Project
Loading...
Searching...
No Matches
NoiseCalibData.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
12#include <TMath.h>
13#include <TH1.h>
14#include <TFile.h>
15#include <TDirectory.h>
16#include "Framework/Logger.h"
18
19using namespace o2::zdc;
20
21//______________________________________________________________________________
23{
24 LOGF(info, "NoiseCalibData::print ts (%llu:%llu)", mCTimeBeg, mCTimeEnd);
25 for (int is = 0; is < NChannels; is++) {
26 uint64_t en = 0;
27 double mean = 0, var = 0;
28 if (getStat(is, en, mean, var) == 0) {
29 LOGF(info, "Noise %2d %s with %10llu events %smean %8.1f rms %8.1f (ch) max=%d", is, ChannelNames[is].data(), en, mHisto[is].mOverflow ? " IN_OVERFLOW" : "",
30 mean, TMath::Sqrt(var), mHisto[is].getMaxBin());
31 }
32 }
33}
34
35//______________________________________________________________________________
37{
38 // Adding data in the working representation
39 if (other.mOverflow) {
40 // Refusing to add an overflow
41 LOG(warn) << "NoiseCalibData" << __func__ << " Refusing to add an overflow. BREAK!";
42 return *this;
43 }
44 for (int32_t is = 0; is < NChannels; is++) {
45 if (other.mHisto[is].mOverflow) {
46 // Refusing to add an overflow histogram
47 LOG(warn) << "NoiseCalibData::" << __func__ << " Refusing to add an overflow histogram for ch " << is << " BREAK!";
48 return *this;
49 }
50 // Check if sum will result into an overflow
51 // The number of bins is not defined a priori: identify max bin number
52 uint32_t maxc = mHisto[is].getMaxBin();
53 uint32_t maxo = other.mHisto[is].getMaxBin();
54 auto max = std::min(maxc, maxo) + 1;
55 for (int32_t i = 0; i < max; i++) {
56 auto pcur = mHisto[is].mData.find(i);
57 auto poth = other.mHisto[is].mData.find(i);
58 if (pcur != mHisto[is].mData.end() && poth != other.mHisto[is].mData.end()) {
59 uint64_t sum = pcur->first + pcur->second;
60 if (sum > 0xffffffff) {
61 LOG(warn) << "NoiseCalibData::" << __func__ << " Addition would result in an overflow for ch " << is << " BREAK!";
62 return *this;
63 }
64 }
65 }
66 }
67 // No problems with overflow
68 for (int32_t is = 0; is < NChannels; is++) {
69 for (const auto& [key, value] : other.mHisto[is].mData) {
70 mHisto[is].mData[key] = mHisto[is].mData[key] + value;
71 }
72 }
73 if (mCTimeBeg == 0 || other.mCTimeBeg < mCTimeBeg) {
74 mCTimeBeg = other.mCTimeBeg;
75 }
76 if (other.mCTimeEnd > mCTimeEnd) {
77 mCTimeEnd = other.mCTimeEnd;
78 }
79#ifdef O2_ZDC_DEBUG
80 LOG(info) << __func__;
81 print();
82#endif
83 return *this;
84}
85
86//______________________________________________________________________________
88{
89 mCTimeBeg = s.mCTimeBeg;
90 mCTimeEnd = s.mCTimeEnd;
91 mOverflow = s.mOverflow;
92 for (int32_t is = 0; is < NChannels; is++) {
93 // Need to clear all bins since summary data have info only on filled channels
94 mHisto[is].clear();
95 mHisto[is].mOverflow = s.mOverflowCh[is];
96 // Cross check
97 if (mHisto[is].mOverflow && mOverflow == false) {
98 LOG(warn) << "Overflow bit set on signal " << is;
99 mOverflow = true;
100 }
101 }
102 for (const NoiseCalibBinData& bin : s.mData) {
103 mHisto[bin.id()].mData[bin.bin()] = bin.cont;
104 }
105 return *this;
106}
107
108//______________________________________________________________________________
110{
111 if (s == nullptr) {
112 LOG(error) << "NoiseCalibData::operator+=(const NoiseCalibSummaryData* s): null pointer";
113 return *this;
114 }
115 if (s->mOverflow) {
116 // Refusing to add an overflow
117 LOG(warn) << __func__ << " Refusing to add an overflow NoiseCalibSummaryData BREAK!";
118 s->print();
119 return *this;
120 }
121 for (int32_t is = 0; is < NChannels; is++) {
122 if (s->mOverflowCh[is]) {
123 // Refusing to add an overflow histogram
124 LOG(warn) << __func__ << " Refusing to add an overflow histogram for ch " << is << " BREAK!";
125 s->print();
126 return *this;
127 }
128 }
129 // Check if sum will result into an overflow
130 for (auto& bin : s->mData) {
131 uint64_t sum = mHisto[bin.id()].mData[bin.bin()] + bin.cont;
132 if (sum > 0xffffffff) {
133 LOG(warn) << __func__ << " Addition would result in an overflow for ch " << bin.id() << " BREAK!";
134 return *this;
135 }
136 }
137 if (mCTimeBeg == 0 || s->mCTimeBeg < mCTimeBeg) {
138 mCTimeBeg = s->mCTimeBeg;
139 }
140 if (s->mCTimeEnd > mCTimeEnd) {
141 mCTimeEnd = s->mCTimeEnd;
142 }
143 for (auto& bin : s->mData) {
144 mHisto[bin.id()].mData[bin.bin()] = mHisto[bin.id()].mData[bin.bin()] + bin.cont;
145 }
146 return *this;
147}
148
149//______________________________________________________________________________
151{
152 if (mCTimeBeg == 0 || ctime < mCTimeBeg) {
153 mCTimeBeg = ctime;
154 }
155 if (ctime > mCTimeEnd) {
156 mCTimeEnd = ctime;
157 }
158#ifdef O2_ZDC_DEBUG
159 LOGF(info, "NoiseCalibData::setCreationTime %llu", ctime);
160#endif
161}
162
163//______________________________________________________________________________
165{
166 mCTimeBeg = ctime;
167 mCTimeEnd = ctime;
168#ifdef O2_ZDC_DEBUG
169 LOGF(info, "NoiseCalibData::setCreationTime %llu", ctime);
170#endif
171}
172
173//______________________________________________________________________________
174uint64_t NoiseCalibData::getEntries(int is) const
175{
176 if (is < 0 || is >= NChannels) {
177 LOGF(error, "NoiseCalibData::getEntries channel index %d is out of range", is);
178 return 0;
179 }
180 return mHisto[is].getEntries();
181}
182
184{
185 uint64_t sum = 0;
186 for (const auto& [key, value] : mData) {
187 sum = sum + value;
188 }
189 return sum;
190}
191
192uint32_t NoiseCalibData::getMaxBin(int is) const
193{
194 if (is < 0 || is >= NChannels) {
195 LOGF(error, "NoiseCalibData::getMaxBin channel index %d is out of range", is);
196 return 0;
197 }
198 return mHisto[is].getMaxBin();
199}
200
202{
203 uint32_t max = 0;
204 for (const auto& [key, value] : mData) {
205 if (key > max) {
206 max = key;
207 }
208 }
209 return max;
210}
211
212//______________________________________________________________________________
213int NoiseCalibData::getStat(int is, uint64_t& en, double& mean, double& var) const
214{
215 if (is < 0 || is >= NChannels) {
216 LOGF(error, "NoiseCalibData::getStat channel index %d is out of range", is);
217 return 1;
218 }
219 return mHisto[is].getStat(en, mean, var);
220}
221
222int NoiseCalibChData::getStat(uint64_t& en, double& mean, double& var) const
223{
224 en = 0;
225 uint64_t sum = 0;
226 for (const auto& [key, value] : mData) {
227 en = en + value;
228 sum = sum + key * value;
229 }
230 if (en == 0) {
231 return 1;
232 }
233 mean = double(sum) / double(en);
234 if (en > 1) {
235 double sums = 0;
236 for (const auto& [key, value] : mData) {
237 double diff = key - mean;
238 sums = sums + (value * diff * diff);
239 }
240 var = sums / (en - 1);
241 } else {
242 var = 0;
243 }
244 // Convert mean to correct range
245 mean = mean;
246 return 0;
247}
248
249//______________________________________________________________________________
250int NoiseCalibData::saveDebugHistos(const std::string fn, bool is_epn)
251{
252 TDirectory* cwd = gDirectory;
253 TFile* f = new TFile(fn.data(), "recreate");
254 if (f->IsZombie()) {
255 LOG(error) << "Cannot create file: " << fn;
256 return 1;
257 }
258 double factor = 1. / double(NTimeBinsPerBC * (NTimeBinsPerBC - 1));
259 for (int32_t is = 0; is < NChannels; is++) {
260 uint64_t nen = mHisto[is].getEntries();
261 if (nen > 0) {
262 int32_t max = mHisto[is].getMaxBin();
263 TString n = TString::Format("h%d", is);
264 TString t = TString::Format("%sNoise %d %s", is_epn ? "EPN " : "", is, ChannelNames[is].data());
265 TH1F h(n, t, max + 1, -0.5 * factor, (max + 0.5) * factor);
266 for (int ibx = 0; ibx < max; ibx++) {
267 h.SetBinContent(ibx + 1, mHisto[is].mData[ibx] * factor);
268 }
269 h.SetEntries(nen);
270 h.Write("", TObject::kOverwrite);
271 }
272 }
273 f->Close();
274 cwd->cd();
275 return 0;
276}
277
278//______________________________________________________________________________
280{
281 mCTimeBeg = 0;
282 mCTimeEnd = 0;
283 mOverflow = false;
284 mSummary.clear();
285 for (int32_t is = 0; is < NChannels; is++) {
286 mHisto[is].clear();
287 }
288}
289
291{
292 mOverflow = false;
293 mData.clear();
294}
295
297{
298 mCTimeBeg = 0;
299 mCTimeEnd = 0;
300 mOverflow = false;
301 mOverflowCh.fill(false);
302 mData.clear();
303}
304
305//______________________________________________________________________________
307{
308 mSummary.clear();
312 for (int32_t is = 0; is < NChannels; is++) {
314 for (const auto& [ib, cont] : mHisto[is].mData) {
315 if (cont > 0) {
316 mSummary.mData.emplace_back(is, ib, cont);
317 }
318 }
319 }
320 return mSummary;
321}
322
323//______________________________________________________________________________
325{
326 LOGF(info, "NoiseCalibSummaryData: %llu:%llu %d bins%s", mCTimeBeg, mCTimeEnd, mData.size(), (mOverflow ? " OVERFLOW_BIT" : ""));
327 if (mOverflow) {
328 printf("OVERFLOW:");
329 for (int ich = 0; ich < NChannels; ich++) {
330 if (mOverflowCh[ich]) {
331 printf(" %s", ChannelNames[ich].data());
332 }
333 }
334 printf("\n");
335 }
336 int nbin[NChannels] = {0};
337 uint64_t ccont[NChannels] = {0};
338 for (auto& bin : mData) {
339 nbin[bin.id()] = nbin[bin.id()] + 1;
340 ccont[bin.id()] = ccont[bin.id()] + bin.cont;
341 }
342 for (int32_t is = 0; is < NChannels; is++) {
343 LOG(info) << "Summary ch " << is << " nbin = " << nbin[is] << " ccont = " << ccont[is];
344 }
345}
int32_t i
Format of noise calibration intermediate data.
StringRef key
Class for time synchronization of RawReader instances.
float sum(float s, o2::dcs::DataPointValue v)
Definition dcs-ccdb.cxx:39
GLdouble n
Definition glcorearb.h:1982
GLdouble f
Definition glcorearb.h:310
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean * data
Definition glcorearb.h:298
constexpr int NTimeBinsPerBC
Definition Constants.h:53
constexpr int NChannels
Definition Constants.h:65
constexpr std::string_view ChannelNames[]
Definition Constants.h:147
uint64_t getEntries() const
Overflow flag (cannot accept more data)
int getStat(uint64_t &en, double &mean, double &var) const
std::map< uint32_t, uint32_t > mData
bool mOverflow
Map histogram container.
NoiseCalibSummaryData & getSummary()
int saveDebugHistos(const std::string fn, bool is_epn=false)
NoiseCalibChData mHisto[NChannels]
Overflow at least one ZDC channel.
NoiseCalibData & operator=(const NoiseCalibSummaryData &s)
uint32_t getMaxBin(int is) const
void mergeCreationTime(uint64_t ctime)
uint64_t mCTimeEnd
Time of processed time frame.
NoiseCalibData & operator+=(const NoiseCalibData &other)
Serialized data to be dispatched.
int getStat(int is, uint64_t &en, double &mean, double &var) const
NoiseCalibSummaryData mSummary
Sparse histogram of single channels.
bool mOverflow
Time of processed time frame.
uint64_t getEntries(int is) const
void setCreationTime(uint64_t ctime)
bool mOverflow
Time of processed time frame.
uint64_t mCTimeEnd
Time of processed time frame.
void clear()
Data of not empty bins.
std::vector< NoiseCalibBinData > mData
Channel overflow information.
std::array< bool, NChannels > mOverflowCh
Overflow of one channel.
constexpr size_t max
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"