Project
Loading...
Searching...
No Matches
PedestalData.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
17#include "fairlogger/Logger.h"
18#include <cmath>
19#include <iostream>
20#include <iterator>
21#include <limits>
22#include <mutex>
23#include <thread>
24#include <queue>
25
27{
28
29PedestalData::PedestalData()
30{
31 mSolar2FeeLinkMapper = o2::mch::raw::createSolar2FeeLinkMapper<o2::mch::raw::ElectronicMapperGenerated>();
32 mElec2DetMapper = o2::mch::raw::createElec2DetMapper<o2::mch::raw::ElectronicMapperGenerated>();
33}
34
35void PedestalData::reset()
36{
37 mPedestals.clear();
38}
39
40PedestalData::PedestalMatrix PedestalData::initPedestalMatrix(uint16_t solarId)
41{
43 for (uint8_t d = 0; d < PedestalData::MAXDS; d++) {
44 // apply the mapping from SOLAR to detector
45 int deId = -1;
46 int dsIddet = -1;
47
48 o2::mch::raw::DsElecId dsElecId(solarId, d / 5, d % 5);
49 std::optional<o2::mch::raw::DsDetId> dsDetId = mElec2DetMapper(dsElecId);
50 if (dsDetId) {
51 deId = dsDetId->deId();
52 dsIddet = dsDetId->dsId();
53 }
54
55 for (uint8_t c = 0; c < PedestalData::MAXCHANNEL; c++) {
56
57 // check if the channel is associated to a detector pad
58 int padId = -1;
59 if (deId >= 0 && dsIddet >= 0) {
61 padId = segment.findPadByFEE(dsIddet, int(c));
62 }
63 if (padId >= 0) {
64 m[d][c].dsChannelId = DsChannelId{solarId, d, c};
65 mSize += 1;
66 }
67 }
68 }
69 return m;
70}
71
72void PedestalData::fill(gsl::span<const PedestalDigit> digits)
73{
74 bool mDebug = false;
75 static std::mutex pedestalMutex;
76 static std::set<uint16_t> solarIds = o2::mch::raw::getSolarUIDs<o2::mch::raw::ElectronicMapperGenerated>();
77
78 if (digits.empty()) {
79 return;
80 }
81
82 LOGP(info, "processing {} digits with {} threads", (int)digits.size(), mNThreads);
83
84 // fill the queue of SOLAR IDs to be processed
85 std::queue<uint16_t> solarQueue;
86 for (auto solarId : solarIds) {
87 solarQueue.push(solarId);
88 }
89
90 auto processSolarDigits = [&]() {
91 while (true) {
92 int targetSolarId = -1;
93 PedestalsMap::iterator iPedestal;
94 bool pedestalsAreInitialized;
95
96 // non thread-safe access to solarQueue, protected by the pedestalMutex
97 {
98 std::lock_guard<std::mutex> lock(pedestalMutex);
99
100 // stop when there are no mor SOLAR IDs to process
101 if (solarQueue.empty()) {
102 break;
103 }
104
105 // get the next SOLAR ID to be processed
106 targetSolarId = solarQueue.front();
107 solarQueue.pop();
108
109 // update the iterator to the pedestal data for the target SOLAR
110 iPedestal = mPedestals.find(targetSolarId);
111 if (iPedestal == mPedestals.end()) {
112 pedestalsAreInitialized = false;
113 } else {
114 pedestalsAreInitialized = true;
115 }
116 }
117
118 // loop over digits, selecting only those belonging to the target SOLAR
119 for (auto& d : digits) {
120 uint16_t solarId = d.getSolarId();
121 if (solarId != targetSolarId) {
122 continue;
123 }
124
125 // non thread-safe access to Pedestals structure, protected by the pedestalMutex
126 if (!pedestalsAreInitialized) {
127 std::lock_guard<std::mutex> lock(pedestalMutex);
128
129 // create the pedestals structure corresponding to the SOLAR ID to be processed
130 iPedestal = mPedestals.emplace(std::make_pair(targetSolarId, initPedestalMatrix(targetSolarId))).first;
131
132 if (iPedestal == mPedestals.end()) {
133 LOGP(fatal, "failed to insert new element in padestals map");
134 break;
135 }
136 pedestalsAreInitialized = true;
137 }
138
139 uint8_t dsId = d.getDsId();
140 uint8_t channel = d.getChannel();
141
142 auto& ped = iPedestal->second[dsId][channel];
143
144 for (uint16_t i = 0; i < d.nofSamples(); i++) {
145 auto s = d.getSample(i);
146
147 ped.mEntries += 1;
148 uint64_t N = ped.mEntries;
149
150 double p0 = ped.mPedestal;
151 double p = p0 + (s - p0) / N;
152 ped.mPedestal = p;
153
154 double M0 = ped.mVariance;
155 double M = M0 + (s - p0) * (s - p);
156 ped.mVariance = M;
157 }
158
159 if (mDebug) {
160 LOGP(info, "solarId {} dsId {} ch {} nsamples {} entries{} mean {} variance {}",
161 (int)solarId, (int)dsId, (int)channel, d.nofSamples(), ped.mEntries, ped.mPedestal, ped.mVariance);
162 }
163 }
164 }
165 };
166
167 // process the digits in parallel threads
168 std::vector<std::thread> threads;
169 for (int ti = 0; ti < mNThreads; ti++) {
170 threads.emplace_back(processSolarDigits);
171 }
172
173 // wait for all threads to finish processing
174 for (auto& thread : threads) {
175 thread.join();
176 }
177}
178
179void PedestalData::merge(const PedestalData* prev)
180{
181 // merge data of 2 slots
182 LOGP(error, "not yet implemented");
183}
184
185void PedestalData::print() const
186{
187 for (const auto& p : const_cast<PedestalData&>(*this)) {
188 LOGP(info, fmt::runtime(p.asString()));
189 }
190}
191
192uint32_t PedestalData::size() const
193{
194 return mSize;
195}
196
197PedestalData::iterator PedestalData::begin()
198{
199 return PedestalData::iterator(this);
200}
201
202PedestalData::iterator PedestalData::end()
203{
204 return PedestalData::iterator(nullptr);
205}
206
207PedestalData::const_iterator PedestalData::cbegin() const
208{
209 return PedestalData::const_iterator(const_cast<PedestalData*>(this));
210}
211PedestalData::const_iterator PedestalData::cend() const
212{
213 return PedestalData::const_iterator(nullptr);
214}
215
216} // namespace o2::mch::calibration
int32_t i
uint32_t c
Definition RawData.h:2
Compute and store the mean and RMS of the pedestal digit amplitudes.
impl::PedestalDataIterator< PedestalChannel > iterator
static constexpr int MAXCHANNEL
impl::PedestalDataIterator< const PedestalChannel > const_iterator
std::array< std::array< PedestalChannel, MAXCHANNEL >, MAXDS > PedestalMatrix
A Segmentation lets you find pads of a detection element and then inspect those pads.
const GLfloat * m
Definition glcorearb.h:4066
GLuint segment
Definition glcorearb.h:4945
O2MCHMAPPINGIMPL3_EXPORT const Segmentation & segmentation(int detElemId)
std::vector< Digit > digits