File indexing completed on 2025-01-18 09:12:32
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/DetectorComponents.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/interface/IExternalStructureBuilder.hpp"
0017 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0018 #include "Acts/Detector/interface/IInternalStructureBuilder.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/Surface.hpp"
0027 #include "Acts/Utilities/Logger.hpp"
0028
0029 #include <memory>
0030 #include <numbers>
0031 #include <stdexcept>
0032 #include <string>
0033 #include <utility>
0034 #include <vector>
0035
0036 using namespace Acts;
0037 using namespace Acts::Experimental;
0038
0039 GeometryContext tContext;
0040
0041
0042
0043 template <typename bounds_type>
0044 class ExternalsBuilder : public IExternalStructureBuilder {
0045 public:
0046 ExternalsBuilder(const Transform3& transform, const bounds_type& bounds)
0047 : IExternalStructureBuilder(),
0048 m_transform(transform),
0049 m_bounds(std::move(bounds)) {}
0050
0051 ExternalStructure construct(
0052 [[maybe_unused]] const GeometryContext& gctx) const final {
0053 return {m_transform, std::make_unique<bounds_type>(m_bounds),
0054 defaultPortalGenerator()};
0055 }
0056
0057 private:
0058 Transform3 m_transform = Transform3::Identity();
0059 bounds_type m_bounds;
0060 };
0061
0062
0063
0064
0065 template <typename surface_type, typename bounds_type>
0066 class InternalSurfaceBuilder : public IInternalStructureBuilder {
0067 public:
0068 InternalSurfaceBuilder(const Transform3& transform, const bounds_type& bounds)
0069 : IInternalStructureBuilder(),
0070 m_transform(transform),
0071 m_bounds(std::move(bounds)) {}
0072
0073 InternalStructure construct(
0074 [[maybe_unused]] const GeometryContext& gctx) const final {
0075 auto surface = Surface::makeShared<surface_type>(
0076 m_transform, std::make_shared<bounds_type>(m_bounds));
0077 return {{surface}, {}, tryAllPortalsAndSurfaces(), tryNoVolumes()};
0078 }
0079
0080 private:
0081 Transform3 m_transform = Transform3::Identity();
0082 bounds_type m_bounds;
0083 };
0084
0085 class SurfaceGeoIdGenerator : public Acts::Experimental::IGeometryIdGenerator {
0086 public:
0087 Acts::Experimental::IGeometryIdGenerator::GeoIdCache generateCache()
0088 const final {
0089 return std::any();
0090 }
0091
0092 void assignGeometryId(
0093 Acts::Experimental::IGeometryIdGenerator::GeoIdCache& ,
0094 Acts::Experimental::DetectorVolume& dVolume) const final {
0095 for (auto [is, s] : Acts::enumerate(dVolume.surfacePtrs())) {
0096 Acts::GeometryIdentifier geoID;
0097 geoID.setPassive(is + 1);
0098 s->assignGeometryId(geoID);
0099 }
0100 }
0101
0102 void assignGeometryId(
0103 Acts::Experimental::IGeometryIdGenerator::GeoIdCache& ,
0104 Acts::Experimental::Portal& ) const final {}
0105
0106 void assignGeometryId(
0107 Acts::Experimental::IGeometryIdGenerator::GeoIdCache& ,
0108 Acts::Surface& ) const final {}
0109 };
0110
0111
0112
0113
0114 template <typename bounds_type>
0115 class InternalVolumeBuilder : public IInternalStructureBuilder {
0116 public:
0117 InternalVolumeBuilder(const Transform3& transform, const bounds_type& bounds)
0118 : IInternalStructureBuilder(),
0119 m_transform(transform),
0120 m_bounds(std::move(bounds)) {}
0121
0122 InternalStructure construct(
0123 [[maybe_unused]] const GeometryContext& gctx) const final {
0124 auto bounds = std::make_unique<bounds_type>(m_bounds);
0125 auto portalGenerator = defaultPortalGenerator();
0126 auto volume = DetectorVolumeFactory::construct(
0127 portalGenerator, tContext, "InternalVolume", m_transform,
0128 std::move(bounds), tryAllPortals());
0129 return {{}, {volume}, tryAllPortals(), tryRootVolumes()};
0130 }
0131
0132 private:
0133 Transform3 m_transform = Transform3::Identity();
0134 bounds_type m_bounds;
0135 };
0136
0137 BOOST_AUTO_TEST_SUITE(Detector)
0138
0139 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_Misconfigured) {
0140
0141 DetectorVolumeBuilder::Config dvCfg;
0142 dvCfg.auxiliary = "*** Test X * Misconfigued ***";
0143 dvCfg.name = "EmptyCylinder";
0144 dvCfg.externalsBuilder = nullptr;
0145 dvCfg.internalsBuilder = nullptr;
0146
0147 BOOST_CHECK_THROW(auto a = DetectorVolumeBuilder(dvCfg),
0148 std::invalid_argument);
0149 }
0150
0151 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_EmptyVolume) {
0152 CylinderVolumeBounds cBounds(10, 100, 200);
0153 auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
0154 Transform3::Identity(), cBounds);
0155
0156 DetectorVolumeBuilder::Config dvCfg;
0157 dvCfg.auxiliary = "*** Test 0 - Empty Cylinder ***";
0158 dvCfg.name = "EmptyCylinder";
0159 dvCfg.externalsBuilder = cBuilder;
0160 dvCfg.internalsBuilder = nullptr;
0161
0162
0163 dvCfg.portalMaterialBinning[2u] = BinningDescription{
0164 {ProtoBinning(AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, 50),
0165 ProtoBinning(AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0166 -std::numbers::pi, std::numbers::pi, 12)}};
0167
0168 auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
0169 dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
0170
0171 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0172
0173 BOOST_CHECK_EQUAL(volumes.size(), 1u);
0174 BOOST_CHECK(volumes.front()->surfaces().empty());
0175 BOOST_CHECK(volumes.front()->volumes().empty());
0176
0177 BOOST_CHECK_EQUAL(portals.size(), 4u);
0178
0179 BOOST_CHECK_EQUAL(roots.volumes.size(), 1u);
0180 BOOST_CHECK(roots.volumeFinder.connected());
0181
0182
0183 BOOST_CHECK_NE(portals[2u]->surface().surfaceMaterial(), nullptr);
0184
0185 BOOST_CHECK_EQUAL(portals[0u]->surface().surfaceMaterial(), nullptr);
0186 BOOST_CHECK_EQUAL(portals[1u]->surface().surfaceMaterial(), nullptr);
0187 BOOST_CHECK_EQUAL(portals[3u]->surface().surfaceMaterial(), nullptr);
0188 }
0189
0190 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithSurface) {
0191 CylinderVolumeBounds cvBounds(10, 100, 200);
0192 auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
0193 Transform3::Identity(), cvBounds);
0194
0195 CylinderBounds csBounds(55., 195.);
0196 auto sBuilder =
0197 std::make_shared<InternalSurfaceBuilder<CylinderSurface, CylinderBounds>>(
0198 Transform3::Identity(), csBounds);
0199
0200 DetectorVolumeBuilder::Config dvCfg;
0201 dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0202 dvCfg.name = "CylinderWithSurface";
0203 dvCfg.externalsBuilder = cBuilder;
0204 dvCfg.internalsBuilder = sBuilder;
0205 dvCfg.geoIdGenerator = std::make_shared<SurfaceGeoIdGenerator>();
0206
0207 auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
0208 dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
0209
0210 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0211
0212 BOOST_CHECK_EQUAL(volumes.size(), 1u);
0213 BOOST_CHECK_EQUAL(volumes.front()->surfaces().size(), 1u);
0214
0215 BOOST_CHECK_EQUAL(volumes.front()->surfaces().front()->geometryId().passive(),
0216 1u);
0217 BOOST_CHECK(volumes.front()->volumes().empty());
0218
0219 BOOST_CHECK_EQUAL(portals.size(), 4u);
0220
0221 BOOST_CHECK_EQUAL(roots.volumes.size(), 1u);
0222 BOOST_CHECK(roots.volumeFinder.connected());
0223 }
0224
0225 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithVolume) {
0226 CylinderVolumeBounds cvBounds(10, 100, 200);
0227 auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
0228 Transform3::Identity(), cvBounds);
0229
0230 CylinderVolumeBounds ciBounds(15., 95., 195.);
0231 auto iBuilder = std::make_shared<InternalVolumeBuilder<CylinderVolumeBounds>>(
0232 Transform3::Identity(), ciBounds);
0233
0234 DetectorVolumeBuilder::Config dvCfg;
0235 dvCfg.auxiliary = "*** Test 2 - Cylinder with internal Volume ***";
0236 dvCfg.name = "CylinderWithVolume";
0237 dvCfg.externalsBuilder = cBuilder;
0238 dvCfg.internalsBuilder = iBuilder;
0239 dvCfg.addInternalsToRoot = false;
0240
0241 auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
0242 dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
0243
0244 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0245
0246 BOOST_CHECK_EQUAL(volumes.size(), 1u);
0247 BOOST_CHECK_EQUAL(portals.size(), 4u);
0248 BOOST_CHECK_EQUAL(roots.volumes.size(), 1u);
0249 }
0250
0251 BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_VolumeWithVolumeToRoot) {
0252 CylinderVolumeBounds cvBounds(10, 100, 200);
0253 auto cBuilder = std::make_shared<ExternalsBuilder<CylinderVolumeBounds>>(
0254 Transform3::Identity(), cvBounds);
0255
0256 CylinderVolumeBounds ciBounds(15., 95., 195.);
0257 auto iBuilder = std::make_shared<InternalVolumeBuilder<CylinderVolumeBounds>>(
0258 Transform3::Identity(), ciBounds);
0259
0260 DetectorVolumeBuilder::Config dvCfg;
0261 dvCfg.auxiliary =
0262 "*** Test 3 - Cylinder with internal Volume, adding to root ***";
0263 dvCfg.name = "CylinderWithVolume";
0264 dvCfg.externalsBuilder = cBuilder;
0265 dvCfg.internalsBuilder = iBuilder;
0266 dvCfg.addInternalsToRoot = true;
0267
0268 auto dvBuilder = std::make_shared<DetectorVolumeBuilder>(
0269 dvCfg, getDefaultLogger("DetectorVolumeBuilder", Logging::VERBOSE));
0270
0271 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0272
0273 BOOST_CHECK_EQUAL(volumes.size(), 1u);
0274 BOOST_CHECK(volumes.front()->surfaces().empty());
0275 BOOST_CHECK_EQUAL(volumes.front()->volumes().size(), 1u);
0276
0277 BOOST_CHECK_EQUAL(portals.size(), 4u);
0278
0279 BOOST_CHECK_EQUAL(roots.volumes.size(), 2u);
0280 BOOST_CHECK(roots.volumeFinder.connected());
0281 }
0282
0283 BOOST_AUTO_TEST_SUITE_END()