Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:38

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