Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-14 08:13:28

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/Navigation/FrustumNavigationPolicy.hpp"
0010 
0011 #include "Acts/Geometry/TrivialPortalLink.hpp"
0012 
0013 namespace Acts::Experimental {
0014 
0015 namespace {
0016 
0017 /// Helper function  to check whether the portal sits on the original boundary
0018 /// surface of the volume
0019 /// @param link: Pointer to the portallink to check
0020 /// @param volume: Reference to the volume which boundaries need to be found
0021 bool leadsOutside(const PortalLinkBase *link, const TrackingVolume &volume) {
0022   const auto *trivialLink = dynamic_cast<const TrivialPortalLink *>(link);
0023   if (trivialLink == nullptr) {
0024     return false;
0025   }
0026 
0027   const TrackingVolume *volumeLink = &trivialLink->volume();
0028   if (volumeLink == &volume || volumeLink->motherVolume() == &volume) {
0029     return false;
0030   }
0031   return true;
0032 }
0033 
0034 }  // namespace
0035 
0036 FrustumNavigationPolicy::FrustumNavigationPolicy(const GeometryContext &gctx,
0037                                                  const TrackingVolume &volume,
0038                                                  const Logger &logger,
0039                                                  const Config &config) {
0040   ACTS_VERBOSE("Constructing FrustumNavigationPolicy for volume "
0041                << volume.volumeName());
0042   m_id = volume.geometryId();
0043   std::vector<BoundingBox *> prims;
0044   m_boxes.push_back(std::make_unique<BoundingBox>(volume.boundingBox(gctx)));
0045   prims.push_back(m_boxes.back().get());
0046   for (auto &vol : volume.volumes()) {
0047     ACTS_VERBOSE("add volume " << vol.volumeName()
0048                                << " to list of bounding boxes");
0049     m_boxes.push_back(std::make_unique<BoundingBox>(vol.boundingBox(gctx)));
0050     prims.push_back(m_boxes.back().get());
0051   }
0052   m_topBox =
0053       Acts::BoundingBoxHierarchy::makeOctree(m_boxes, prims, config.depth);
0054 
0055   for (const auto &portal : volume.portals()) {
0056     if (leadsOutside(portal.getLink(Direction::AlongNormal()), volume) ||
0057         leadsOutside(portal.getLink(Direction::OppositeNormal()), volume)) {
0058       m_cachedPortals.push_back(&portal);
0059     }
0060   }
0061 }
0062 
0063 void FrustumNavigationPolicy::initializeCandidates(
0064     const GeometryContext & /*gctx*/, const NavigationArguments &args,
0065     NavigationPolicyState &state, AppendOnlyNavigationStream &stream,
0066     const Logger &logger) const {
0067   ACTS_VERBOSE("FrustumNavigationPolicy Candidates initialization for volume "
0068                << m_id);
0069   auto &s = state.as<State>();
0070   // Reset the frustum from the NavigationArguments
0071   s.frustum = Frustum3(args.position, args.direction, s.openingAngle);
0072   Frustum3 frustum = s.frustum;
0073   ACTS_VERBOSE("Frustum origin " << s.frustum.origin() << ", frustum dir "
0074                                  << s.frustum.dir());
0075   Acts::BoundingBoxHierarchy::visitIntersecting(
0076       frustum, m_topBox, [this, &stream, &logger](const Volume &entity) {
0077         const TrackingVolume *tvol =
0078             dynamic_cast<const TrackingVolume *>(&entity);
0079         ACTS_VERBOSE("Get portals from volume " << tvol->volumeName());
0080         if (tvol->geometryId() == m_id) {
0081           for (const Portal *portal : m_cachedPortals) {
0082             stream.addPortalCandidate(*portal);
0083           }
0084         } else {
0085           for (const auto &portal : tvol->portals()) {
0086             stream.addPortalCandidate(portal);
0087           }
0088         }
0089       });
0090   ACTS_VERBOSE(
0091       "FrustumNavigationPolicy Candidates initialization done for volume "
0092       << this->m_id);
0093 }
0094 
0095 void FrustumNavigationPolicy::connect(NavigationDelegate &delegate) const {
0096   connectDefault<FrustumNavigationPolicy>(delegate);
0097 }
0098 
0099 bool FrustumNavigationPolicy::isValid(const GeometryContext & /*gctx*/,
0100                                       const NavigationArguments &args,
0101                                       NavigationPolicyState &state,
0102                                       const Logger &logger) const {
0103   // Check if we leave the frustum, reset candidates if so
0104   auto &s = state.as<State>();
0105   double costheta =
0106       args.position.normalized().dot(s.frustum.origin().normalized());
0107   // Compare to half the frustum opening angle
0108   if (costheta < std::cos(s.openingAngle / 2)) {
0109     ACTS_DEBUG("FrustumNavigationPolicy: outside frustum");
0110     return false;
0111   } else {
0112     ACTS_DEBUG("FrustumNavigationPolicy: frustum still ok");
0113     return true;
0114   }
0115 }
0116 
0117 void FrustumNavigationPolicy::createState(
0118     const GeometryContext & /*gctx*/, const NavigationArguments &args,
0119     NavigationPolicyStateManager &stateManager, const Logger &logger) const {
0120   ACTS_DEBUG("create FrustumNavigationPolicy state");
0121   auto &s = stateManager.pushState<State>();
0122   s.openingAngle = std::numbers::pi / 4;
0123   s.frustum = Frustum3(args.position, args.direction, s.openingAngle);
0124 }
0125 
0126 void FrustumNavigationPolicy::popState(
0127     NavigationPolicyStateManager &stateManager, const Logger &logger) const {
0128   ACTS_DEBUG("remove FrustumNavigationPolicy state");
0129   stateManager.popState();
0130 }
0131 }  // namespace Acts::Experimental