Back to home page

EIC code displayed by LXR

 
 

    


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

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/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/GeometryIdentifier.hpp"
0014 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0015 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0016 #include "Acts/Material/MaterialInteraction.hpp"
0017 #include "Acts/Material/MaterialMapper.hpp"
0018 #include "Acts/Material/MaterialSlab.hpp"
0019 #include "Acts/Material/MaterialValidater.hpp"
0020 #include "Acts/Material/interface/IAssignmentFinder.hpp"
0021 #include "Acts/Surfaces/CylinderSurface.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 
0024 #include <limits>
0025 #include <numbers>
0026 
0027 namespace Acts::Test {
0028 
0029 auto tContext = GeometryContext();
0030 
0031 /// @brief Interface for the material mapping that seeks the possible
0032 /// assignment candidates for the material interactiosn
0033 class IntersectSurfacesFinder : public IAssignmentFinder {
0034  public:
0035   std::vector<const Surface*> surfaces;
0036 
0037   /// @brief Interface method for generating assignment candidates for the
0038   /// material interaction assignment to surfaces or volumes
0039   ///
0040   /// @param gctx is the geometry context
0041   /// @param mctx is the magnetic field context
0042   /// @param position is the position of the initial ray
0043   /// @param direction is the direction of initial ray
0044   ///
0045   /// @return a vector of Surface Assignments and Volume Assignments
0046   std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0047             std::vector<IAssignmentFinder::VolumeAssignment>>
0048   assignmentCandidates(const GeometryContext& gctx,
0049                        const MagneticFieldContext& /*ignored*/,
0050                        const Vector3& position,
0051                        const Vector3& direction) const override {
0052     std::vector<IAssignmentFinder::SurfaceAssignment> surfaceAssignments;
0053     std::vector<IAssignmentFinder::VolumeAssignment> volumeAssignments;
0054     // Intersect the surfaces
0055     for (auto& surface : surfaces) {
0056       // Get the intersection
0057       auto sMultiIntersection = surface->intersect(gctx, position, direction,
0058                                                    BoundaryTolerance::None());
0059       // One solution, take it
0060       if (sMultiIntersection.size() == 1u &&
0061           sMultiIntersection[0u].status() >=
0062               Acts::IntersectionStatus::reachable &&
0063           sMultiIntersection[0u].pathLength() >= 0.0) {
0064         surfaceAssignments.push_back(
0065             {surface, sMultiIntersection[0u].position(), direction});
0066         continue;
0067       }
0068       if (sMultiIntersection.size() > 1u) {
0069         // Multiple intersections, take the closest
0070         auto closestForward = sMultiIntersection.closestForward();
0071         if (closestForward.status() >= Acts::IntersectionStatus::reachable &&
0072             closestForward.pathLength() > 0.0) {
0073           surfaceAssignments.push_back(
0074               {surface, closestForward.position(), direction});
0075           continue;
0076         }
0077       }
0078     }
0079     return {surfaceAssignments, volumeAssignments};
0080   }
0081 };
0082 
0083 BOOST_AUTO_TEST_SUITE(MAterialValidatorTestSuite)
0084 
0085 BOOST_AUTO_TEST_CASE(MaterialValidaterFlowTest) {
0086   auto cylinder0 =
0087       Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20, 100);
0088   auto cylinder1 =
0089       Surface::makeShared<CylinderSurface>(Transform3::Identity(), 40, 100);
0090   auto cylinder2 =
0091       Surface::makeShared<CylinderSurface>(Transform3::Identity(), 60, 100);
0092 
0093   auto material0 = std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab(
0094       Acts::Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 2.0));
0095   auto material1 = std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab(
0096       Acts::Material::fromMolarDensity(41.0, 42.0, 43.0, 44.0, 45.0), 4.0));
0097   auto material2 = std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab(
0098       Acts::Material::fromMolarDensity(61.0, 62.0, 63.0, 64.0, 65.0), 6.0));
0099 
0100   cylinder0->assignSurfaceMaterial(material0);
0101   cylinder1->assignSurfaceMaterial(material1);
0102   cylinder2->assignSurfaceMaterial(material2);
0103 
0104   auto materialAssinger = std::make_shared<IntersectSurfacesFinder>();
0105   materialAssinger->surfaces = {cylinder0.get(), cylinder1.get(),
0106                                 cylinder2.get()};
0107 
0108   MaterialValidater::Config mvConfig;
0109   mvConfig.materialAssigner = materialAssinger;
0110 
0111   auto materialValidater = MaterialValidater(
0112       mvConfig, getDefaultLogger("MaterialValidater", Logging::VERBOSE));
0113 
0114   // Test one central ray
0115   auto [posDir, rMaterial] = materialValidater.recordMaterial(
0116       tContext, MagneticFieldContext(), Vector3(0, 0, 0), Vector3(1, 0, 0));
0117 
0118   BOOST_CHECK(posDir.first == Vector3(0, 0, 0));
0119   BOOST_CHECK(posDir.second == Vector3(1, 0, 0));
0120   CHECK_CLOSE_ABS(rMaterial.materialInX0, 2. / 21. + 4. / 41. + 6. / 61., 1e-6);
0121   CHECK_CLOSE_ABS(rMaterial.materialInL0, 2. / 22. + 4. / 42. + 6. / 62., 1e-6);
0122   BOOST_CHECK_EQUAL(rMaterial.materialInteractions.size(), 3u);
0123 
0124   // Test a ray at 45 degrees
0125   auto [posDir2, rMaterial2] = materialValidater.recordMaterial(
0126       tContext, MagneticFieldContext(), Vector3(0, 0, 0),
0127       Vector3(1, 0, 1).normalized());
0128 
0129   double pathCorrection = std::numbers::sqrt2;
0130   CHECK_CLOSE_ABS(rMaterial2.materialInX0,
0131                   pathCorrection * (2. / 21. + 4. / 41. + 6. / 61.), 1e-6);
0132   CHECK_CLOSE_ABS(rMaterial2.materialInL0,
0133                   pathCorrection * (2. / 22. + 4. / 42. + 6. / 62.), 1e-6);
0134   BOOST_CHECK_EQUAL(rMaterial2.materialInteractions.size(), 3u);
0135 }
0136 
0137 BOOST_AUTO_TEST_SUITE_END()
0138 
0139 }  // namespace Acts::Test