Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:23:13

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 "Acts/Material/IntersectionMaterialAssigner.hpp"
0010 
0011 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0012 #include "Acts/Surfaces/Surface.hpp"
0013 #include "Acts/Utilities/Intersection.hpp"
0014 #include "Acts/Utilities/StringHelpers.hpp"
0015 
0016 #include <algorithm>
0017 
0018 namespace Acts {
0019 
0020 namespace {
0021 
0022 struct SurfaceIntersection {
0023   Intersection3D intersection;
0024   const Surface* surface;
0025 
0026   constexpr static bool pathLengthOrder(
0027       const SurfaceIntersection& aIntersection,
0028       const SurfaceIntersection& bIntersection) noexcept {
0029     return Intersection3D::pathLengthOrder(aIntersection.intersection,
0030                                            bIntersection.intersection);
0031   }
0032 };
0033 
0034 std::vector<SurfaceIntersection> forwardOrderedIntersections(
0035     const GeometryContext& gctx, const Vector3& position,
0036     const Vector3& direction, const std::vector<const Surface*>& surfaces) {
0037   // First deal with the surface intersections
0038   std::vector<SurfaceIntersection> surfaceIntersections;
0039   // Intersect the surfaces
0040   for (const Surface* surface : surfaces) {
0041     // Get the intersection
0042     MultiIntersection3D multiIntersection = surface->intersect(
0043         gctx, position, direction, BoundaryTolerance::None());
0044 
0045     // Take the closest
0046     const Intersection3D& intersection = multiIntersection.closestForward();
0047     if (intersection.status() >= IntersectionStatus::reachable &&
0048         intersection.pathLength() > 0) {
0049       surfaceIntersections.emplace_back(intersection, surface);
0050       continue;
0051     }
0052   }
0053   // Sort the intersection along the pathlength
0054   std::ranges::sort(surfaceIntersections, SurfaceIntersection::pathLengthOrder);
0055   return surfaceIntersections;
0056 }
0057 
0058 }  // namespace
0059 
0060 std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0061           std::vector<IAssignmentFinder::VolumeAssignment>>
0062 IntersectionMaterialAssigner::assignmentCandidates(
0063     const GeometryContext& gctx, const MagneticFieldContext& /*mctx*/,
0064     const Vector3& position, const Vector3& direction) const {
0065   // The resulting candidates
0066   std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0067             std::vector<IAssignmentFinder::VolumeAssignment>>
0068       candidates;
0069 
0070   ACTS_DEBUG("Finding material assignment from position "
0071              << toString(position) << " and direction " << toString(direction));
0072 
0073   // Try the surfaces first
0074   auto sIntersections =
0075       forwardOrderedIntersections(gctx, position, direction, m_cfg.surfaces);
0076   candidates.first.reserve(sIntersections.size());
0077   for (auto& sIntersection : sIntersections) {
0078     candidates.first.push_back(IAssignmentFinder::SurfaceAssignment{
0079         sIntersection.surface, sIntersection.intersection.position(),
0080         direction});
0081   }
0082 
0083   // Now deal with the volume intersections : tracking volume first
0084   if (!m_cfg.trackingVolumes.empty()) {
0085     for (auto& trackingVolume : m_cfg.trackingVolumes) {
0086       // Collect the boundary surfaces
0087       auto boundarySurfaces = trackingVolume->boundarySurfaces();
0088       std::vector<const Surface*> tSurfaces;
0089       for (auto& boundarySurface : boundarySurfaces) {
0090         tSurfaces.push_back(&(boundarySurface->surfaceRepresentation()));
0091       }
0092       // Get the intersections
0093       auto tIntersections =
0094           forwardOrderedIntersections(gctx, position, direction, tSurfaces);
0095       // Entry/exit exists in forward direction
0096       if (tIntersections.size() == 2u) {
0097         candidates.second.push_back(IAssignmentFinder::VolumeAssignment{
0098             InteractionVolume(trackingVolume),
0099             tIntersections[0u].intersection.position(),
0100             tIntersections[1u].intersection.position()});
0101       }
0102     }
0103   }
0104 
0105   ACTS_DEBUG("Found " << candidates.first.size() << " surface candidates and "
0106                       << candidates.second.size() << " volume candidates");
0107 
0108   // Return the result
0109   return candidates;
0110 }
0111 
0112 }  // namespace Acts