Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-12 09:40:17

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/Geometry/LinearVolumeLookup.hpp"
0010 
0011 #include "Acts/Geometry/TrackingVolume.hpp"
0012 
0013 #include <algorithm>
0014 
0015 #include "VolumeLookupImpl.hpp"
0016 
0017 namespace Acts {
0018 LinearVolumeLookup::LinearVolumeLookup(const TrackingVolume& world,
0019                                        const Config& config,
0020                                        const Logger& logger)
0021     : m_root(world), m_config(config) {
0022   if (m_config.warningThreshold.has_value() &&
0023       logger.doPrint(Logging::WARNING)) {
0024     warnIfNeeded(logger);
0025   }
0026 }
0027 
0028 void LinearVolumeLookup::warnIfNeeded(const Logger& logger) const {
0029   const auto warningThreshold = *m_config.warningThreshold;
0030   std::size_t largest = 0;
0031   // apply() cannot prune subtrees: explicit child lookups end this scan's
0032   // scope, and their descendants must not contribute to its warning.
0033   auto inspect = [&](auto&& self, const TrackingVolume& volume) -> void {
0034     largest = std::max(
0035         {largest, volume.volumes().size(), volume.denseVolumes().size()});
0036     if (const auto confined = volume.confinedVolumes()) {
0037       for (const auto& child : confined->arrayObjects()) {
0038         if (child && child->volumeLookup() == nullptr) {
0039           self(self, *child);
0040         }
0041       }
0042     }
0043     for (const auto& child : volume.volumes()) {
0044       if (child.volumeLookup() == nullptr) {
0045         self(self, child);
0046       }
0047     }
0048   };
0049   inspect(inspect, m_root);
0050   if (largest > warningThreshold) {
0051     ACTS_WARNING("Linear volume lookup scans up to "
0052                  << largest << " siblings (warning threshold "
0053                  << warningThreshold
0054                  << "). Consider RzGrid via "
0055                     "setVolumeLookupFactory on a blueprint node.");
0056   }
0057 }
0058 
0059 const LinearVolumeLookup::Config& LinearVolumeLookup::config() const {
0060   return m_config;
0061 }
0062 
0063 const TrackingVolume* LinearVolumeLookup::findLowest(
0064     const GeometryContext& gctx, const Vector3& position,
0065     double tolerance) const {
0066   return detail::linearVolumeScan(m_root, gctx, position, tolerance);
0067 }
0068 const TrackingVolume* detail::linearVolumeScan(const TrackingVolume& root,
0069                                                const GeometryContext& gctx,
0070                                                const Vector3& position,
0071                                                double tol) {
0072   if (!root.inside(gctx, position, tol)) {
0073     return nullptr;
0074   }
0075 
0076   // confined static volumes - highest hierarchy
0077   if (const auto confined = root.confinedVolumes()) {
0078     const TrackingVolume* volume = confined->object(position).get();
0079     if (volume != nullptr) {
0080       return volume->lowestTrackingVolume(gctx, position, tol);
0081     }
0082   }
0083 
0084   // search for dense volumes
0085   for (const auto& denseVolume : root.denseVolumes()) {
0086     if (denseVolume->inside(gctx, position, tol)) {
0087       return denseVolume.get();
0088     }
0089   }
0090 
0091   for (const auto& volume : root.volumes()) {
0092     if (volume.inside(gctx, position, tol)) {
0093       return volume.lowestTrackingVolume(gctx, position, tol);
0094     }
0095   }
0096 
0097   // there is no lower sub structure
0098   return &root;
0099 }
0100 }  // namespace Acts