Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 09:54:59

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/BoundaryCheck.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   BoundaryCheck boundaryCheck;
0029 
0030   NavigationObjectCandidate(AnyIntersectionObject _object,
0031                             const Surface* _representation,
0032                             BoundaryCheck _boundaryCheck)
0033       : object(_object),
0034         representation(_representation),
0035         boundaryCheck(std::move(_boundaryCheck)) {}
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(gctx, position, direction,
0043                                                     boundaryCheck, 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(gctx, position, direction,
0049                                                     boundaryCheck, 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(gctx, position, direction,
0055                                                     boundaryCheck, 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   BoundaryCheck boundaryCheck;
0068 
0069   IntersectionCandidate(SurfaceIntersection _intersection,
0070                         detail::AnyIntersectionObject _anyObject,
0071                         BoundaryCheck _boundaryCheck)
0072       : intersection(std::move(_intersection)),
0073         anyObject(_anyObject),
0074         boundaryCheck(std::move(_boundaryCheck)) {}
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, const BoundaryCheck& boundaryCheckSurfaceApproach,
0099     const Logger& logger) {
0100   auto addCandidate = [&](AnyIntersectionObject object,
0101                           const Surface* representation,
0102                           const BoundaryCheck& boundaryCheck) {
0103     candidates.emplace_back(object, representation, boundaryCheck);
0104   };
0105 
0106   // Get all boundary candidates
0107   {
0108     ACTS_VERBOSE("Searching for boundaries.");
0109 
0110     const auto& boundaries = volume.boundarySurfaces();
0111 
0112     ACTS_VERBOSE("Found " << boundaries.size() << " boundaries.");
0113 
0114     for (const auto& boundary : boundaries) {
0115       addCandidate(boundary.get(), &boundary->surfaceRepresentation(),
0116                    BoundaryCheck(true));
0117     }
0118   }
0119 
0120   // Get all layer candidates
0121   {
0122     ACTS_VERBOSE("Searching for layers.");
0123 
0124     const auto& layers = volume.confinedLayers()->arrayObjects();
0125 
0126     ACTS_VERBOSE("Found " << layers.size() << " layers.");
0127 
0128     for (const auto& layer : layers) {
0129       if (!layer->resolve(resolveSensitive, resolveMaterial, resolvePassive)) {
0130         continue;
0131       }
0132 
0133       if (!resolveSensitive ||
0134           layer->surfaceRepresentation().surfaceMaterial() != nullptr) {
0135         addCandidate(layer.get(), &layer->surfaceRepresentation(),
0136                      BoundaryCheck(true));
0137       }
0138 
0139       if (layer->approachDescriptor() != nullptr) {
0140         const auto& approaches =
0141             layer->approachDescriptor()->containedSurfaces();
0142 
0143         for (const auto& approach : approaches) {
0144           addCandidate(layer.get(), approach, BoundaryCheck(true));
0145         }
0146       }
0147 
0148       // Get all surface candidates from layers
0149       {
0150         ACTS_VERBOSE("Searching for surfaces.");
0151 
0152         if (layer->surfaceArray() != nullptr) {
0153           const auto& surfaces = layer->surfaceArray()->surfaces();
0154 
0155           ACTS_VERBOSE("Found " << surfaces.size() << " surfaces.");
0156 
0157           for (const auto& surface : surfaces) {
0158             addCandidate(surface, surface, boundaryCheckSurfaceApproach);
0159           }
0160         }
0161       }
0162     }
0163   }
0164 }
0165 
0166 }  // namespace Acts::detail