Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DetectorVolumeBuilderTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DetectorVolumeBuilderTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022 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 
28 
29 #include <memory>
30 #include <stdexcept>
31 #include <string>
32 #include <utility>
33 #include <vector>
34 
35 using namespace Acts;
36 using namespace Acts::Experimental;
37 
39 
42 template <typename bounds_type>
44  public:
45  ExternalsBuilder(const Transform3& transform, const bounds_type& bounds)
47  m_transform(transform),
48  m_bounds(std::move(bounds)) {}
49 
50  ExternalStructure construct(
51  [[maybe_unused]] const GeometryContext& gctx) const final {
52  return {m_transform, std::make_unique<bounds_type>(m_bounds),
54  }
55 
56  private:
57  Transform3 m_transform = Transform3::Identity();
58  bounds_type m_bounds;
59 };
60 
64 template <typename surface_type, typename bounds_type>
66  public:
67  InternalSurfaceBuilder(const Transform3& transform, const bounds_type& bounds)
69  m_transform(transform),
70  m_bounds(std::move(bounds)) {}
71 
72  InternalStructure construct(
73  [[maybe_unused]] const GeometryContext& gctx) const final {
74  auto surface = Surface::makeShared<surface_type>(
75  m_transform, std::make_shared<bounds_type>(m_bounds));
76  return {{surface}, {}, tryAllPortalsAndSurfaces(), tryNoVolumes()};
77  }
78 
79  private:
80  Transform3 m_transform = Transform3::Identity();
81  bounds_type m_bounds;
82 };
83 
85  public:
87  const final {
88  return std::any();
89  }
90 
91  void assignGeometryId(
93  Acts::Experimental::DetectorVolume& dVolume) const final {
94  for (auto [is, s] : Acts::enumerate(dVolume.surfacePtrs())) {
96  geoID.setPassive(is + 1);
97  s->assignGeometryId(geoID);
98  }
99  }
100 
101  void assignGeometryId(
103  Acts::Experimental::Portal& /*portal*/) const final {}
104 
105  void assignGeometryId(
107  Acts::Surface& /*surface*/) const final {}
108 };
109 
113 template <typename bounds_type>
115  public:
116  InternalVolumeBuilder(const Transform3& transform, const bounds_type& bounds)
118  m_transform(transform),
119  m_bounds(std::move(bounds)) {}
120 
121  InternalStructure construct(
122  [[maybe_unused]] const GeometryContext& gctx) const final {
123  auto bounds = std::make_unique<bounds_type>(m_bounds);
125  auto volume = DetectorVolumeFactory::construct(
126  portalGenerator, tContext, "InternalVolume", m_transform,
128  return {{}, {volume}, tryAllPortals(), tryRootVolumes()};
129  }
130 
131  private:
132  Transform3 m_transform = Transform3::Identity();
133  bounds_type m_bounds;
134 };
135 
136 BOOST_AUTO_TEST_SUITE(Detector)
137 
138 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_Misconfigured) {
139  // Internal and external structure builder is empty
141  dvCfg.auxiliary = "*** Test X * Misconfigued ***";
142  dvCfg.name = "EmptyCylinder";
143  dvCfg.externalsBuilder = nullptr;
144  dvCfg.internalsBuilder = nullptr;
145 
146  BOOST_CHECK_THROW(auto a = DetectorVolumeBuilder(dvCfg),
147  std::invalid_argument);
148 }
149 
150 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_EmptyVolume) {
151  CylinderVolumeBounds cBounds(10, 100, 200);
152  auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
153  Transform3::Identity(), cBounds);
154 
156  dvCfg.auxiliary = "*** Test 0 - Empty Cylinder ***";
157  dvCfg.name = "EmptyCylinder";
158  dvCfg.externalsBuilder = cBuilder;
159  dvCfg.internalsBuilder = nullptr;
160 
161  auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
162  dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
163 
164  auto [volumes, portals, roots] = dvBuilder->construct(tContext);
165 
166  BOOST_CHECK(volumes.size() == 1u);
167  BOOST_CHECK(volumes.front()->surfaces().empty());
168  BOOST_CHECK(volumes.front()->volumes().empty());
169 
170  BOOST_CHECK(portals.size() == 4u);
171 
172  BOOST_CHECK(roots.volumes.size() == 1u);
173  BOOST_CHECK(roots.volumeFinder.connected());
174 }
175 
176 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithSurface) {
177  CylinderVolumeBounds cvBounds(10, 100, 200);
178  auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
179  Transform3::Identity(), cvBounds);
180 
181  CylinderBounds csBounds(55., 195.);
182  auto sBuilder =
183  std::make_shared<InternalSurfaceBuilder<CylinderSurface, CylinderBounds>>(
184  Transform3::Identity(), csBounds);
185 
187  dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
188  dvCfg.name = "CylinderWithSurface";
189  dvCfg.externalsBuilder = cBuilder;
190  dvCfg.internalsBuilder = sBuilder;
191  dvCfg.geoIdGenerator = std::make_shared<SurfaceGeoIdGenerator>();
192 
193  auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
194  dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
195 
196  auto [volumes, portals, roots] = dvBuilder->construct(tContext);
197 
198  BOOST_CHECK(volumes.size() == 1u);
199  BOOST_CHECK(volumes.front()->surfaces().size() == 1u);
200 
201  BOOST_CHECK(volumes.front()->surfaces().front()->geometryId().passive() ==
202  1u);
203  BOOST_CHECK(volumes.front()->volumes().empty());
204 
205  BOOST_CHECK(portals.size() == 4u);
206 
207  BOOST_CHECK(roots.volumes.size() == 1u);
208  BOOST_CHECK(roots.volumeFinder.connected());
209 }
210 
211 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithVolume) {
212  CylinderVolumeBounds cvBounds(10, 100, 200);
213  auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
214  Transform3::Identity(), cvBounds);
215 
216  CylinderVolumeBounds ciBounds(15., 95., 195.);
217  auto iBuilder = std::make_shared<InternalVolumeBuilder<CylinderVolumeBounds>>(
218  Transform3::Identity(), ciBounds);
219 
221  dvCfg.auxiliary = "*** Test 2 - Cylinder with internal Volume ***";
222  dvCfg.name = "CylinderWithVolume";
223  dvCfg.externalsBuilder = cBuilder;
224  dvCfg.internalsBuilder = iBuilder;
225  dvCfg.addInternalsToRoot = false;
226 
227  auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
228  dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
229 
230  auto [volumes, portals, roots] = dvBuilder->construct(tContext);
231 
232  BOOST_CHECK(volumes.size() == 1u);
233  BOOST_CHECK(portals.size() == 4u);
234  BOOST_CHECK(roots.volumes.size() == 1u);
235 }
236 
237 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithVolumeToRoot) {
238  CylinderVolumeBounds cvBounds(10, 100, 200);
239  auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
240  Transform3::Identity(), cvBounds);
241 
242  CylinderVolumeBounds ciBounds(15., 95., 195.);
243  auto iBuilder = std::make_shared<InternalVolumeBuilder<CylinderVolumeBounds>>(
244  Transform3::Identity(), ciBounds);
245 
247  dvCfg.auxiliary =
248  "*** Test 3 - Cylinder with internal Volume, adding to root ***";
249  dvCfg.name = "CylinderWithVolume";
250  dvCfg.externalsBuilder = cBuilder;
251  dvCfg.internalsBuilder = iBuilder;
252  dvCfg.addInternalsToRoot = true;
253 
254  auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
255  dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
256 
257  auto [volumes, portals, roots] = dvBuilder->construct(tContext);
258 
259  BOOST_CHECK(volumes.size() == 1u);
260  BOOST_CHECK(volumes.front()->surfaces().empty());
261  BOOST_CHECK(volumes.front()->volumes().size() == 1u);
262 
263  BOOST_CHECK(portals.size() == 4u);
264 
265  BOOST_CHECK(roots.volumes.size() == 2u);
266  BOOST_CHECK(roots.volumeFinder.connected());
267 }
268 
269 BOOST_AUTO_TEST_SUITE_END()