Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IndexedSurfaceGridFillerTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file IndexedSurfaceGridFillerTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 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 
29 
30 #include <array>
31 #include <cmath>
32 #include <cstddef>
33 #include <memory>
34 #include <ostream>
35 #include <set>
36 #include <utility>
37 #include <vector>
38 
39 using namespace Acts;
40 using namespace Acts::detail;
41 using namespace Acts::Experimental;
42 using namespace Acts::Experimental::detail;
43 
46 
47 namespace {
48 
50 template <typename indexed_surface_grid>
51 std::size_t countBins(const indexed_surface_grid& isGrid) {
52  std::size_t nonEmptyBins = 0u;
53  for (std::size_t igb = 0u; igb < isGrid.grid.size(); ++igb) {
54  const auto& gb = isGrid.grid.at(igb);
55  if (not gb.empty()) {
56  ++nonEmptyBins;
57  }
58  }
59  return nonEmptyBins;
60 }
61 
62 } // namespace
63 
64 BOOST_AUTO_TEST_SUITE(Detector)
65 
66 BOOST_AUTO_TEST_CASE(BinSequence) {
68  ACTS_INFO("Testing bin sequence generators.");
69 
70  // Test standard bound local bin sequence
71  auto seq48e0b10B = binSequence({4u, 8u}, 0u, 10u, AxisBoundaryType::Bound);
72  std::vector<std::size_t> reference = {4u, 5u, 6u, 7u, 8u};
73  BOOST_CHECK(seq48e0b10B == reference);
74 
75  // Test bound local bin sequence with expansion 1u
76  auto seq48e1b10B = binSequence({4u, 8u}, 1u, 10u, AxisBoundaryType::Bound);
77  reference = {3u, 4u, 5u, 6u, 7u, 8u, 9u};
78  BOOST_CHECK(seq48e1b10B == reference);
79 
80  // Test bound local bin sequence with expansion 3u - clipped to max bin 10u
81  auto seq48e3b10B = binSequence({4u, 8u}, 3u, 10u, AxisBoundaryType::Bound);
82  reference = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u};
83  BOOST_CHECK(seq48e3b10B == reference);
84 
85  // Test open bin sequence with overflow filling
86  auto seq48e3b10O = binSequence({4u, 8u}, 3u, 10u, AxisBoundaryType::Open);
87  reference = {1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u};
88  BOOST_CHECK(seq48e3b10O == reference);
89 
90  // Test standard closed local bins
91  auto seq48e0b10C = binSequence({4u, 8u}, 0u, 20u, AxisBoundaryType::Closed);
92  reference = {4u, 5u, 6u, 7u, 8u};
93  BOOST_CHECK(seq48e0b10C == reference);
94 
95  // Test closed local bins with expansion
96  auto seq48e1b10C = binSequence({4u, 8u}, 1u, 20u, AxisBoundaryType::Closed);
97  reference = {3u, 4u, 5u, 6u, 7u, 8u, 9u};
98  BOOST_CHECK(seq48e1b10C == reference);
99 
100  // Test closed local bins with expansion over bin boundary
101  auto seq1029e1b20C =
102  binSequence({19u, 20u}, 1u, 20u, AxisBoundaryType::Closed);
103  reference = {1u, 18u, 19u, 20u};
104  BOOST_CHECK(seq1029e1b20C == reference);
105 
106  // Test closed local bins with bin boundary jump
107  auto seq218e0b20C = binSequence({2u, 18u}, 0u, 20u, AxisBoundaryType::Closed);
108  reference = {1u, 2u, 18u, 19u, 20u};
109  BOOST_CHECK(seq218e0b20C == reference);
110 
111  // Test closed local bins with bin boundary jump with extension
112  auto seq218e2b20C = binSequence({2u, 18u}, 2u, 20u, AxisBoundaryType::Closed);
113  reference = {1u, 2u, 3u, 4u, 16u, 17u, 18u, 19u, 20u};
114  BOOST_CHECK(seq218e2b20C == reference);
115 }
116 
117 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceCenter) {
119  ACTS_INFO("Testing X-Y grid.");
120  ACTS_INFO("Testing one surface with center generator, should lead to 1 bin.");
121 
122  // x-y Axes & Grid
125  Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
126  {axisX, axisY});
127 
128  // Indexed Surface grid
129  IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
130  {binX, binY});
131 
132  // Create a single surface in the center
133  auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
134  auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
135  std::move(rBounds));
136 
137  // The Filler instance and a center based generator
138  IndexedGridFiller filler{{}};
139  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::VERBOSE);
141  std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
142 
143  // Fill the surface
144  filler.fill(tContext, indexedGridXY, surfaces, generator);
145 
146  std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
147  // Check the correct number of filled bins
148  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
149  BOOST_CHECK(nonEmptyBins == 1u);
150 }
151 
152 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceBinValue) {
154  ACTS_INFO("Testing X-Y grid.");
155  ACTS_INFO(
156  "Testing one surface with bin value generator, should lead to 1 bin.");
157 
158  // x-y Axes & Grid
161  Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
162  {axisX, axisY});
163 
164  // Indexed Surface grid
165  IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
166  {binX, binY});
167 
168  // Create a single surface in the center
169  auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
170  auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
171  std::move(rBounds));
172 
173  // The Filler instance and a center based generator
174  IndexedGridFiller filler{{}};
175  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::VERBOSE);
176 
178  std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
179 
180  // Fill the surface
181  filler.fill(tContext, indexedGridXY, surfaces, generator);
182 
183  std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
184  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
185  BOOST_CHECK(nonEmptyBins == 1u);
186 }
187 
188 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedron) {
190  ACTS_INFO("Testing X-Y grid.");
191  ACTS_INFO(
192  "Testing one surface with polyhedron generator without expansion, should "
193  "lead to 5 unique bins, 25 total bins filled");
194 
195  // x-y Axes & Grid
198  Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
199  {axisX, axisY});
200 
201  // Indexed Surface grid
202  IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
203  {binX, binY});
204 
205  // Create a single surface in the center
206  auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
207  auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
208  std::move(rBounds));
209 
210  // The Filler instance and a center based generator
211  IndexedGridFiller filler{{0u, 0u}};
212  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
213 
215  std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
216 
217  // Fill the surface
218  filler.fill(tContext, indexedGridXY, surfaces, generator);
219 
220  std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
221  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
222  BOOST_CHECK(nonEmptyBins == 25u);
223 }
224 
225 BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedronBinExpansion) {
227  ACTS_INFO("Testing X-Y grid.");
228  ACTS_INFO(
229  "Testing one surface with polyhedron generator and expansion, should "
230  "lead to 5 unique bins, 49 total bins filled");
231 
232  // x-y Axes & Grid
235  Grid<std::vector<unsigned int>, decltype(axisX), decltype(axisY)> gridXY(
236  {axisX, axisY});
237 
238  // Indexed Surface grid
239  IndexedSurfacesImpl<decltype(gridXY)> indexedGridXY(std::move(gridXY),
240  {binX, binY});
241 
242  // Create a single surface in the center
243  auto rBounds = std::make_shared<RectangleBounds>(4., 4.);
244  auto pSurface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
245  std::move(rBounds));
246 
247  // The Filler instance and a center based generator
248  IndexedGridFiller filler{{1u, 1u}};
249  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
250 
252  std::vector<std::shared_ptr<Surface>> surfaces = {pSurface};
253 
254  // Fill the surface
255  filler.fill(tContext, indexedGridXY, surfaces, generator);
256 
257  std::size_t nonEmptyBins = countBins<decltype(indexedGridXY)>(indexedGridXY);
258  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
259  BOOST_CHECK(nonEmptyBins == 49u);
260 }
261 
262 BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfacePolyhedronBinExpansion) {
264  ACTS_INFO("Testing Phi-Z grid.");
265  ACTS_INFO(
266  "Testing one surface with polyhedron generator without expansion, should "
267  "lead to 5 unique bins, 6 total bins filled");
268 
269  // z-phi Axes & Grid
272  36);
273  Grid<std::vector<unsigned int>, decltype(axisZ), decltype(axisPhi)> gridZPhi(
274  {axisZ, axisPhi});
275 
276  // Indexed Surface grid
277  IndexedSurfacesImpl<decltype(gridZPhi)> indexedGridZPhi(std::move(gridZPhi),
278  {binZ, binPhi});
279 
280  auto cBounds = std::make_shared<CylinderBounds>(10, 2., M_PI / 30, 0.);
281  auto cSurface = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
282  std::move(cBounds));
283 
284  // The Filler instance and a center based generator
285  IndexedGridFiller filler{{0u, 0u}};
286  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
287 
289  std::vector<std::shared_ptr<Surface>> surfaces = {cSurface};
290 
291  // Fill the surface
292  filler.fill(tContext, indexedGridZPhi, surfaces, generator);
293 
294  std::size_t nonEmptyBins =
295  countBins<decltype(indexedGridZPhi)>(indexedGridZPhi);
296  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
297  BOOST_CHECK(nonEmptyBins == 6u);
298 }
299 
300 BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfaceMPIPolyhedronBinExpansion) {
302  ACTS_INFO("Testing Phi-Z grid.");
303  ACTS_INFO("Testing one surface at M_PI jump, with polyhedron generator");
304 
305  // z-phi Axes & Grid
308  36);
309  Grid<std::vector<unsigned int>, decltype(axisZ), decltype(axisPhi)> gridZPhi(
310  {axisZ, axisPhi});
311 
312  // Indexed Surface grid
313  IndexedSurfacesImpl<decltype(gridZPhi)> indexedGridZPhi(std::move(gridZPhi),
314  {binZ, binPhi});
315 
316  auto cBounds = std::make_shared<CylinderBounds>(10, 2., M_PI / 10, 0.);
317  auto tf = AngleAxis3(M_PI, Vector3::UnitZ()) * Transform3::Identity();
318  auto cSurface = Surface::makeShared<CylinderSurface>(tf, std::move(cBounds));
319 
320  // The Filler instance and a center based generator
321  IndexedGridFiller filler{{0u, 0u}};
322  filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::DEBUG);
323 
325  std::vector<std::shared_ptr<Surface>> surfaces = {cSurface};
326 
327  // Fill the surface
328  filler.fill(tContext, indexedGridZPhi, surfaces, generator);
329 
330  std::size_t nonEmptyBins =
331  countBins<decltype(indexedGridZPhi)>(indexedGridZPhi);
332  ACTS_INFO("- filled " << nonEmptyBins << " bins of the grid.");
333  BOOST_CHECK(nonEmptyBins == 9u);
334 }
335 
336 BOOST_AUTO_TEST_SUITE_END()