Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CuboidVolumeBuilderTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CuboidVolumeBuilderTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 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 
16 #include "Acts/Geometry/Layer.hpp"
29 
30 #include <cmath>
31 #include <functional>
32 #include <memory>
33 #include <string>
34 #include <vector>
35 
36 using namespace Acts::UnitLiterals;
37 
38 namespace Acts {
39 namespace Test {
40 
45  struct this_result {
46  // Position of the propagator after each step
47  std::vector<Vector3> position;
48  // Volume of the propagator after each step
49  std::vector<TrackingVolume const*> volume;
50  };
51 
53 
54  template <typename propagator_state_t, typename stepper_t,
55  typename navigator_t>
56  void operator()(propagator_state_t& state, const stepper_t& stepper,
57  const navigator_t& navigator, result_type& result) const {
58  result.position.push_back(stepper.position(state.stepping));
59  result.volume.push_back(navigator.currentVolume(state.navigation));
60  }
61 };
62 
63 BOOST_AUTO_TEST_CASE(CuboidVolumeBuilderTest) {
64  // Construct builder
66 
67  // Create a test context
69 
70  // Create configurations for surfaces
71  std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig;
72  for (unsigned int i = 1; i < 5; i++) {
73  // Position of the surfaces
75  cfg.position = {i * UnitConstants::m, 0., 0.};
76 
77  // Rotation of the surfaces
78  double rotationAngle = M_PI * 0.5;
79  Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
80  Vector3 yPos(0., 1., 0.);
81  Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
82  cfg.rotation.col(0) = xPos;
83  cfg.rotation.col(1) = yPos;
84  cfg.rotation.col(2) = zPos;
85 
86  // Boundaries of the surfaces
87  cfg.rBounds =
88  std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
89 
90  // Material of the surfaces
91  MaterialSlab matProp(makeBeryllium(), 0.5_mm);
92  cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
93 
94  // Thickness of the detector element
95  cfg.thickness = 1_um;
96 
98  [](const Transform3& trans,
99  const std::shared_ptr<const RectangleBounds>& bounds,
100  double thickness) {
101  return new DetectorElementStub(trans, bounds, thickness);
102  };
103  surfaceConfig.push_back(cfg);
104  }
105 
106  // Test that there are actually 4 surface configurations
107  BOOST_CHECK_EQUAL(surfaceConfig.size(), 4u);
108 
109  // Test that 4 surfaces can be built
110  for (const auto& cfg : surfaceConfig) {
111  std::shared_ptr<const Surface> pSur = cvb.buildSurface(tgContext, cfg);
112  BOOST_CHECK_NE(pSur, nullptr);
113  CHECK_CLOSE_ABS(pSur->center(tgContext), cfg.position, 1e-9);
114  BOOST_CHECK_NE(pSur->surfaceMaterial(), nullptr);
115  BOOST_CHECK_NE(pSur->associatedDetectorElement(), nullptr);
116  }
117 
119  // Build layer configurations
120  std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig;
121  for (auto& sCfg : surfaceConfig) {
123  cfg.surfaceCfg = {sCfg};
124  layerConfig.push_back(cfg);
125  }
126 
127  // Test that there are actually 4 layer configurations
128  BOOST_CHECK_EQUAL(layerConfig.size(), 4u);
129 
130  // Test that 4 layers with surfaces can be built
131  for (auto& cfg : layerConfig) {
132  LayerPtr layer = cvb.buildLayer(tgContext, cfg);
133  BOOST_CHECK_NE(layer, nullptr);
134  BOOST_CHECK(!cfg.surfaces.empty());
135  BOOST_CHECK_EQUAL(layer->surfaceArray()->surfaces().size(), 1u);
136  BOOST_CHECK_EQUAL(layer->layerType(), LayerType::active);
137  }
138 
139  for (auto& cfg : layerConfig) {
140  cfg.surfaces = {};
141  }
142 
143  // Build volume configuration
145  volumeConfig.position = {2.5_m, 0., 0.};
146  volumeConfig.length = {5_m, 1_m, 1_m};
147  volumeConfig.layerCfg = layerConfig;
148  volumeConfig.name = "Test volume";
149  volumeConfig.volumeMaterial =
150  std::make_shared<HomogeneousVolumeMaterial>(makeBeryllium());
151 
152  // Test the building
153  std::shared_ptr<TrackingVolume> trVol =
154  cvb.buildVolume(tgContext, volumeConfig);
155  BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
156  BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
157  volumeConfig.layers.size() * 2 +
158  1u); // #layers = navigation + material layers
159  BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
160  BOOST_CHECK_NE(trVol->volumeMaterial(), nullptr);
161 
162  // Test the building
163  volumeConfig.layers.clear();
164  trVol = cvb.buildVolume(tgContext, volumeConfig);
165  BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
166  BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
167  volumeConfig.layers.size() * 2 +
168  1u); // #layers = navigation + material layers
169  BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
170 
171  volumeConfig.layers.clear();
172  for (auto& lay : volumeConfig.layerCfg) {
173  lay.surfaces = {};
174  lay.active = true;
175  }
176  trVol = cvb.buildVolume(tgContext, volumeConfig);
177  BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
178  for (auto& lay : volumeConfig.layers) {
179  BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
180  }
181 
182  volumeConfig.layers.clear();
183  for (auto& lay : volumeConfig.layerCfg) {
184  lay.active = true;
185  }
186  trVol = cvb.buildVolume(tgContext, volumeConfig);
187  BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
188  for (auto& lay : volumeConfig.layers) {
189  BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
190  }
191 
193  // Build TrackingGeometry configuration
194 
195  // Build second volume
196  std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig2;
197  for (int i = 1; i < 5; i++) {
198  // Position of the surfaces
200  cfg.position = {-i * UnitConstants::m, 0., 0.};
201 
202  // Rotation of the surfaces
203  double rotationAngle = M_PI * 0.5;
204  Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
205  Vector3 yPos(0., 1., 0.);
206  Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
207  cfg.rotation.col(0) = xPos;
208  cfg.rotation.col(1) = yPos;
209  cfg.rotation.col(2) = zPos;
210 
211  // Boundaries of the surfaces
212  cfg.rBounds =
213  std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
214 
215  // Material of the surfaces
216  MaterialSlab matProp(makeBeryllium(), 0.5_mm);
217  cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
218 
219  // Thickness of the detector element
220  cfg.thickness = 1_um;
221  surfaceConfig2.push_back(cfg);
222  }
223 
224  std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig2;
225  for (auto& sCfg : surfaceConfig2) {
227  cfg.surfaceCfg = {sCfg};
228  layerConfig2.push_back(cfg);
229  }
230  CuboidVolumeBuilder::VolumeConfig volumeConfig2;
231  volumeConfig2.position = {-2.5_m, 0., 0.};
232  volumeConfig2.length = {5_m, 1_m, 1_m};
233  volumeConfig2.layerCfg = layerConfig2;
234  volumeConfig2.name = "Test volume2";
235 
237  config.position = {0., 0., 0.};
238  config.length = {10_m, 1_m, 1_m};
239  config.volumeCfg = {volumeConfig2, volumeConfig};
240 
241  cvb.setConfig(config);
243  tgbCfg.trackingVolumeBuilders.push_back(
244  [=](const auto& context, const auto& inner, const auto&) {
245  return cvb.trackingVolume(context, inner, nullptr);
246  });
247  TrackingGeometryBuilder tgb(tgbCfg);
248 
249  std::unique_ptr<const TrackingGeometry> detector =
250  tgb.trackingGeometry(tgContext);
251  BOOST_CHECK_EQUAL(
252  detector->lowestTrackingVolume(tgContext, Vector3(1., 0., 0.))
253  ->volumeName(),
254  volumeConfig.name);
255  BOOST_CHECK_EQUAL(
256  detector->lowestTrackingVolume(tgContext, Vector3(-1., 0., 0.))
257  ->volumeName(),
258  volumeConfig2.name);
259 }
260 
261 } // namespace Test
262 } // namespace Acts