Back to home page

EIC code displayed by LXR

 
 

    


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

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/ProtoBinning.hpp"
0017 #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
0018 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0019 #include "Acts/Geometry/CuboidVolumeBounds.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/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/RectangleBounds.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/BinningType.hpp"
0028 #include "Acts/Utilities/Enumerate.hpp"
0029 #include "Acts/Utilities/Logger.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     Acts::GeometryIdentifier geoID;
0106     geoID.setVolume(ccache.volumeCount);
0107     dVolume.assignGeometryId(geoID);
0108   }
0109 
0110   void assignGeometryId(
0111       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0112       Acts::Experimental::Portal& /*portal*/) const final {}
0113 
0114   void assignGeometryId(
0115       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0116       Acts::Surface& /*surface*/) const final {}
0117 };
0118 
0119 BOOST_AUTO_TEST_SUITE(Detector)
0120 
0121 BOOST_AUTO_TEST_CASE(CuboidalContainerBuilder_Misconfiguration) {
0122   // misconfiruation: no builders
0123   CuboidalContainerBuilder::Config misCfg;
0124   BOOST_CHECK_THROW(auto a = CuboidalContainerBuilder(misCfg),
0125                     std::invalid_argument);
0126   // misconfiguration - 1D binning not in x, y, z
0127   misCfg.builders = {nullptr};
0128   misCfg.binning = Acts::AxisDirection::AxisR;
0129   BOOST_CHECK_THROW(auto b = CuboidalContainerBuilder(misCfg),
0130                     std::invalid_argument);
0131 }
0132 
0133 BOOST_AUTO_TEST_CASE(CuboidalContainerBuildingXYZVolumes) {
0134   std::array<Acts::AxisDirection, 3> binningValues = {
0135       Acts::AxisDirection::AxisX, Acts::AxisDirection::AxisY,
0136       Acts::AxisDirection::AxisZ};
0137   for (auto bVal : binningValues) {
0138     // A perfect box shape
0139     auto box = Acts::CuboidVolumeBounds(10, 10, 10);
0140 
0141     // Transform the second volume away from the first one
0142     auto transformB = Acts::Transform3::Identity();
0143 
0144     Acts::Vector3 translation = Acts::Vector3::Zero();
0145     translation[toUnderlying(bVal)] = 20;
0146     transformB.pretranslate(translation);
0147 
0148     auto builderA = std::make_shared<CuboidalVolumeBuilder>(
0149         Acts::Transform3::Identity(), box, Acts::RectangleBounds(2, 2),
0150         "VolumeA");
0151 
0152     auto builderB = std::make_shared<CuboidalVolumeBuilder>(
0153         transformB, box, Acts::RectangleBounds(2, 2), "VolumeB");
0154 
0155     CuboidalContainerBuilder::Config ccbCfg;
0156     ccbCfg.auxiliary = "*** Build simple connection ***";
0157     ccbCfg.builders = {builderA, builderB};
0158     ccbCfg.binning = bVal;
0159     ccbCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0160 
0161     auto ccBuilder = std::make_shared<CuboidalContainerBuilder>(
0162         ccbCfg, Acts::getDefaultLogger("CuboidalContainerBuilder",
0163                                        Acts::Logging::VERBOSE));
0164 
0165     auto [volumes, portals, roots] = ccBuilder->construct(tContext);
0166 
0167     BOOST_CHECK_EQUAL(portals.size(), 4u);
0168     BOOST_CHECK_EQUAL(roots.volumes.size(), 2u);
0169     BOOST_CHECK_EQUAL(roots.volumes.at(0)->geometryId().volume(), 1u);
0170     BOOST_CHECK_EQUAL(roots.volumes.at(1)->geometryId().volume(), 2u);
0171     BOOST_CHECK_EQUAL(roots.volumes.at(0)
0172                           ->transform(tContext)
0173                           .translation()[toUnderlying(bVal)],
0174                       0);
0175     BOOST_CHECK_EQUAL(roots.volumes.at(1)
0176                           ->transform(tContext)
0177                           .translation()[toUnderlying(bVal)],
0178                       20);
0179 
0180     for (auto& portal : portals) {
0181       if (portal.second->attachedDetectorVolumes().at(0).empty()) {
0182         BOOST_CHECK_EQUAL(portal.second->attachedDetectorVolumes().at(1).size(),
0183                           2u);
0184       } else {
0185         BOOST_CHECK_EQUAL(portal.second->attachedDetectorVolumes().at(0).size(),
0186                           2u);
0187       }
0188     }
0189   }
0190 }
0191 
0192 BOOST_AUTO_TEST_SUITE_END()