Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:07:53

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023-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 #pragma once
0010 
0011 #include "Acts/Geometry/Layer.hpp"
0012 #include "Acts/Geometry/TrackingVolume.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Intersection.hpp"
0016 
0017 #include <variant>
0018 
0019 namespace Acts::detail {
0020 
0021 using AnyIntersectionObject =
0022     std::variant<const Surface*, const Layer*, const BoundarySurface*>;
0023 
0024 /// @brief A candidate object for navigation
0025 struct NavigationObjectCandidate {
0026   AnyIntersectionObject object;
0027   const Surface* representation = nullptr;
0028   BoundaryTolerance boundaryTolerance;
0029 
0030   NavigationObjectCandidate(AnyIntersectionObject _object,
0031                             const Surface* _representation,
0032                             BoundaryTolerance _boundaryTolerance)
0033       : object(_object),
0034         representation(_representation),
0035         boundaryTolerance(std::move(_boundaryTolerance)) {}
0036 
0037   std::pair<SurfaceMultiIntersection, AnyIntersectionObject> intersect(
0038       const GeometryContext& gctx, const Vector3& position,
0039       const Vector3& direction, ActsScalar tolerance) const {
0040     if (std::holds_alternative<const Surface*>(object)) {
0041       const auto& surface = std::get<const Surface*>(object);
0042       auto intersection = representation->intersect(
0043           gctx, position, direction, boundaryTolerance, tolerance);
0044       return {intersection, surface};
0045     }
0046     if (std::holds_alternative<const Layer*>(object)) {
0047       const auto& layer = std::get<const Layer*>(object);
0048       auto intersection = representation->intersect(
0049           gctx, position, direction, boundaryTolerance, tolerance);
0050       return {intersection, layer};
0051     }
0052     if (std::holds_alternative<const BoundarySurface*>(object)) {
0053       const auto& boundary = std::get<const BoundarySurface*>(object);
0054       auto intersection = representation->intersect(
0055           gctx, position, direction, boundaryTolerance, tolerance);
0056       return {intersection, boundary};
0057     }
0058     throw std::runtime_error("unknown type");
0059   }
0060 };
0061 
0062 /// Composes an intersection and a bounds check into a navigation candidate.
0063 /// This is used to consistently update intersections after creation.
0064 struct IntersectionCandidate {
0065   SurfaceIntersection intersection;
0066   detail::AnyIntersectionObject anyObject;
0067   BoundaryTolerance boundaryTolerance;
0068 
0069   IntersectionCandidate(SurfaceIntersection _intersection,
0070                         detail::AnyIntersectionObject _anyObject,
0071                         BoundaryTolerance _boundaryTolerance)
0072       : intersection(std::move(_intersection)),
0073         anyObject(_anyObject),
0074         boundaryTolerance(std::move(_boundaryTolerance)) {}
0075 
0076   template <typename object_t>
0077   bool checkType() const {
0078     return std::holds_alternative<const object_t*>(anyObject);
0079   }
0080 
0081   template <typename object_t>
0082   const object_t* object() const {
0083     return std::get<const object_t*>(anyObject);
0084   }
0085 
0086   static bool forwardOrder(const IntersectionCandidate& aCandidate,
0087                            const IntersectionCandidate& bCandidate) {
0088     return Intersection3D::pathLengthOrder(
0089         aCandidate.intersection.intersection(),
0090         bCandidate.intersection.intersection());
0091   }
0092 };
0093 
0094 /// @brief Emplace all navigation candidates for a given volume
0095 inline void emplaceAllVolumeCandidates(
0096     std::vector<detail::NavigationObjectCandidate>& candidates,
0097     const TrackingVolume& volume, bool resolveSensitive, bool resolveMaterial,
0098     bool resolvePassive,
0099     const BoundaryTolerance& boundaryToleranceSurfaceApproach,
0100     const Logger& logger) {
0101   auto addCandidate = [&](AnyIntersectionObject object,
0102                           const Surface* representation,
0103                           const BoundaryTolerance& boundaryTolerance) {
0104     candidates.emplace_back(object, representation, boundaryTolerance);
0105   };
0106 
0107   // Get all boundary candidates
0108   {
0109     ACTS_VERBOSE("Searching for boundaries.");
0110 
0111     const auto& boundaries = volume.boundarySurfaces();
0112 
0113     ACTS_VERBOSE("Found " << boundaries.size() << " boundaries.");
0114 
0115     for (const auto& boundary : boundaries) {
0116       addCandidate(boundary.get(), &boundary->surfaceRepresentation(),
0117                    BoundaryTolerance::None());
0118     }
0119   }
0120 
0121   // Get all layer candidates
0122   {
0123     ACTS_VERBOSE("Searching for layers.");
0124 
0125     const auto& layers = volume.confinedLayers()->arrayObjects();
0126 
0127     ACTS_VERBOSE("Found " << layers.size() << " layers.");
0128 
0129     for (const auto& layer : layers) {
0130       if (!layer->resolve(resolveSensitive, resolveMaterial, resolvePassive)) {
0131         continue;
0132       }
0133 
0134       if (!resolveSensitive ||
0135           layer->surfaceRepresentation().surfaceMaterial() != nullptr) {
0136         addCandidate(layer.get(), &layer->surfaceRepresentation(),
0137                      BoundaryTolerance::None());
0138       }
0139 
0140       if (layer->approachDescriptor() != nullptr) {
0141         const auto& approaches =
0142             layer->approachDescriptor()->containedSurfaces();
0143 
0144         for (const auto& approach : approaches) {
0145           addCandidate(layer.get(), approach, BoundaryTolerance::None());
0146         }
0147       }
0148 
0149       // Get all surface candidates from layers
0150       {
0151         ACTS_VERBOSE("Searching for surfaces.");
0152 
0153         if (layer->surfaceArray() != nullptr) {
0154           const auto& surfaces = layer->surfaceArray()->surfaces();
0155 
0156           ACTS_VERBOSE("Found " << surfaces.size() << " surfaces.");
0157 
0158           for (const auto& surface : surfaces) {
0159             addCandidate(surface, surface, boundaryToleranceSurfaceApproach);
0160           }
0161         }
0162       }
0163     }
0164   }
0165 }
0166 
0167 }  // namespace Acts::detail