EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GeometryHierarchyMapTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GeometryHierarchyMapTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 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 
12 
13 #include <iterator>
14 #include <stdexcept>
15 
16 namespace {
17 
19 
20 // helper function to create geometry ids
21 GeometryIdentifier makeId(int volume = 0, int layer = 0, int sensitive = 0) {
22  return GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive(
23  sensitive);
24 }
25 
26 // example value type stored in the geometry hierarchy map
27 struct Thing {
28  double value = 1.0;
29 };
30 
31 using Container = Acts::GeometryHierarchyMap<Thing>;
32 
33 } // namespace
34 
35 // check that an entry exists for the query and compare the id
36 #define CHECK_ENTRY(container, query, compare) \
37  do { \
38  auto ret = container.find(query); \
39  BOOST_CHECK_NE(ret, container.end()); \
40  if (ret != container.end()) { \
41  auto idx = std::distance(container.begin(), ret); \
42  BOOST_CHECK_EQUAL(container.idAt(idx), compare); \
43  } \
44  } while (false)
45 
46 BOOST_TEST_DONT_PRINT_LOG_VALUE(Container::Iterator)
47 BOOST_TEST_DONT_PRINT_LOG_VALUE(Thing)
48 
49 BOOST_AUTO_TEST_SUITE(GeometryHierarchyMap)
50 
51 BOOST_AUTO_TEST_CASE(ConstructDefault) {
52  Container c;
53  BOOST_CHECK_EQUAL(c.begin(), c.end());
54  BOOST_CHECK(c.empty());
55  BOOST_CHECK_EQUAL(c.size(), 0u);
56 }
57 
58 BOOST_AUTO_TEST_CASE(ConstructNonUnique) {
59  std::vector<std::pair<GeometryIdentifier, Thing>> entries = {
60  {makeId(2, 4, 6), {1.0}},
61  {makeId(3, 5), {1.0}},
62  {makeId(3), {1.0}},
63  // duplicate identifier
64  {makeId(2, 4, 6), {2.0}},
65  };
66  BOOST_CHECK_THROW(Container(std::move(entries)), std::invalid_argument);
67 
68  std::vector<std::pair<GeometryIdentifier, Thing>> defaults = {
69  {makeId(), {1.0}},
70  // duplicate global default
71  {makeId(), {2.0}},
72  };
73  BOOST_CHECK_THROW(Container(std::move(defaults)), std::invalid_argument);
74 }
75 
76 BOOST_AUTO_TEST_CASE(ConstructInitializerList) {
77  Container c = {
78  {makeId(0, 1, 2), {1.0}},
79  {makeId(3, 4), {3.0}},
80  {makeId(2), {2.0}},
81  {makeId(), {23.0}},
82  };
83  BOOST_CHECK_EQUAL(std::next(c.begin(), 4), c.end());
84  BOOST_CHECK(not c.empty());
85  BOOST_CHECK_EQUAL(c.size(), 4u);
86  // only test that all elements are there; failure test are below
87  CHECK_ENTRY(c, makeId(0, 1, 2), makeId(0, 1, 2));
88  CHECK_ENTRY(c, makeId(2), makeId(2));
89  CHECK_ENTRY(c, makeId(3, 4), makeId(3, 4));
90 }
91 
92 BOOST_AUTO_TEST_CASE(IndexBasedAccess) {
93  Container c({
94  {makeId(1, 2, 3), {2.0}},
95  {makeId(3, 4, 5), {2.5}},
96  {makeId(3, 5), {3.0}},
97  {makeId(4, 5, 7), {4.0}},
98  });
99 
100  BOOST_CHECK(not c.empty());
101  BOOST_CHECK_EQUAL(c.size(), 4u);
102  // this tests just that the index-based access works
103  // NOTE order is undefined and should not be tested
104  for (auto i = c.size(); 0 < i--;) {
105  // just check that the id is valid
106  BOOST_CHECK_NE(c.idAt(i), GeometryIdentifier());
107  // check that something is actually stored by comparing with the default
108  BOOST_CHECK_NE(c.valueAt(i).value, Thing().value);
109  }
110  // test that invalid inputs actually fail
111  BOOST_CHECK_THROW(c.idAt(c.size()), std::out_of_range);
112  BOOST_CHECK_THROW(c.valueAt(c.size()), std::out_of_range);
113 }
114 
116  Container c = {
117  // entry for volume 2, layer 4, sensitive 6
118  {makeId(2, 4, 6), {-23.0}},
119  // entry for volume 2, layer 8
120  {makeId(2, 8), {5.0}},
121  // entry for the whole volume 2
122  {makeId(2), {1.0}},
123  // entry for volume 12, layer 16
124  // NOTE no entry for the volume as a whole
125  {makeId(12, 16), {-1.0}},
126  };
127 
128  // basic checks
129  BOOST_CHECK_EQUAL(std::next(c.begin(), 4u), c.end());
130  BOOST_CHECK(not c.empty());
131  BOOST_CHECK_EQUAL(c.size(), 4u);
132 
133  // find existing sensitive
134  CHECK_ENTRY(c, makeId(2, 4, 6), makeId(2, 4, 6));
135  // find existing layer
136  CHECK_ENTRY(c, makeId(2, 8), makeId(2, 8));
137  // find existing volume
138  CHECK_ENTRY(c, makeId(2), makeId(2));
139  // find existing layer
140  CHECK_ENTRY(c, makeId(12, 16), makeId(12, 16));
141 
142  // find non-existing sensitive, which has a set volume
143  CHECK_ENTRY(c, makeId(2, 4, 7), makeId(2));
144  // find non-existing layer id, which has a set volume
145  CHECK_ENTRY(c, makeId(2, 13), makeId(2));
146  // find non-existing sensitive id, which has a set layer
147  CHECK_ENTRY(c, makeId(2, 8, 13), makeId(2, 8));
148  // find non-existing sensitive, which has a set layer
149  CHECK_ENTRY(c, makeId(12, 16, 20), makeId(12, 16));
150 
151  // find non-existing sensitive, which has no higher hierarchy set
152  BOOST_CHECK_EQUAL(c.find(makeId(3, 5, 7)), c.end());
153  // find non-existing layer, which has no higher hierarchy set
154  BOOST_CHECK_EQUAL(c.find(makeId(3, 5)), c.end());
155  // find non-existing volume
156  BOOST_CHECK_EQUAL(c.find(makeId(3)), c.end());
157  // find non-existing volume, which has only lower hierarchy elements
158  BOOST_CHECK_EQUAL(c.find(makeId(12)), c.end());
159 }
160 
161 BOOST_AUTO_TEST_CASE(FindWithGlobalDefault) {
162  Container c = {
163  // global default entry
164  {makeId(), {1.0}},
165  // entry for volume 2, layer 3
166  {makeId(2, 3), {2.0}},
167  // entry for volume 4
168  {makeId(4), {4.0}},
169  };
170 
171  // basic checks
172  BOOST_CHECK_EQUAL(std::next(c.begin(), 3u), c.end());
173  BOOST_CHECK(not c.empty());
174  BOOST_CHECK_EQUAL(c.size(), 3u);
175 
176  // find existing entries
177  CHECK_ENTRY(c, makeId(), makeId());
178  CHECK_ENTRY(c, makeId(2, 3), makeId(2, 3));
179  CHECK_ENTRY(c, makeId(4), makeId(4));
180 
181  // find missing sensitive w/ set layer
182  CHECK_ENTRY(c, makeId(2, 3, 4), makeId(2, 3));
183  // find missing layer w/ set volume
184  CHECK_ENTRY(c, makeId(4, 5), makeId(4));
185 
186  // find missing sensitive w/o set volume/layer -> global default
187  CHECK_ENTRY(c, makeId(2, 4, 5), makeId());
188  // find missing layer w/o set volume -> global default
189  CHECK_ENTRY(c, makeId(2, 4), makeId());
190  // find missing volume
191  CHECK_ENTRY(c, makeId(5), makeId());
192 }
193 
194 BOOST_AUTO_TEST_SUITE_END()