Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:32

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 /// @brief Mockup external structure builder
0042 /// @tparam bounds_type the volume bounds type that is constructed
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 /// @brief  Mockup internal surface builder
0063 /// @tparam surface_type the surface type to be constructed
0064 /// @tparam bounds_type the bounds type that is constructed
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& /*cache*/,
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& /*cache*/,
0104       Acts::Experimental::Portal& /*portal*/) const final {}
0105 
0106   void assignGeometryId(
0107       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0108       Acts::Surface& /*surface*/) const final {}
0109 };
0110 
0111 /// @brief  Mockup internal surface builder
0112 /// @tparam surface_type the surface type to be constructed
0113 /// @tparam bounds_type the bounds type that is constructed
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   // Internal and external structure builder is empty
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   // Assign proto material to
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   // Check that the outside portal has material
0183   BOOST_CHECK_NE(portals[2u]->surface().surfaceMaterial(), nullptr);
0184   // While all the others have none
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()