Project
Loading...
Searching...
No Matches
testTPCCalDet.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 <algorithm>
13#define BOOST_TEST_MODULE Test TPC CalDet class
14#define BOOST_TEST_MAIN
15#define BOOST_TEST_DYN_LINK
16#include <boost/range/combine.hpp>
17#include <boost/test/unit_test.hpp>
18#include <vector>
19#include <limits>
20
21#include "TMath.h"
22#include "TPCBase/Mapper.h"
23#include "TPCBase/CalArray.h"
24#include "TPCBase/CalDet.h"
25#include "TFile.h"
28
29namespace o2::tpc
30{
31
32// templated euqality check
33// for integer one would need a specialisation to check for == instead of <
34template <typename T>
35bool isEqualAbs(T x, T y, int n = 1)
36{
37 // Since `epsilon()` is the gap size (ULP, unit in the last place)
38 // of floating-point numbers in interval [1, 2), we can scale it to
39 // the gap size in interval [2^e, 2^{e+1}), where `e` is the exponent
40 // of `x` and `y`.
41
42 // If `x` and `y` have different gap sizes (which means they have
43 // different exponents), we take the smaller one. Taking the bigger
44 // one is also reasonable, I guess.
45 const T m = std::min(std::fabs(x), std::fabs(y));
46
47 // Subnormal numbers have fixed exponent, which is `min_exponent - 1`.
48 const int exp = m < std::numeric_limits<T>::min()
49 ? std::numeric_limits<T>::min_exponent - 1
50 : std::ilogb(m);
51
52 // We consider `x` and `y` equal if the difference between them is
53 // within `n` ULPs.
54 return std::fabs(x - y) <= n * std::ldexp(std::numeric_limits<T>::epsilon(), exp);
55}
56
57template <typename T>
58 requires(std::integral<T>)
59bool isEqualAbs(T val1, T val2)
60{
61 return val1 == val2;
62}
63
64BOOST_AUTO_TEST_CASE(CalArray_ROOTIO)
65{
66 // CalROC roc(PadSubset::ROC, 10);
68
69 int iter = 0;
70 // unsigned iter=0;
71 for (auto& val : roc.getData()) {
72 val = iter++;
73 }
74
75 auto f = TFile::Open("CalArray_ROOTIO.root", "recreate");
76 f->WriteObject(&roc, "roc");
77 delete f;
78
79 // CalROC *rocRead = nullptr;
80 CalArray<unsigned>* rocRead = nullptr;
81 f = TFile::Open("CalArray_ROOTIO.root");
82 f->GetObject("roc", rocRead);
83 delete f;
84
85 BOOST_REQUIRE(rocRead != nullptr);
86
87 float sumROC = 0;
88 for (auto const& val : boost::combine(roc.getData(), rocRead->getData())) {
89 sumROC += (val.get<0>() - val.get<1>());
90 }
91
92 BOOST_CHECK_CLOSE(sumROC, 0., 1.E-12);
93}
94
96{
97
98 auto& mapper = Mapper::instance();
99 const auto numberOfPads = mapper.getPadsInSector() * 36;
100
101 CalPad padROC(PadSubset::ROC);
102 CalPad padPartition(PadSubset::Partition);
103 CalPad padRegion(PadSubset::Region);
104
105 // ===| Fill Data |===========================================================
106 int iter = 0;
107 // --- ROC type
108 padROC.setName("ROCData");
109 for (auto& calArray : padROC.getData()) {
110 for (auto& value : calArray.getData()) {
111 value = iter++;
112 }
113 }
114
115 // --- Partition type
116 padPartition.setName("PartitionData");
117 for (auto& calArray : padPartition.getData()) {
118 for (auto& value : calArray.getData()) {
119 value = iter++;
120 }
121 }
122
123 // --- Region type
124 padRegion.setName("RegionData");
125 for (auto& calArray : padRegion.getData()) {
126 for (auto& value : calArray.getData()) {
127 value = iter++;
128 }
129 }
130
131 // ===| dump all objects to file |============================================
132 auto f = TFile::Open("CalDet.root", "recreate");
133 f->WriteObject(&padROC, "CalDetROC");
134 f->WriteObject(&padPartition, "CalDetPartition");
135 f->WriteObject(&padRegion, "CalDetRegion");
136 f->Close();
137 delete f;
138
139 // ===| read back all values |================================================
140 CalPad* padROCRead = nullptr;
141 CalPad* padPartitionRead = nullptr;
142 CalPad* padRegionRead = nullptr;
143
144 f = TFile::Open("CalDet.root");
145 f->GetObject("CalDetROC", padROCRead);
146 f->GetObject("CalDetPartition", padPartitionRead);
147 f->GetObject("CalDetRegion", padRegionRead);
148
149 delete f;
150
151 BOOST_REQUIRE(padROCRead != nullptr);
152 BOOST_REQUIRE(padPartitionRead != nullptr);
153 BOOST_REQUIRE(padRegionRead != nullptr);
154
155 // ===| compare values before and after |=====================================
156 float sumROC = 0.f;
157 float sumPartition = 0.f;
158 float sumRegion = 0.f;
159
160 int numberOfPadsROC = 0;
161 int numberOfPadsPartition = 0;
162 int numberOfPadsRegion = 0;
163
164 for (auto const& arrays : boost::combine(padROC.getData(), padROCRead->getData())) {
165 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
166 sumROC += (val.get<0>() - val.get<1>());
167 ++numberOfPadsROC;
168 }
169 }
170
171 for (auto const& arrays : boost::combine(padPartition.getData(), padPartitionRead->getData())) {
172 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
173 sumPartition += (val.get<0>() - val.get<1>());
174 ++numberOfPadsPartition;
175 }
176 }
177
178 for (auto const& arrays : boost::combine(padRegion.getData(), padRegionRead->getData())) {
179 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
180 sumRegion += (val.get<0>() - val.get<1>());
181 ++numberOfPadsRegion;
182 }
183 }
184
185 // ===| checks |==============================================================
186 BOOST_CHECK_EQUAL(padROC.getName(), padROCRead->getName());
187 BOOST_CHECK_CLOSE(sumROC, 0.f, 1.E-12);
188 BOOST_CHECK_EQUAL(numberOfPadsROC, numberOfPads);
189
190 BOOST_CHECK_EQUAL(padPartition.getName(), padPartitionRead->getName());
191 BOOST_CHECK_CLOSE(sumPartition, 0.f, 1.E-12);
192 BOOST_CHECK_EQUAL(numberOfPadsPartition, numberOfPads);
193
194 BOOST_CHECK_EQUAL(padRegion.getName(), padRegionRead->getName());
195 BOOST_CHECK_CLOSE(sumRegion, 0.f, 1.E-12);
196 BOOST_CHECK_EQUAL(numberOfPadsRegion, numberOfPads);
197} // BOOST_AUTO_TEST_CASE
198
199BOOST_AUTO_TEST_CASE(CalDet_Arithmetics)
200{
201 // data
203
204 // data 2 for testing operators on objects
206
207 // for applying the operators on
208 CalPad padCmp(PadSubset::ROC);
209
210 // ===| fill with data |======================================================
211 int iter = 0;
212 // --- ROC type
213 for (auto& calArray : pad.getData()) {
214 for (auto& value : calArray.getData()) {
215 value = iter++;
216 }
217 }
218
219 iter = 1;
220 for (auto& calArray : pad2.getData()) {
221 for (auto& value : calArray.getData()) {
222 value = iter++;
223 }
224 }
225
226 //
227 // ===| test operators with simple numbers |==================================
228 //
229 const float number = 0.2f;
230 bool isEqual = true;
231
232 // + operator
233 isEqual = true;
234 padCmp = pad;
235 padCmp += number;
236
237 for (auto const& arrays : boost::combine(padCmp.getData(), pad.getData())) {
238 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
239 isEqual &= isEqualAbs(val.get<0>(), val.get<1>() + number);
240 }
241 }
242 BOOST_CHECK_EQUAL(isEqual, true);
243
244 // - operator
245 isEqual = true;
246 padCmp = pad;
247 padCmp -= number;
248
249 for (auto const& arrays : boost::combine(padCmp.getData(), pad.getData())) {
250 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
251 isEqual &= isEqualAbs(val.get<0>(), val.get<1>() - number);
252 }
253 }
254 BOOST_CHECK_EQUAL(isEqual, true);
255
256 // * operator
257 isEqual = true;
258 padCmp = pad;
259 padCmp *= number;
260
261 for (auto const& arrays : boost::combine(padCmp.getData(), pad.getData())) {
262 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
263 isEqual &= isEqualAbs(val.get<0>(), val.get<1>() * number);
264 }
265 }
266 BOOST_CHECK_EQUAL(isEqual, true);
267
268 // / operator
269 isEqual = true;
270 padCmp = pad;
271 padCmp /= number;
272
273 for (auto const& arrays : boost::combine(padCmp.getData(), pad.getData())) {
274 for (auto const& val : boost::combine(arrays.get<0>().getData(), arrays.get<1>().getData())) {
275 isEqual &= isEqualAbs(val.get<0>(), val.get<1>() / number);
276 }
277 }
278 BOOST_CHECK_EQUAL(isEqual, true);
279
280 //
281 // ===| test operators with full object |=====================================
282 //
283 // + operator
284 isEqual = true;
285 padCmp = pad;
286 padCmp += pad2;
287
288 for (auto itpad = pad.getData().begin(), itpad2 = pad2.getData().begin(), itpadCmp = padCmp.getData().begin(); itpad != pad.getData().end(); ++itpad, ++itpad2, ++itpadCmp) {
289 for (auto itval1 = (*itpad).getData().begin(), itval2 = (*itpad2).getData().begin(), itval3 = (*itpadCmp).getData().begin(); itval1 != (*itpad).getData().end(); ++itval1, ++itval2, ++itval3) {
290 isEqual &= isEqualAbs(*itval3, *itval1 + *itval2);
291 }
292 }
293 BOOST_CHECK_EQUAL(isEqual, true);
294
295 // - operator
296 isEqual = true;
297 padCmp = pad;
298 padCmp -= pad2;
299
300 for (auto itpad = pad.getData().begin(), itpad2 = pad2.getData().begin(), itpadCmp = padCmp.getData().begin(); itpad != pad.getData().end(); ++itpad, ++itpad2, ++itpadCmp) {
301 for (auto itval1 = (*itpad).getData().begin(), itval2 = (*itpad2).getData().begin(), itval3 = (*itpadCmp).getData().begin(); itval1 != (*itpad).getData().end(); ++itval1, ++itval2, ++itval3) {
302 isEqual &= isEqualAbs(*itval3, *itval1 - *itval2);
303 }
304 }
305 BOOST_CHECK_EQUAL(isEqual, true);
306
307 // * operator
308 isEqual = true;
309 padCmp = pad;
310 padCmp *= pad2;
311
312 for (auto itpad = pad.getData().begin(), itpad2 = pad2.getData().begin(), itpadCmp = padCmp.getData().begin(); itpad != pad.getData().end(); ++itpad, ++itpad2, ++itpadCmp) {
313 for (auto itval1 = (*itpad).getData().begin(), itval2 = (*itpad2).getData().begin(), itval3 = (*itpadCmp).getData().begin(); itval1 != (*itpad).getData().end(); ++itval1, ++itval2, ++itval3) {
314 isEqual &= isEqualAbs(*itval3, *itval1 * *itval2);
315 }
316 }
317 BOOST_CHECK_EQUAL(isEqual, true);
318
319 // / operator
320 isEqual = true;
321 padCmp = pad;
322 padCmp /= pad2;
323
324 for (auto itpad = pad.getData().begin(), itpad2 = pad2.getData().begin(), itpadCmp = padCmp.getData().begin(); itpad != pad.getData().end(); ++itpad, ++itpad2, ++itpadCmp) {
325 for (auto itval1 = (*itpad).getData().begin(), itval2 = (*itpad2).getData().begin(), itval3 = (*itpadCmp).getData().begin(); itval1 != (*itpad).getData().end(); ++itval1, ++itval2, ++itval3) {
326 isEqual &= isEqualAbs(*itval3, *itval1 / *itval2);
327 }
328 }
329 BOOST_CHECK_EQUAL(isEqual, true);
330
331 // = operator
332 isEqual = true;
333 padCmp = 10.f;
334 for (const auto& calArr : padCmp.getData()) {
335 isEqual &= std::all_of(calArr.getData().begin(), calArr.getData().end(), [](const auto val) { return isEqualAbs(val, 10.f); });
336 }
337 BOOST_CHECK_EQUAL(isEqual, true);
338}
339
347
348BOOST_AUTO_TEST_CASE(CalDetStreamerTest)
349{
350 // simple code executing the TPC IDCPadFlags loading in a standalone env --> easy to valgrind
352 creator.init("https://alice-ccdb.cern.ch");
353 creator.loadIDCPadFlags(1731274461770);
354}
355
356} // namespace o2::tpc
uint32_t pad2
uint64_t exp(uint64_t base, uint8_t exp) noexcept
uint32_t roc
Definition RawData.h:3
const std::vector< T > & getData() const
Definition CalArray.h:113
void setName(const std::string_view name, bool nameCalArrays=true)
Definition CalDet.h:84
const std::vector< CalType > & getData() const
Definition CalDet.h:64
const std::string & getName() const
Definition CalDet.h:91
void init(std::string_view url="")
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLdouble f
Definition glcorearb.h:310
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLuint GLfloat * val
Definition glcorearb.h:1582
const GLuint * arrays
Definition glcorearb.h:1314
Defining PrimaryVertex explicitly as messageable.
Global TPC definitions and constants.
Definition SimTraits.h:168
BOOST_AUTO_TEST_CASE(ClusterHardware_test1)
bool isEqualAbs(T x, T y, int n=1)
@ Partition
Partitions (up to 36*5)
@ ROC
ROCs (up to 72)
@ Region
Regions (up to 36*10)
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())