Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:55

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