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