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