File indexing completed on 2025-10-14 08:02:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/ITrackingVolumeHelper.hpp"
0016 #include "Acts/Geometry/Layer.hpp"
0017 #include "Acts/Geometry/TrackingGeometry.hpp"
0018 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0019 #include "Acts/Geometry/TrackingVolume.hpp"
0020 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0021 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0022 #include "Acts/Material/MaterialSlab.hpp"
0023 #include "Acts/Surfaces/RectangleBounds.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Surfaces/SurfaceArray.hpp"
0026 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0027 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0028 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0029
0030 #include <cmath>
0031 #include <functional>
0032 #include <memory>
0033 #include <numbers>
0034 #include <string>
0035 #include <vector>
0036
0037 using namespace Acts;
0038 using namespace Acts::UnitLiterals;
0039
0040 namespace ActsTests {
0041
0042 BOOST_AUTO_TEST_CASE(CuboidVolumeBuilderTest) {
0043
0044 CuboidVolumeBuilder cvb;
0045
0046
0047 GeometryContext tgContext = GeometryContext();
0048
0049
0050 std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig;
0051 for (unsigned int i = 1; i < 5; i++) {
0052
0053 CuboidVolumeBuilder::SurfaceConfig cfg;
0054 cfg.position = {i * UnitConstants::m, 0., 0.};
0055
0056
0057 double rotationAngle = std::numbers::pi / 2.;
0058 Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0059 Vector3 yPos(0., 1., 0.);
0060 Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0061 cfg.rotation.col(0) = xPos;
0062 cfg.rotation.col(1) = yPos;
0063 cfg.rotation.col(2) = zPos;
0064
0065
0066 cfg.rBounds =
0067 std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
0068
0069
0070 MaterialSlab matProp(makeBeryllium(), 0.5_mm);
0071 cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0072
0073
0074 cfg.thickness = 1_um;
0075
0076 cfg.detElementConstructor =
0077 [](const Transform3& trans,
0078 const std::shared_ptr<const RectangleBounds>& bounds,
0079 double thickness) {
0080 return new DetectorElementStub(trans, bounds, thickness);
0081 };
0082 surfaceConfig.push_back(cfg);
0083 }
0084
0085
0086 BOOST_CHECK_EQUAL(surfaceConfig.size(), 4u);
0087
0088
0089 for (const auto& cfg : surfaceConfig) {
0090 std::shared_ptr<const Surface> pSur = cvb.buildSurface(tgContext, cfg);
0091 BOOST_REQUIRE_NE(pSur, nullptr);
0092 CHECK_CLOSE_ABS(pSur->center(tgContext), cfg.position, 1e-9);
0093 BOOST_CHECK_NE(pSur->surfaceMaterial(), nullptr);
0094 BOOST_CHECK_NE(pSur->associatedDetectorElement(), nullptr);
0095 }
0096
0097
0098
0099 std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig;
0100 for (auto& sCfg : surfaceConfig) {
0101 CuboidVolumeBuilder::LayerConfig cfg;
0102 cfg.surfaceCfg = {sCfg};
0103 layerConfig.push_back(cfg);
0104 }
0105
0106
0107 BOOST_CHECK_EQUAL(layerConfig.size(), 4u);
0108
0109
0110 for (auto& cfg : layerConfig) {
0111 LayerPtr layer = cvb.buildLayer(tgContext, cfg);
0112 BOOST_REQUIRE_NE(layer, nullptr);
0113 BOOST_CHECK(!cfg.surfaces.empty());
0114 BOOST_CHECK_EQUAL(layer->surfaceArray()->surfaces().size(), 1u);
0115 BOOST_CHECK_EQUAL(layer->layerType(), LayerType::active);
0116 }
0117
0118 for (auto& cfg : layerConfig) {
0119 cfg.surfaces = {};
0120 }
0121
0122
0123 CuboidVolumeBuilder::VolumeConfig volumeConfig;
0124 volumeConfig.position = {2.5_m, 0., 0.};
0125 volumeConfig.length = {5_m, 1_m, 1_m};
0126 volumeConfig.layerCfg = layerConfig;
0127 volumeConfig.name = "Test volume";
0128 volumeConfig.volumeMaterial =
0129 std::make_shared<HomogeneousVolumeMaterial>(makeBeryllium());
0130
0131
0132 std::shared_ptr<TrackingVolume> trVol =
0133 cvb.buildVolume(tgContext, volumeConfig);
0134 BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0135 BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
0136 volumeConfig.layers.size() * 2 +
0137 1u);
0138 BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
0139 BOOST_CHECK_NE(trVol->volumeMaterial(), nullptr);
0140
0141
0142 volumeConfig.layers.clear();
0143 trVol = cvb.buildVolume(tgContext, volumeConfig);
0144 BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0145 BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
0146 volumeConfig.layers.size() * 2 +
0147 1u);
0148 BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
0149
0150 volumeConfig.layers.clear();
0151 for (auto& lay : volumeConfig.layerCfg) {
0152 lay.surfaces = {};
0153 lay.active = true;
0154 }
0155 trVol = cvb.buildVolume(tgContext, volumeConfig);
0156 BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0157 for (auto& lay : volumeConfig.layers) {
0158 BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
0159 }
0160
0161 volumeConfig.layers.clear();
0162 for (auto& lay : volumeConfig.layerCfg) {
0163 lay.active = true;
0164 }
0165 trVol = cvb.buildVolume(tgContext, volumeConfig);
0166 BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0167 for (auto& lay : volumeConfig.layers) {
0168 BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
0169 }
0170
0171
0172
0173
0174
0175 std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig2;
0176 for (int i = 1; i < 5; i++) {
0177
0178 CuboidVolumeBuilder::SurfaceConfig cfg;
0179 cfg.position = {-i * UnitConstants::m, 0., 0.};
0180
0181
0182 double rotationAngle = std::numbers::pi / 2.;
0183 Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0184 Vector3 yPos(0., 1., 0.);
0185 Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0186 cfg.rotation.col(0) = xPos;
0187 cfg.rotation.col(1) = yPos;
0188 cfg.rotation.col(2) = zPos;
0189
0190
0191 cfg.rBounds =
0192 std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
0193
0194
0195 MaterialSlab matProp(makeBeryllium(), 0.5_mm);
0196 cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0197
0198
0199 cfg.thickness = 1_um;
0200 surfaceConfig2.push_back(cfg);
0201 }
0202
0203 std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig2;
0204 for (auto& sCfg : surfaceConfig2) {
0205 CuboidVolumeBuilder::LayerConfig cfg;
0206 cfg.surfaceCfg = {sCfg};
0207 layerConfig2.push_back(cfg);
0208 }
0209 CuboidVolumeBuilder::VolumeConfig volumeConfig2;
0210 volumeConfig2.position = {-2.5_m, 0., 0.};
0211 volumeConfig2.length = {5_m, 1_m, 1_m};
0212 volumeConfig2.layerCfg = layerConfig2;
0213 volumeConfig2.name = "Test volume2";
0214
0215 CuboidVolumeBuilder::Config config;
0216 config.position = {0., 0., 0.};
0217 config.length = {10_m, 1_m, 1_m};
0218 config.volumeCfg = {volumeConfig2, volumeConfig};
0219
0220 cvb.setConfig(config);
0221 TrackingGeometryBuilder::Config tgbCfg;
0222 tgbCfg.trackingVolumeBuilders.push_back(
0223 [=](const auto& context, const auto& inner, const auto&) {
0224 return cvb.trackingVolume(context, inner, nullptr);
0225 });
0226 TrackingGeometryBuilder tgb(tgbCfg);
0227
0228 std::unique_ptr<const TrackingGeometry> detector =
0229 tgb.trackingGeometry(tgContext);
0230 BOOST_CHECK_EQUAL(
0231 detector->lowestTrackingVolume(tgContext, Vector3(1_mm, 0_mm, 0_mm))
0232 ->volumeName(),
0233 volumeConfig.name);
0234 BOOST_CHECK_EQUAL(
0235 detector->lowestTrackingVolume(tgContext, Vector3(-1_mm, 0_mm, 0_mm))
0236 ->volumeName(),
0237 volumeConfig2.name);
0238 BOOST_CHECK_EQUAL(
0239 detector->lowestTrackingVolume(tgContext, Vector3(1000_m, 0_m, 0_m)),
0240 nullptr);
0241 }
0242
0243 }