Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:26

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