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/Detector.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/GeometryIdGenerator.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0019 #include "Acts/Geometry/GeometryIdentifier.hpp"
0020 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0021 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0022 #include "Acts/Material/Material.hpp"
0023 #include "Acts/Material/MaterialSlab.hpp"
0024 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0025 #include "Acts/Navigation/InternalNavigation.hpp"
0026 #include "Acts/Navigation/NavigationDelegates.hpp"
0027 #include "Acts/Navigation/NavigationState.hpp"
0028 #include "Acts/Surfaces/CylinderBounds.hpp"
0029 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0030 
0031 #include <memory>
0032 #include <stdexcept>
0033 #include <string>
0034 #include <utility>
0035 #include <vector>
0036 
0037 /// Unpack to shared - simply to test the getSharedPtr mechanism
0038 ///
0039 /// @tparam referenced_type is the type of the referenced object
0040 ///
0041 /// @param rt is the referenced object
0042 ///
0043 /// @returns a shared pointer
0044 template <typename referenced_type>
0045 std::shared_ptr<referenced_type> unpackToShared(referenced_type& rt) {
0046   return rt.getSharedPtr();
0047 }
0048 
0049 Acts::GeometryContext tContext;
0050 
0051 BOOST_AUTO_TEST_SUITE(Detector)
0052 
0053 BOOST_AUTO_TEST_CASE(DetectorConstruction) {
0054   double r0 = 0.;
0055   double r1 = 10.;
0056   double r2 = 100.;
0057   double r3 = 200.;
0058   double zHalfL = 200.;
0059 
0060   Acts::Transform3 nominal = Acts::Transform3::Identity();
0061 
0062   // Create a bunch of volumes
0063   auto cyl0Bounds =
0064       std::make_unique<Acts::CylinderVolumeBounds>(r0, r1, zHalfL);
0065 
0066   auto cyl0BoundsCopy =
0067       std::make_unique<Acts::CylinderVolumeBounds>(r0, r1, zHalfL);
0068 
0069   auto cyl1Bounds =
0070       std::make_unique<Acts::CylinderVolumeBounds>(r1, r2, zHalfL);
0071 
0072   auto cyl2Bounds =
0073       std::make_unique<Acts::CylinderVolumeBounds>(r2, r3, zHalfL);
0074 
0075   auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0076 
0077   auto cyl0 = Acts::Experimental::DetectorVolumeFactory::construct(
0078       portalGenerator, tContext, "Cyl0", nominal, std::move(cyl0Bounds),
0079       Acts::Experimental::tryAllPortals());
0080 
0081   auto cyl0nameDup = Acts::Experimental::DetectorVolumeFactory::construct(
0082       portalGenerator, tContext, "Cyl0", nominal, std::move(cyl0BoundsCopy),
0083       Acts::Experimental::tryAllPortals());
0084 
0085   auto cyl1 = Acts::Experimental::DetectorVolumeFactory::construct(
0086       portalGenerator, tContext, "Cyl1", nominal, std::move(cyl1Bounds),
0087       Acts::Experimental::tryAllPortals());
0088 
0089   auto cyl2 = Acts::Experimental::DetectorVolumeFactory::construct(
0090       portalGenerator, tContext, "Cyl2", nominal, std::move(cyl2Bounds),
0091       Acts::Experimental::tryAllPortals());
0092 
0093   std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes012 =
0094       {cyl0, cyl1, cyl2};
0095 
0096   Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0097   Acts::Experimental::GeometryIdGenerator generator(
0098       generatorConfig,
0099       Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE));
0100   auto cache = generator.generateCache();
0101   for (auto& vol : volumes012) {
0102     generator.assignGeometryId(cache, *vol);
0103   }
0104 
0105   auto det012 = Acts::Experimental::Detector::makeShared(
0106       "Det012", volumes012, Acts::Experimental::tryRootVolumes());
0107 
0108   // Check the basic return functions
0109   BOOST_CHECK_EQUAL(det012->name(), "Det012");
0110   BOOST_CHECK_EQUAL(det012->volumes().size(), 3u);
0111   BOOST_CHECK_EQUAL(det012->volumePtrs().size(), 3u);
0112 
0113   // Check the shared pointer mechanism
0114   BOOST_CHECK_EQUAL(det012,
0115                     unpackToShared<Acts::Experimental::Detector>(*det012));
0116   BOOST_CHECK_EQUAL(
0117       det012, unpackToShared<const Acts::Experimental::Detector>(*det012));
0118 
0119   // Check surface visiting
0120   // Test the visitor pattern for surfaces
0121   std::size_t nSurfaces = 0;
0122   det012->visitSurfaces([&nSurfaces](const auto* s) {
0123     if (s != nullptr) {
0124       nSurfaces++;
0125     }
0126   });
0127   BOOST_CHECK_EQUAL(nSurfaces, 11u);
0128 
0129   // Check the volume visiting
0130   std::size_t nVolumes = 0;
0131   det012->visitVolumes([&nVolumes](const auto* v) {
0132     if (v != nullptr) {
0133       nVolumes++;
0134     }
0135   });
0136   BOOST_CHECK_EQUAL(nVolumes, 3u);
0137 
0138   // Check surface visiting - non-const access
0139   // Test visitor pattern - non-const access
0140   struct SetMaterial {
0141     /// The material to set
0142     std::shared_ptr<const Acts::HomogeneousSurfaceMaterial> surfaceMaterial =
0143         std::make_shared<Acts::HomogeneousSurfaceMaterial>(Acts::MaterialSlab(
0144             Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.), 1.));
0145 
0146     std::shared_ptr<Acts::HomogeneousVolumeMaterial> volumeMaterial =
0147         std::make_shared<Acts::HomogeneousVolumeMaterial>(
0148             Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.));
0149 
0150     /// The visitor call: set surface material
0151     void operator()(Acts::Surface* s) {
0152       if (s != nullptr) {
0153         s->assignSurfaceMaterial(surfaceMaterial);
0154       }
0155     }
0156 
0157     /// The visitor call : set volume material
0158     void operator()(Acts::Experimental::DetectorVolume* v) {
0159       if (v != nullptr) {
0160         v->assignVolumeMaterial(volumeMaterial);
0161       }
0162     }
0163   };
0164 
0165   SetMaterial setMaterial;
0166   det012->visitMutableSurfaces(setMaterial);
0167   det012->visitMutableVolumes(setMaterial);
0168 
0169   // Count surfaces with material
0170   std::size_t nSurfacesWithMaterial = 0;
0171   det012->visitSurfaces([&nSurfacesWithMaterial](const auto* s) {
0172     if (s != nullptr && s->surfaceMaterial() != nullptr) {
0173       nSurfacesWithMaterial++;
0174     }
0175   });
0176   BOOST_CHECK_EQUAL(nSurfacesWithMaterial, 11u);
0177 
0178   // Count volumes with material
0179   std::size_t nVolumesWithMaterial = 0;
0180 
0181   det012->visitVolumes([&nVolumesWithMaterial](const auto* v) {
0182     if (v != nullptr && v->volumeMaterial() != nullptr) {
0183       nVolumesWithMaterial++;
0184     }
0185   });
0186   BOOST_CHECK_EQUAL(nVolumesWithMaterial, 3u);
0187 
0188   // Check the inside function with positions
0189   Acts::Experimental::NavigationState nState;
0190   nState.position = Acts::Vector3(5., 0., 0.);
0191   nState.currentDetector = det012.get();
0192   det012->updateDetectorVolume(tContext, nState);
0193   BOOST_CHECK_EQUAL(nState.currentVolume, cyl0.get());
0194 
0195   auto find1 = det012->findDetectorVolume(tContext, Acts::Vector3(15., 0., 0.));
0196   BOOST_CHECK_EQUAL(find1, cyl1.get());
0197 
0198   auto find2 =
0199       det012->findDetectorVolume(tContext, Acts::Vector3(150., 0., 0.));
0200   BOOST_CHECK_EQUAL(find2, cyl2.get());
0201 
0202   auto findNull =
0203       det012->findDetectorVolume(tContext, Acts::Vector3(1500., 0., 0.));
0204   BOOST_CHECK_EQUAL(findNull, nullptr);
0205 
0206   /// Find by name
0207   auto find0 = det012->findDetectorVolume("Cyl0");
0208   BOOST_CHECK_EQUAL(find0, cyl0.get());
0209 
0210   findNull = det012->findDetectorVolume("Null");
0211   BOOST_CHECK_EQUAL(findNull, nullptr);
0212 
0213   // Misconfigured - unkonnected finder
0214   Acts::Experimental::ExternalNavigationDelegate unconnected;
0215   BOOST_CHECK_THROW(
0216       Acts::Experimental::Detector::makeShared("Det012_unconnected", volumes012,
0217                                                std::move(unconnected)),
0218       std::invalid_argument);
0219 
0220   generator.assignGeometryId(cache, *cyl0nameDup);
0221 
0222   // Misconfigured - duplicate name
0223   std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes002 =
0224       {cyl0, cyl0nameDup, cyl2};
0225   BOOST_CHECK_THROW(Acts::Experimental::Detector::makeShared(
0226                         "Det002_name_duplicate", volumes002,
0227                         Acts::Experimental::tryRootVolumes()),
0228                     std::invalid_argument);
0229 }
0230 
0231 BOOST_AUTO_TEST_CASE(DetectorConstructionWithHierarchyMap) {
0232   auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0233 
0234   std::vector<std::unique_ptr<Acts::Test::DetectorElementStub>> detStore;
0235   std::vector<double> radii = {100, 102, 104, 106, 108, 110};
0236   auto cylinderVoumeBounds =
0237       std::make_unique<Acts::CylinderVolumeBounds>(80, 130, 200);
0238   std::vector<std::shared_ptr<Acts::Surface>> surfaces = {};
0239   for (auto [ir, r] : Acts::enumerate(radii)) {
0240     auto detElement = std::make_unique<Acts::Test::DetectorElementStub>(
0241         Acts::Transform3::Identity(),
0242         std::make_shared<Acts::CylinderBounds>(r, 190.), 0.1);
0243     auto surface = detElement->surface().getSharedPtr();
0244     surface->assignGeometryId(Acts::GeometryIdentifier{}.setSensitive(ir + 1));
0245     surfaces.push_back(std::move(surface));
0246     detStore.push_back(std::move(detElement));
0247   }
0248 
0249   auto cylVolume = Acts::Experimental::DetectorVolumeFactory::construct(
0250       portalGenerator, tContext, "CylinderVolume", Acts::Transform3::Identity(),
0251       std::move(cylinderVoumeBounds), surfaces, {},
0252       Acts::Experimental::tryNoVolumes(),
0253       Acts::Experimental::tryAllPortalsAndSurfaces());
0254 
0255   Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0256   Acts::Experimental::GeometryIdGenerator generator(
0257       generatorConfig,
0258       Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE));
0259 
0260   auto cache = generator.generateCache();
0261   generator.assignGeometryId(cache, *cylVolume);
0262 
0263   auto det = Acts::Experimental::Detector::makeShared(
0264       "DetWithSurfaces", {cylVolume}, Acts::Experimental::tryRootVolumes());
0265 
0266   const auto& sensitiveHierarchyMap = det->sensitiveHierarchyMap();
0267 
0268   const Acts::Surface* surface0 =
0269       det->findSurface(Acts::GeometryIdentifier{}.setSensitive(1));
0270 
0271   BOOST_CHECK_EQUAL(sensitiveHierarchyMap.size(), 6u);
0272   BOOST_CHECK_NE(surface0, nullptr);
0273 }
0274 
0275 BOOST_AUTO_TEST_SUITE_END()