Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 07:51:07

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/CuboidalContainerBuilder.hpp"
0013 #include "Acts/Detector/DetectorComponents.hpp"
0014 #include "Acts/Detector/DetectorVolume.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
0017 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0018 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Geometry/GeometryIdentifier.hpp"
0021 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0022 #include "Acts/Navigation/InternalNavigation.hpp"
0023 #include "Acts/Surfaces/PlaneSurface.hpp"
0024 #include "Acts/Surfaces/RectangleBounds.hpp"
0025 #include "Acts/Surfaces/Surface.hpp"
0026 #include "Acts/Utilities/BinningType.hpp"
0027 #include "Acts/Utilities/Enumerate.hpp"
0028 #include "Acts/Utilities/Logger.hpp"
0029 #include "Acts/Utilities/ProtoAxis.hpp"
0030 
0031 #include <array>
0032 #include <memory>
0033 #include <stdexcept>
0034 
0035 using namespace Acts::Experimental;
0036 
0037 auto tContext = Acts::GeometryContext();
0038 
0039 /// @brief A mockup volume builder, it generates volumes with
0040 /// a single surface filled in in order to use the CuboidalContainerBuilder
0041 /// infrastructure.
0042 class CuboidalVolumeBuilder : public IDetectorComponentBuilder {
0043  public:
0044   CuboidalVolumeBuilder(const Acts::Transform3& transform,
0045                         const Acts::CuboidVolumeBounds& vBounds,
0046                         const Acts::RectangleBounds& sBounds,
0047                         const std::string& vName)
0048       : IDetectorComponentBuilder(),
0049         m_transform(transform),
0050         m_volumeBounds(vBounds),
0051         m_surfaceBounds(sBounds),
0052         m_name(vName) {}
0053 
0054   DetectorComponent construct(
0055       [[maybe_unused]] const Acts::GeometryContext& gctx) const final {
0056     // The outgoing root volumes
0057     std::vector<std::shared_ptr<DetectorVolume>> rootVolumes;
0058 
0059     // Ingredients
0060     auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0061         (m_transform),
0062         std::make_shared<Acts::RectangleBounds>(m_surfaceBounds));
0063 
0064     auto bounds = std::make_unique<Acts::CuboidVolumeBounds>(m_volumeBounds);
0065     auto portalGenerator = defaultPortalAndSubPortalGenerator();
0066     auto volume = DetectorVolumeFactory::construct(
0067         portalGenerator, tContext, m_name, m_transform, std::move(bounds),
0068         {surface}, {}, tryAllSubVolumes(), tryAllPortalsAndSurfaces());
0069 
0070     // Add to the roots
0071     rootVolumes.push_back(volume);
0072 
0073     DetectorComponent::PortalContainer dContainer;
0074     for (auto [ip, p] : Acts::enumerate(volume->portalPtrs())) {
0075       dContainer[ip] = p;
0076     }
0077 
0078     return DetectorComponent{
0079         {volume},
0080         dContainer,
0081         RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
0082   }
0083 
0084  private:
0085   Acts::Transform3 m_transform;
0086   Acts::CuboidVolumeBounds m_volumeBounds;
0087   Acts::RectangleBounds m_surfaceBounds;
0088   std::string m_name;
0089 };
0090 
0091 class VolumeGeoIdGenerator : public IGeometryIdGenerator {
0092  public:
0093   struct Cache {
0094     unsigned int volumeCount = 0;
0095   };
0096 
0097   IGeometryIdGenerator::GeoIdCache generateCache() const final {
0098     return Cache{0};
0099   }
0100 
0101   void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
0102                         DetectorVolume& dVolume) const final {
0103     auto& ccache = std::any_cast<Cache&>(cache);
0104     ccache.volumeCount += 1;
0105     auto geoID = Acts::GeometryIdentifier().withVolume(ccache.volumeCount);
0106     dVolume.assignGeometryId(geoID);
0107   }
0108 
0109   void assignGeometryId(
0110       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0111       Acts::Experimental::Portal& /*portal*/) const final {}
0112 
0113   void assignGeometryId(
0114       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0115       Acts::Surface& /*surface*/) const final {}
0116 };
0117 
0118 BOOST_AUTO_TEST_SUITE(Detector)
0119 
0120 BOOST_AUTO_TEST_CASE(CuboidalContainerBuilder_Misconfiguration) {
0121   // misconfiruation: no builders
0122   CuboidalContainerBuilder::Config misCfg;
0123   BOOST_CHECK_THROW(auto a = CuboidalContainerBuilder(misCfg),
0124                     std::invalid_argument);
0125   // misconfiguration - 1D binning not in x, y, z
0126   misCfg.builders = {nullptr};
0127   misCfg.binning = Acts::AxisDirection::AxisR;
0128   BOOST_CHECK_THROW(auto b = CuboidalContainerBuilder(misCfg),
0129                     std::invalid_argument);
0130 }
0131 
0132 BOOST_AUTO_TEST_CASE(CuboidalContainerBuildingXYZVolumes) {
0133   std::array<Acts::AxisDirection, 3> binningValues = {
0134       Acts::AxisDirection::AxisX, Acts::AxisDirection::AxisY,
0135       Acts::AxisDirection::AxisZ};
0136   for (auto bVal : binningValues) {
0137     // A perfect box shape
0138     auto box = Acts::CuboidVolumeBounds(10, 10, 10);
0139 
0140     // Transform the second volume away from the first one
0141     auto transformB = Acts::Transform3::Identity();
0142 
0143     Acts::Vector3 translation = Acts::Vector3::Zero();
0144     translation[toUnderlying(bVal)] = 20;
0145     transformB.pretranslate(translation);
0146 
0147     auto builderA = std::make_shared<CuboidalVolumeBuilder>(
0148         Acts::Transform3::Identity(), box, Acts::RectangleBounds(2, 2),
0149         "VolumeA");
0150 
0151     auto builderB = std::make_shared<CuboidalVolumeBuilder>(
0152         transformB, box, Acts::RectangleBounds(2, 2), "VolumeB");
0153 
0154     CuboidalContainerBuilder::Config ccbCfg;
0155     ccbCfg.auxiliary = "*** Build simple connection ***";
0156     ccbCfg.builders = {builderA, builderB};
0157     ccbCfg.binning = bVal;
0158     ccbCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0159 
0160     auto ccBuilder = std::make_shared<CuboidalContainerBuilder>(
0161         ccbCfg, Acts::getDefaultLogger("CuboidalContainerBuilder",
0162                                        Acts::Logging::VERBOSE));
0163 
0164     auto [volumes, portals, roots] = ccBuilder->construct(tContext);
0165 
0166     BOOST_CHECK_EQUAL(portals.size(), 4u);
0167     BOOST_CHECK_EQUAL(roots.volumes.size(), 2u);
0168     BOOST_CHECK_EQUAL(roots.volumes.at(0)->geometryId().volume(), 1u);
0169     BOOST_CHECK_EQUAL(roots.volumes.at(1)->geometryId().volume(), 2u);
0170     BOOST_CHECK_EQUAL(roots.volumes.at(0)
0171                           ->transform(tContext)
0172                           .translation()[toUnderlying(bVal)],
0173                       0);
0174     BOOST_CHECK_EQUAL(roots.volumes.at(1)
0175                           ->transform(tContext)
0176                           .translation()[toUnderlying(bVal)],
0177                       20);
0178 
0179     for (auto& portal : portals) {
0180       if (portal.second->attachedDetectorVolumes().at(0).empty()) {
0181         BOOST_CHECK_EQUAL(portal.second->attachedDetectorVolumes().at(1).size(),
0182                           2u);
0183       } else {
0184         BOOST_CHECK_EQUAL(portal.second->attachedDetectorVolumes().at(0).size(),
0185                           2u);
0186       }
0187     }
0188   }
0189 }
0190 
0191 BOOST_AUTO_TEST_SUITE_END()