File indexing completed on 2025-12-16 09:23:13
0001
0002
0003
0004
0005
0006
0007
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
0038 std::vector<SurfaceIntersection> surfaceIntersections;
0039
0040 for (const Surface* surface : surfaces) {
0041
0042 MultiIntersection3D multiIntersection = surface->intersect(
0043 gctx, position, direction, BoundaryTolerance::None());
0044
0045
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
0054 std::ranges::sort(surfaceIntersections, SurfaceIntersection::pathLengthOrder);
0055 return surfaceIntersections;
0056 }
0057
0058 }
0059
0060 std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0061 std::vector<IAssignmentFinder::VolumeAssignment>>
0062 IntersectionMaterialAssigner::assignmentCandidates(
0063 const GeometryContext& gctx, const MagneticFieldContext& ,
0064 const Vector3& position, const Vector3& direction) const {
0065
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
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
0084 if (!m_cfg.trackingVolumes.empty()) {
0085 for (auto& trackingVolume : m_cfg.trackingVolumes) {
0086
0087 auto boundarySurfaces = trackingVolume->boundarySurfaces();
0088 std::vector<const Surface*> tSurfaces;
0089 for (auto& boundarySurface : boundarySurfaces) {
0090 tSurfaces.push_back(&(boundarySurface->surfaceRepresentation()));
0091 }
0092
0093 auto tIntersections =
0094 forwardOrderedIntersections(gctx, position, direction, tSurfaces);
0095
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
0109 return candidates;
0110 }
0111
0112 }