File indexing completed on 2025-01-18 09:12:31
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/Detector/CylindricalContainerBuilder.hpp"
0013 #include "Acts/Detector/DetectorComponents.hpp"
0014 #include "Acts/Detector/DetectorVolume.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/ProtoBinning.hpp"
0017 #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
0018 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0019 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Geometry/GeometryIdentifier.hpp"
0022 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0023 #include "Acts/Navigation/InternalNavigation.hpp"
0024 #include "Acts/Surfaces/CylinderBounds.hpp"
0025 #include "Acts/Surfaces/CylinderSurface.hpp"
0026 #include "Acts/Surfaces/DiscSurface.hpp"
0027 #include "Acts/Surfaces/RadialBounds.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Tests/CommonHelpers/CylindricalDetector.hpp"
0030 #include "Acts/Utilities/BinningType.hpp"
0031 #include "Acts/Utilities/Enumerate.hpp"
0032 #include "Acts/Utilities/Logger.hpp"
0033
0034 #include <any>
0035 #include <cmath>
0036 #include <iterator>
0037 #include <memory>
0038 #include <numbers>
0039 #include <stdexcept>
0040 #include <string>
0041 #include <utility>
0042 #include <vector>
0043
0044 using namespace Acts;
0045 using namespace Acts::Test;
0046 using namespace Acts::Experimental;
0047
0048 GeometryContext tContext;
0049
0050 class VolumeGeoIdGenerator : public IGeometryIdGenerator {
0051 public:
0052 struct Cache {
0053 unsigned int volumeCount = 0;
0054 };
0055
0056 IGeometryIdGenerator::GeoIdCache generateCache() const final {
0057 return Cache{0};
0058 }
0059
0060 void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
0061 DetectorVolume& dVolume) const final {
0062 auto& ccache = std::any_cast<Cache&>(cache);
0063 ccache.volumeCount += 1;
0064 Acts::GeometryIdentifier geoID;
0065 geoID.setVolume(ccache.volumeCount);
0066 dVolume.assignGeometryId(geoID);
0067 }
0068
0069 void assignGeometryId(
0070 Acts::Experimental::IGeometryIdGenerator::GeoIdCache& ,
0071 Acts::Experimental::Portal& ) const final {}
0072
0073 void assignGeometryId(
0074 Acts::Experimental::IGeometryIdGenerator::GeoIdCache& ,
0075 Acts::Surface& ) const final {}
0076 };
0077
0078 BOOST_AUTO_TEST_SUITE(Detector)
0079
0080 BOOST_AUTO_TEST_CASE(CylindricaContainerBuilder_Misconfiguration) {
0081
0082 CylindricalContainerBuilder::Config misCfg;
0083 BOOST_CHECK_THROW(auto a = CylindricalContainerBuilder(misCfg),
0084 std::invalid_argument);
0085
0086 misCfg.builders = {nullptr};
0087 misCfg.binning = {Acts::AxisDirection::AxisX};
0088 BOOST_CHECK_THROW(auto b = CylindricalContainerBuilder(misCfg),
0089 std::invalid_argument);
0090
0091
0092 misCfg.builders = {nullptr, nullptr};
0093 misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisPhi};
0094 BOOST_CHECK_THROW(auto c = CylindricalContainerBuilder(misCfg),
0095 std::invalid_argument);
0096
0097
0098 misCfg.builders = {nullptr, nullptr, nullptr};
0099 misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR};
0100 BOOST_CHECK_THROW(auto d = CylindricalContainerBuilder(misCfg),
0101 std::invalid_argument);
0102 }
0103
0104 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingZ) {
0105
0106 Transform3 negZ = Transform3::Identity();
0107 negZ.pretranslate(Vector3(0., 0., -300.));
0108 auto negDisc =
0109 std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0110 negZ, CylinderVolumeBounds(50., 200., 100.), RadialBounds(60., 190.),
0111 "NegativeDisc");
0112
0113
0114 auto barrel = std::make_shared<
0115 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0116 Transform3::Identity(), CylinderVolumeBounds(50., 200., 200.),
0117 CylinderBounds(80., 190.), "Barrel");
0118
0119 Transform3 posZ = Transform3::Identity();
0120 posZ.pretranslate(Vector3(0., 0., 300.));
0121 auto posDisc =
0122 std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0123 posZ, CylinderVolumeBounds(50., 200., 100.), RadialBounds(60., 190.),
0124 "PositiveDisc");
0125
0126
0127 CylindricalContainerBuilder::Config tripleZCfg;
0128 tripleZCfg.auxiliary = "*** Test 0 - Build triple in Z ***";
0129 tripleZCfg.builders = {negDisc, barrel, posDisc};
0130 tripleZCfg.binning = {AxisDirection::AxisZ};
0131 tripleZCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0132
0133 tripleZCfg.portalMaterialBinning[2u] = BinningDescription{
0134 {ProtoBinning(AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, 50),
0135 ProtoBinning(AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0136 -std::numbers::pi, std::numbers::pi, 12)}};
0137
0138
0139 tripleZCfg.geoIdReverseGen = true;
0140
0141 auto tripleZ = std::make_shared<CylindricalContainerBuilder>(
0142 tripleZCfg, getDefaultLogger("TripleBuilderZ", Logging::VERBOSE));
0143
0144 auto [volumes, portals, roots] = tripleZ->construct(tContext);
0145
0146 BOOST_CHECK_EQUAL(portals.size(), 4u);
0147 BOOST_CHECK_EQUAL(roots.volumes.size(), 3u);
0148 BOOST_CHECK_EQUAL(roots.volumes[0]->geometryId().volume(), 3u);
0149 BOOST_CHECK_EQUAL(roots.volumes[1]->geometryId().volume(), 2u);
0150 BOOST_CHECK_EQUAL(roots.volumes[2]->geometryId().volume(), 1u);
0151
0152
0153 BOOST_CHECK_NE(portals[2u]->surface().surfaceMaterial(), nullptr);
0154
0155 BOOST_CHECK_EQUAL(portals[0u]->surface().surfaceMaterial(), nullptr);
0156 BOOST_CHECK_EQUAL(portals[1u]->surface().surfaceMaterial(), nullptr);
0157 BOOST_CHECK_EQUAL(portals[3u]->surface().surfaceMaterial(), nullptr);
0158 }
0159
0160 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingR) {
0161
0162 auto barrel0 = std::make_shared<
0163 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0164 Transform3::Identity(), CylinderVolumeBounds(50., 80., 200.),
0165 CylinderBounds(65., 190.), "Barrel0");
0166
0167
0168 auto barrel1 = std::make_shared<
0169 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0170 Transform3::Identity(), CylinderVolumeBounds(80., 110., 200.),
0171 CylinderBounds(95., 190.), "Barrel1");
0172
0173
0174 auto barrel2 = std::make_shared<
0175 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0176 Transform3::Identity(), CylinderVolumeBounds(110., 140., 200.),
0177 CylinderBounds(125., 190.), "Barrel2");
0178
0179
0180 CylindricalContainerBuilder::Config barrelRCfg;
0181 barrelRCfg.auxiliary = "*** Test 1 - Build multilayer barrel ***";
0182 barrelRCfg.builders = {barrel0, barrel1, barrel2};
0183 barrelRCfg.binning = {AxisDirection::AxisR};
0184 barrelRCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0185
0186 auto barrelR = std::make_shared<CylindricalContainerBuilder>(
0187 barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::VERBOSE));
0188
0189 auto [volumes, portals, roots] = barrelR->construct(tContext);
0190
0191 BOOST_CHECK_EQUAL(portals.size(), 4u);
0192 BOOST_CHECK_EQUAL(roots.volumes.size(), 3u);
0193 BOOST_CHECK_EQUAL(roots.volumes[0]->geometryId().volume(), 1u);
0194 BOOST_CHECK_EQUAL(roots.volumes[1]->geometryId().volume(), 2u);
0195 BOOST_CHECK_EQUAL(roots.volumes[2]->geometryId().volume(), 3u);
0196 }
0197
0198 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingPhi) {
0199
0200 CylindricalContainerBuilder::Config barrelPhiCfg;
0201 barrelPhiCfg.auxiliary = "*** Test 2 - Build segmented phi barrel ***";
0202 barrelPhiCfg.binning = {AxisDirection::AxisPhi};
0203
0204 unsigned int phiSectors = 5;
0205 double phiHalfSector = std::numbers::pi / phiSectors;
0206
0207 std::vector<std::shared_ptr<DetectorVolume>> phiVolumes = {};
0208 for (unsigned int i = 0; i < phiSectors; ++i) {
0209
0210 Acts::CylinderVolumeBounds volumeBounds(
0211 10., 100., 100., phiHalfSector,
0212 -std::numbers::pi + (2u * i + 1u) * phiHalfSector);
0213
0214 Acts::CylinderBounds surfaceBounds(
0215 50., 90., 0.99 * phiHalfSector,
0216 -std::numbers::pi + (2u * i + 1u) * phiHalfSector);
0217
0218 auto builder = std::make_shared<
0219 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0220 Transform3::Identity(), volumeBounds, surfaceBounds,
0221 std::string("Sector_") + std::to_string(i));
0222 barrelPhiCfg.builders.push_back(builder);
0223 }
0224
0225 auto barrelPhi = std::make_shared<CylindricalContainerBuilder>(
0226 barrelPhiCfg, getDefaultLogger("BarrelBuilderPhi", Logging::VERBOSE));
0227
0228 auto [volumes, portals, roots] = barrelPhi->construct(tContext);
0229
0230 BOOST_CHECK_EQUAL(portals.size(), 4u);
0231 BOOST_CHECK_EQUAL(roots.volumes.size(), 5u);
0232 }
0233
0234 BOOST_AUTO_TEST_CASE(CylindricalContainerBuilderDetector) {
0235
0236 auto beampipe = std::make_shared<
0237 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0238 Transform3::Identity(), CylinderVolumeBounds(0., 50., 600.),
0239 CylinderBounds(25., 590.), "BeamPipe");
0240
0241
0242 Transform3 negZ = Transform3::Identity();
0243 negZ.pretranslate(Vector3(0., 0., -300.));
0244 auto endcapN =
0245 std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0246 negZ, CylinderVolumeBounds(50., 140., 100.), RadialBounds(60., 130.),
0247 "NegativeEndcap");
0248
0249
0250 auto barrel0 = std::make_shared<
0251 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0252 Transform3::Identity(), CylinderVolumeBounds(50., 80., 200.),
0253 CylinderBounds(65., 190.), "Barrel0");
0254
0255
0256 auto barrel1 = std::make_shared<
0257 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0258 Transform3::Identity(), CylinderVolumeBounds(80., 110., 200.),
0259 CylinderBounds(95., 190.), "Barrel1");
0260
0261
0262 auto barrel2 = std::make_shared<
0263 CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0264 Transform3::Identity(), CylinderVolumeBounds(110., 140., 200.),
0265 CylinderBounds(125., 190.), "Barrel2");
0266
0267
0268 CylindricalContainerBuilder::Config barrelRCfg;
0269 barrelRCfg.builders = {barrel0, barrel1, barrel2};
0270 barrelRCfg.binning = {AxisDirection::AxisR};
0271
0272 auto barrel = std::make_shared<CylindricalContainerBuilder>(
0273 barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::VERBOSE));
0274
0275 Transform3 posZ = Transform3::Identity();
0276 posZ.pretranslate(Vector3(0., 0., 300.));
0277 auto endcapP =
0278 std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0279 posZ, CylinderVolumeBounds(50., 140., 100.), RadialBounds(60., 130.),
0280 "PositiveEndcap");
0281
0282
0283 CylindricalContainerBuilder::Config barrelEndcapCfg;
0284 barrelEndcapCfg.builders = {endcapN, barrel, endcapP};
0285 barrelEndcapCfg.binning = {AxisDirection::AxisZ};
0286
0287 auto barrelEndcap = std::make_shared<CylindricalContainerBuilder>(
0288 barrelEndcapCfg,
0289 getDefaultLogger("BarrelEndcapBuilder", Logging::VERBOSE));
0290
0291
0292 CylindricalContainerBuilder::Config detectorCfg;
0293 detectorCfg.builders = {beampipe, barrelEndcap};
0294 detectorCfg.binning = {AxisDirection::AxisR};
0295
0296 auto detector = std::make_shared<CylindricalContainerBuilder>(
0297 detectorCfg, getDefaultLogger("DetectorBuilder", Logging::VERBOSE));
0298
0299 auto [volumes, portals, roots] = detector->construct(tContext);
0300 BOOST_CHECK_EQUAL(portals.size(), 3u);
0301 BOOST_CHECK_EQUAL(roots.volumes.size(), 6u);
0302 }
0303
0304 BOOST_AUTO_TEST_SUITE_END()