Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BinningDataTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BinningDataTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
15 
16 #include <cmath>
17 #include <cstddef>
18 #include <memory>
19 #include <utility>
20 #include <vector>
21 
22 namespace Acts {
23 namespace Test {
24 
25 namespace tt = boost::test_tools;
26 
27 // the test positions in 3D
28 Vector3 xyzPosition(0.5, 1.5, 2.5);
29 Vector3 xyzPositionOutside(30., -30., 200.);
30 Vector3 phi0Position(0.5, 0., 2.5);
31 Vector3 phiPihPosition(0., 1.5, 2.5);
32 Vector3 eta0Position(0.5, 1.5, 0.);
33 // the test positions in 2D
34 Vector2 xyPosition(0.5, 1.5);
35 Vector2 rphizPosition(0.1, 2.5);
36 Vector2 rphiPosition(3.5, M_PI / 8.);
37 
38 // the binnings - equidistant
39 // x/y/zData
40 // bin boundaries
41 // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
42 BinningData xData_eq(open, binX, 10, 0., 10.);
43 BinningData yData_eq(open, binY, 10, 0., 10.);
44 BinningData zData_eq(open, binZ, 10, 0., 10.);
45 // r/phi/rphiData
46 // bin boundaries
47 // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
48 BinningData rData_eq(open, binR, 10, 0., 10.);
49 // bin boundaries
50 // > -M_PI | -3/5 M_PI | -1/5 M_PI | 1/5 M_PI | 3/5 M_PI | M_PI <
51 BinningData phiData_eq(closed, binPhi, 5, -M_PI, M_PI);
52 BinningData rPhiData_eq(closed, binRPhi, 5, -M_PI, M_PI);
53 // h/etaData
54 // bin boundaries
55 // | 0 | 2 | 4 | 6 | 8 | 10 |
56 BinningData hData_eq(open, binH, 5, 0., 10.);
57 // | -2.5 | -1.5 | -0.5 | 0.5 | 1.5 | 2.5 |
58 BinningData etaData_eq(open, binEta, 5, -2.5, 2.5);
59 
60 // Fest equality operator
61 BinningData xData_eq_copy(open, binX, 10, 0., 10.);
62 
63 // the binnings - arbitrary
64 std::vector<float> values = {0., 1., 2., 3., 4., 10.};
65 // bin boundaries
66 // | 0 | 1 | 2 | 3 | 4 | 10 |
69 // | -M_PI | -2 | -1 | 1 | 2 | M_PI |
70 std::vector<float> phiValues = {-M_PI, -2., -1., 1., 2., M_PI};
72 
73 // the binnings - arbitrary when switching to binary search - for boundary
74 // sizes >= 50
75 size_t nBins_binary = 59;
76 double valueMin = 0.;
77 double phiMin = -M_PI;
78 double delta = 0.5;
79 double phiDelta = 0.1064;
80 
81 // the binning - substructure
82 std::vector<float> sstr = {0., 1., 1.5, 2., 3.};
83 // multiplicative
84 auto xData_sstr_mult = std::make_unique<const BinningData>(open, binX, sstr);
85 // | 0 | 1 | 1.5 | 2 | 3 | 4 | 4.5 | 5 | 6 | 7 | 7.5 | 8 | 9 |
88 // | 0 | 1 | 1.5 | 2 | 3 | 4 | 5 |
89 std::vector<float> main_sstr = {0., 3., 4., 5.};
90 auto xData_sstr_add = std::make_unique<const BinningData>(open, binX, sstr);
92 
93 // enum BinningValue { binX, binY, binZ, binR, binPhi, binRPhi, binH, binEta }
94 //
95 // test the different binning values
96 BOOST_AUTO_TEST_CASE(BinningData_BinningValue) {
97  // the binnings - arbitrary when switching to binary search - for boundary
98  // sizes >= 50
99  std::vector<float> values_binary;
100  std::vector<float> phiValues_binary;
101  for (size_t i = 0; i <= nBins_binary; i++) {
102  values_binary.push_back(valueMin + i * delta);
103  phiValues_binary.push_back(phiMin + i * phiDelta);
104  }
105  // bin boundaries when switching to binary search - for boundary sizes >= 50
106  BinningData xData_arb_binary(open, binX, values_binary);
107  BinningData phiData_arb_binary(closed, binPhi, phiValues_binary);
110  // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
111  BOOST_CHECK_EQUAL(xData_eq.bins(), size_t(10));
112  // | 0 | 1 | 2 | 3 | 4 | 10 |
113  BOOST_CHECK_EQUAL(xData_arb.bins(), size_t(5));
114  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 4.5 | 5 | 6 | 7 | 7.5 | 8 | 9 |
115  BOOST_CHECK_EQUAL(xData_mult.bins(), size_t(12));
116  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 5 |
117  BOOST_CHECK_EQUAL(xData_add.bins(), size_t(6));
118  BOOST_CHECK_EQUAL(xData_arb_binary.bins(), nBins_binary);
119 
120  BOOST_CHECK(xData_eq_copy == xData_eq_copy);
121  BOOST_CHECK(not(xData_eq == yData_eq));
122 
124  BOOST_CHECK_EQUAL(xData_eq.value(xyzPosition), 0.5);
125  BOOST_CHECK_EQUAL(yData_eq.value(xyzPosition), 1.5);
126  BOOST_CHECK_EQUAL(zData_eq.value(xyzPosition), 2.5);
127  BOOST_CHECK_EQUAL(xData_arb.value(xyzPosition), 0.5);
128  BOOST_CHECK_EQUAL(xData_mult.value(xyzPosition), 0.5);
129  BOOST_CHECK_EQUAL(xData_add.value(xyzPosition), 0.5);
130  BOOST_CHECK_EQUAL(xData_arb_binary.value(xyzPosition), 0.5);
131 
133  BOOST_CHECK_EQUAL(xData_eq.value(xyPosition), 0.5);
134  BOOST_CHECK_EQUAL(yData_eq.value(xyPosition), 1.5);
135  BOOST_CHECK_EQUAL(zData_eq.value(rphizPosition), 2.5);
136  BOOST_CHECK_EQUAL(xData_arb.value(xyPosition), 0.5);
137  BOOST_CHECK_EQUAL(xData_mult.value(xyPosition), 0.5);
138  BOOST_CHECK_EQUAL(xData_add.value(xyPosition), 0.5);
139  BOOST_CHECK_EQUAL(xData_arb_binary.value(xyPosition), 0.5);
140 
141  // r/phi/rphiData
142  CHECK_CLOSE_REL(rData_eq.value(xyzPosition), std::hypot(0.5, 1.5), 1e-5);
143  BOOST_CHECK_EQUAL(rData_eq.value(rphiPosition), 3.5);
144 
147 
148  BOOST_CHECK_EQUAL(phiData_eq.bins(), size_t(5));
149  BOOST_CHECK_EQUAL(phiData_arb.bins(), size_t(5));
150  BOOST_CHECK_EQUAL(phiData_arb_binary.bins(), size_t(nBins_binary));
151 
152  // h/etaData
154 }
155 
156 // test bin values
157 BOOST_AUTO_TEST_CASE(BinningData_bins) {
158  // the binnings - arbitrary when switching to binary search - for boundary
159  // sizes >= 50
160  std::vector<float> values_binary;
161  std::vector<float> phiValues_binary;
162  for (size_t i = 0; i <= nBins_binary; i++) {
163  values_binary.push_back(valueMin + i * delta);
164  phiValues_binary.push_back(phiMin + i * phiDelta);
165  }
166  // bin boundaries when switching to binary search - for boundary sizes >= 50
167  BinningData xData_arb_binary(open, binX, values_binary);
168  BinningData phiData_arb_binary(closed, binPhi, phiValues_binary);
171  // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
172  BOOST_CHECK_EQUAL(xData_eq.searchGlobal(xyzPosition), size_t(0));
173  BOOST_CHECK_EQUAL(yData_eq.searchGlobal(xyzPosition), size_t(1));
174  BOOST_CHECK_EQUAL(zData_eq.searchGlobal(xyzPosition), size_t(2));
175  // | 0 | 1 | 2 | 3 | 4 | 10 |
176  BOOST_CHECK_EQUAL(xData_arb.searchGlobal(xyzPosition), size_t(0));
177  BOOST_CHECK_EQUAL(xData_arb.search(6.), size_t(4));
178  BOOST_CHECK_EQUAL(xData_arb_binary.searchGlobal(xyzPosition), size_t(0));
179  BOOST_CHECK_EQUAL(xData_arb_binary.search(50.), (nBins_binary - 1));
180  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 5 |
181  BOOST_CHECK_EQUAL(xData_add.searchGlobal(xyzPosition), size_t(0));
182  BOOST_CHECK_EQUAL(xData_add.searchGlobal(xyzPosition), size_t(0));
183  BOOST_CHECK_EQUAL(xData_add.search(0.2), size_t(0));
184  BOOST_CHECK_EQUAL(xData_add.search(1.2), size_t(1));
185  BOOST_CHECK_EQUAL(xData_add.search(1.7), size_t(2));
186  BOOST_CHECK_EQUAL(xData_add.search(2.5), size_t(3));
187  BOOST_CHECK_EQUAL(xData_add.search(3.5), size_t(4));
188  BOOST_CHECK_EQUAL(xData_add.search(4.2), size_t(5));
189  BOOST_CHECK_EQUAL(xData_add.search(7.), size_t(5));
190  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 4.5 | 5 | 6 | 7 | 7.5 | 8 | 9 |
191  BOOST_CHECK_EQUAL(xData_mult.searchGlobal(xyzPosition), size_t(0));
192  BOOST_CHECK_EQUAL(xData_mult.search(0.2), size_t(0));
193  BOOST_CHECK_EQUAL(xData_mult.search(1.2), size_t(1));
194  BOOST_CHECK_EQUAL(xData_mult.search(1.7), size_t(2));
195  BOOST_CHECK_EQUAL(xData_mult.search(2.5), size_t(3));
196  BOOST_CHECK_EQUAL(xData_mult.search(3.5), size_t(4));
197  BOOST_CHECK_EQUAL(xData_mult.search(4.2), size_t(5));
198  BOOST_CHECK_EQUAL(xData_mult.search(4.7), size_t(6));
199  BOOST_CHECK_EQUAL(xData_mult.search(5.7), size_t(7));
200  BOOST_CHECK_EQUAL(xData_mult.search(6.5), size_t(8));
201  BOOST_CHECK_EQUAL(xData_mult.search(7.2), size_t(9));
202  BOOST_CHECK_EQUAL(xData_mult.search(7.7), size_t(10));
203  BOOST_CHECK_EQUAL(xData_mult.search(8.1), size_t(11));
204 
206  BOOST_CHECK_EQUAL(xData_eq.searchLocal(xyPosition), size_t(0));
207  BOOST_CHECK_EQUAL(yData_eq.searchLocal(xyPosition), size_t(1));
208  BOOST_CHECK_EQUAL(zData_eq.searchLocal(rphizPosition), size_t(2));
209  BOOST_CHECK_EQUAL(xData_arb.searchLocal(xyPosition), size_t(0));
210  BOOST_CHECK_EQUAL(xData_arb_binary.searchLocal(xyPosition), size_t(0));
211 
212  // r/phi/rphiData
213  BOOST_CHECK_EQUAL(rData_eq.searchGlobal(xyzPosition), size_t(1));
214  BOOST_CHECK_EQUAL(rData_eq.searchLocal(rphiPosition), size_t(3));
215  BOOST_CHECK_EQUAL(phiData_eq.searchGlobal(phi0Position), size_t(2));
216  BOOST_CHECK_EQUAL(phiData_eq.searchGlobal(phiPihPosition), size_t(3));
217  BOOST_CHECK_EQUAL(phiData_arb_binary.search(M_PI), size_t(0));
218 
219  // h/etaData
220  BOOST_CHECK_EQUAL(etaData_eq.searchGlobal(eta0Position), size_t(2));
221 }
222 
223 // test inside/outside
224 BOOST_AUTO_TEST_CASE(BinningData_inside_outside) {
225  // the binnings - arbitrary when switching to binary search - for boundary
226  // sizes >= 50
227  std::vector<float> values_binary;
228  std::vector<float> phiValues_binary;
229  for (size_t i = 0; i <= nBins_binary; i++) {
230  values_binary.push_back(valueMin + i * delta);
231  phiValues_binary.push_back(phiMin + i * phiDelta);
232  }
233  // bin boundaries when switching to binary search - for boundary sizes >= 50
234  BinningData xData_arb_binary(open, binX, values_binary);
235  BinningData phiData_arb_binary(closed, binPhi, phiValues_binary);
236  // check the global inside
237  BOOST_CHECK_EQUAL(xData_eq.inside(xyzPosition), true);
238  BOOST_CHECK_EQUAL(yData_eq.inside(xyzPosition), true);
239  BOOST_CHECK_EQUAL(zData_eq.inside(xyzPosition), true);
240  BOOST_CHECK_EQUAL(xData_arb.inside(xyzPosition), true);
241  BOOST_CHECK_EQUAL(xData_add.inside(xyzPosition), true);
242  BOOST_CHECK_EQUAL(xData_mult.inside(xyzPosition), true);
243  BOOST_CHECK_EQUAL(xData_arb_binary.inside(xyzPosition), true);
244 
245  // check the global outside
246  BOOST_CHECK_EQUAL(xData_eq.inside(xyzPositionOutside), false);
247  BOOST_CHECK_EQUAL(yData_eq.inside(xyzPositionOutside), false);
248  BOOST_CHECK_EQUAL(zData_eq.inside(xyzPositionOutside), false);
249  BOOST_CHECK_EQUAL(xData_arb.inside(xyzPositionOutside), false);
250  BOOST_CHECK_EQUAL(xData_add.inside(xyzPositionOutside), false);
251  BOOST_CHECK_EQUAL(xData_mult.inside(xyzPositionOutside), false);
252  BOOST_CHECK_EQUAL(xData_arb_binary.inside(xyzPositionOutside), false);
253 
254  // cthe local inside
255  BOOST_CHECK_EQUAL(xData_eq.inside(xyPosition), true);
256  BOOST_CHECK_EQUAL(yData_eq.inside(xyPosition), true);
257  BOOST_CHECK_EQUAL(zData_eq.inside(rphizPosition), true);
258 
259  // r/phi/rphiData inside
260  BOOST_CHECK_EQUAL(phiData_eq.inside(phi0Position), true);
261  BOOST_CHECK_EQUAL(phiData_eq.inside(phiPihPosition), true);
263  BOOST_CHECK_EQUAL(etaData_eq.inside(eta0Position), true);
264 }
265 
266 // test open/close
267 BOOST_AUTO_TEST_CASE(BinningData_open_close) {
268  // the binnings - arbitrary when switching to binary search - for boundary
269  // sizes >= 50
270  std::vector<float> values_binary;
271  std::vector<float> phiValues_binary;
272  for (size_t i = 0; i <= nBins_binary; i++) {
273  values_binary.push_back(valueMin + i * delta);
274  phiValues_binary.push_back(phiMin + i * phiDelta);
275  }
276  // bin boundaries when switching to binary search - for boundary sizes >= 50
277  BinningData xData_arb_binary(open, binX, values_binary);
278  BinningData phiData_arb_binary(closed, binPhi, phiValues_binary);
279  // open values
280  BOOST_CHECK_EQUAL(xData_eq.searchGlobal(xyzPositionOutside), size_t(9));
281  BOOST_CHECK_EQUAL(yData_eq.searchGlobal(xyzPositionOutside), size_t(0));
282  BOOST_CHECK_EQUAL(zData_eq.searchGlobal(xyzPositionOutside), size_t(9));
283  BOOST_CHECK_EQUAL(xData_arb.searchGlobal(xyzPositionOutside) + 1,
284  xData_arb.bins());
285  BOOST_CHECK_EQUAL(xData_arb_binary.searchGlobal(xyzPositionOutside) + 1,
286  xData_arb_binary.bins());
287  BOOST_CHECK_EQUAL(yData_arb.searchGlobal(xyzPositionOutside), size_t(0));
288 
289  // closed values
290  BOOST_CHECK_EQUAL(phiData_eq.search(-4.), size_t(4));
291  BOOST_CHECK_EQUAL(phiData_eq.search(4.), size_t(0));
292  BOOST_CHECK_EQUAL(phiData_arb.search(-4.), size_t(4));
293  BOOST_CHECK_EQUAL(phiData_arb.search(4.), size_t(0));
294  BOOST_CHECK_EQUAL(phiData_arb_binary.search(-4.), (nBins_binary - 1));
295  BOOST_CHECK_EQUAL(phiData_arb_binary.search(4.), size_t(0));
296 }
297 
298 // test boundaries
299 BOOST_AUTO_TEST_CASE(BinningData_boundaries) {
300  // open values
301  std::vector<float> boundaries = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
302  BOOST_CHECK_EQUAL_COLLECTIONS(xData_eq.boundaries().begin(),
303  xData_eq.boundaries().end(), boundaries.begin(),
304  boundaries.end());
305 
306  float phiStep = M_PI * 2. / 5.;
307  std::vector<float> phiBoundaries_eq = {-M_PI,
308  float(-M_PI + 1 * phiStep),
309  float(-M_PI + 2 * phiStep),
310  float(-M_PI + 3 * phiStep),
311  float(-M_PI + 4 * phiStep),
312  float(-M_PI + 5 * phiStep)};
313  CHECK_CLOSE_REL(phiData_eq.boundaries(), phiBoundaries_eq, 1e-5);
314 }
315 
316 // test bin center values
317 // test boundaries
318 BOOST_AUTO_TEST_CASE(BinningData_bincenter) {
319  // the binnings - arbitrary when switching to binary search - for boundary
320  // sizes >= 50
321  std::vector<float> values_binary;
322  std::vector<float> phiValues_binary;
323  for (size_t i = 0; i <= nBins_binary; i++) {
324  values_binary.push_back(valueMin + i * delta);
325  phiValues_binary.push_back(phiMin + i * phiDelta);
326  }
327  // bin boundaries when switching to binary search - for boundary sizes >= 50
328  BinningData xData_arb_binary(open, binX, values_binary);
329  BinningData phiData_arb_binary(closed, binPhi, phiValues_binary);
331  // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
332  BOOST_CHECK_EQUAL(xData_eq.center(3), 3.5);
333  // | 0 | 1 | 2 | 3 | 4 | 10 |
334  BOOST_CHECK_EQUAL(xData_arb.center(4), 7.);
335  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 5 |
336  BOOST_CHECK_EQUAL(xData_add.center(0), 0.5);
337  BOOST_CHECK_EQUAL(xData_add.center(1), 1.25);
338  BOOST_CHECK_EQUAL(xData_add.center(4), 3.5);
339  // | 0 | 1 | 1.5 | 2 | 3 | 4 | 4.5 | 5 | 6 | 7 | 7.5 | 8 | 9 |
340  BOOST_CHECK_EQUAL(xData_mult.center(0), 0.5);
341  BOOST_CHECK_EQUAL(xData_mult.center(1), 1.25);
342  BOOST_CHECK_EQUAL(xData_mult.center(4), 3.5);
343  BOOST_CHECK_EQUAL(xData_mult.center(10), 7.75);
344  BOOST_CHECK_EQUAL(xData_mult.center(11), 8.5);
345 
346  BOOST_CHECK_EQUAL(xData_arb_binary.center(0), 0.5 * delta);
347 
348  // open values
349  std::vector<float> center = {0.5, 1.5, 2.5, 3.5, 4.5,
350  5.5, 6.5, 7.5, 8.5, 9.5};
351  for (size_t ib = 0; ib < center.size(); ++ib) {
352  BOOST_CHECK_EQUAL(xData_eq.center(ib), center[ib]);
353  }
354 
355  // running into rounding errors here
356  float phiStep = M_PI * 2. / 5.;
357  std::vector<float> phiCenters_eq = {
358  float(-M_PI + 0.5 * phiStep), float(-M_PI + 1.5 * phiStep),
359  float(-M_PI + 2.5 * phiStep), float(-M_PI + 3.5 * phiStep),
360  float(-M_PI + 4.5 * phiStep)};
361 
362  for (size_t ib = 0; ib < phiCenters_eq.size(); ++ib) {
363  CHECK_CLOSE_ABS(phiData_eq.center(ib), phiCenters_eq[ib], 1e-3);
364  }
365 }
366 
367 // special test for phi binning
368 BOOST_AUTO_TEST_CASE(BinningData_phi_modules) {
369  // n phi modules with phi boundary at -M_Pi/+M_PI are checked above
370  // one module expands over -M_Pi/+M_PI
371  float deltaPhi = 0.1;
372  BinningData phiData_mod(closed, binPhi, 5, -M_PI + deltaPhi, M_PI + deltaPhi);
373  float phiStep = M_PI * 2. / 5.;
374  std::vector<float> phiBoundaries_mod = {
375  float(-M_PI + deltaPhi),
376  float(-M_PI + 1 * phiStep) + deltaPhi,
377  float(-M_PI + 2 * phiStep) + deltaPhi,
378  float(-M_PI + 3 * phiStep) + deltaPhi,
379  float(-M_PI + 4 * phiStep) + deltaPhi,
380  float(-M_PI + 5 * phiStep) + deltaPhi};
381  // this is the boundary test
382  CHECK_CLOSE_REL(phiData_mod.boundaries(), phiBoundaries_mod, 1e-5);
383 
384  // now test the bin jump 0/maxbin
385 
386  float firstAngle = (-M_PI + 1.5 * deltaPhi);
387  Vector3 firstBin(cos(firstAngle), sin(firstAngle), 0.);
388  BOOST_CHECK_EQUAL(phiData_mod.search(firstAngle), size_t(0));
389  BOOST_CHECK_EQUAL(phiData_mod.searchGlobal(firstBin), size_t(0));
390 
391  float firstAngleNeg = (-M_PI + 0.5 * deltaPhi);
392  Vector3 lastBinNeg(cos(firstAngleNeg), sin(firstAngleNeg), 0.);
393  BOOST_CHECK_EQUAL(phiData_mod.search(firstAngleNeg), size_t(4));
394  BOOST_CHECK_EQUAL(phiData_mod.searchGlobal(lastBinNeg), size_t(4));
395 
396  float lastAnglePos = (M_PI + 0.5 * deltaPhi);
397  Vector3 lastBinPos(cos(lastAnglePos), sin(lastAnglePos), 0.);
398  BOOST_CHECK_EQUAL(phiData_mod.search(lastAnglePos), size_t(4));
399  BOOST_CHECK_EQUAL(phiData_mod.searchGlobal(lastBinPos), size_t(4));
400 
401  // now test the (remaining) phi scaling
402  float underscaledAngle = -M_PI - 0.5 * deltaPhi;
403  Vector3 underscaledPos(cos(underscaledAngle), sin(underscaledAngle), 0.);
404  BOOST_CHECK_EQUAL(phiData_mod.search(underscaledAngle), size_t(4));
405  BOOST_CHECK_EQUAL(phiData_mod.searchGlobal(underscaledPos), size_t(4));
406 }
407 
408 } // namespace Test
409 } // namespace Acts