Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-08 07:47:05

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/SurfaceArrayNavigationPolicy.hpp"
0010 
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Geometry/ProtoLayer.hpp"
0013 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0014 #include "Acts/Geometry/TrackingVolume.hpp"
0015 #include "Acts/Navigation/NavigationStream.hpp"
0016 
0017 namespace Acts {
0018 
0019 SurfaceArrayNavigationPolicy::SurfaceArrayNavigationPolicy(
0020     const GeometryContext& gctx, const TrackingVolume& volume,
0021     const Logger& logger, Config config)
0022     : m_volume(volume) {
0023   ACTS_VERBOSE("Constructing SurfaceArrayNavigationPolicy for volume "
0024                << volume.volumeName());
0025   ACTS_VERBOSE("~> Layer type is " << config.layerType);
0026   ACTS_VERBOSE("~> bins: " << config.bins.first << " x " << config.bins.second);
0027 
0028   SurfaceArrayCreator::Config sacConfig;
0029   // This is important! detray does not support separate transforms for the
0030   // grids (yet?), so we need to ensure that the volume and surface array
0031   // transforms are at most translated relative to one another, so that the
0032   // projection is correct.
0033   sacConfig.doPhiBinningOptimization = false;
0034   SurfaceArrayCreator sac{sacConfig, logger.clone("SrfArrCrtr")};
0035 
0036   std::vector<std::shared_ptr<const Surface>> surfaces;
0037   surfaces.reserve(volume.surfaces().size());
0038   for (const auto& surface : volume.surfaces()) {
0039     if (!surface.isSensitive()) {
0040       continue;
0041     }
0042     surfaces.push_back(surface.getSharedPtr());
0043   }
0044 
0045   ACTS_VERBOSE("Number of surfaces passed to the surface array creation: "
0046                << surfaces.size());
0047   if (surfaces.empty()) {
0048     ACTS_ERROR("The number of surfaces is 0!");
0049     throw std::runtime_error("Cannot create surface array with zero surfaces");
0050   }
0051 
0052   ProtoLayer protoLayer(
0053       gctx, surfaces, Transform3{volume.localToGlobalTransform(gctx).linear()});
0054 
0055   if (config.layerType == LayerType::Disc) {
0056     auto [binsR, binsPhi] = config.bins;
0057 
0058     double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0059 
0060     ACTS_VERBOSE("Creating a disk Layer:");
0061     ACTS_VERBOSE(" - at Z position    = " << layerZ);
0062     ACTS_VERBOSE(" - from Z min/max   = "
0063                  << protoLayer.min(AxisDirection::AxisZ, false) << " / "
0064                  << protoLayer.max(AxisDirection::AxisZ, false));
0065     ACTS_VERBOSE(" - with R min/max   = "
0066                  << protoLayer.min(AxisDirection::AxisR, false) << " (-"
0067                  << protoLayer.envelope[AxisDirection::AxisR][0u] << ") / "
0068                  << protoLayer.max(AxisDirection::AxisR, false) << " (+"
0069                  << protoLayer.envelope[AxisDirection::AxisR][1u] << ")");
0070     ACTS_VERBOSE(" - with phi min/max = "
0071                  << protoLayer.min(AxisDirection::AxisPhi, false) << " / "
0072                  << protoLayer.max(AxisDirection::AxisPhi, false));
0073     ACTS_VERBOSE(" - # of modules    = " << surfaces.size() << " ordered in ( "
0074                                          << binsR << " x " << binsPhi << ")");
0075 
0076     Transform3 layerTransform{Translation3(0, 0, layerZ)};
0077 
0078     m_surfaceArray = sac.surfaceArrayOnDisc(
0079         gctx, std::move(surfaces), binsR, binsPhi, protoLayer, layerTransform);
0080   } else if (config.layerType == LayerType::Cylinder) {
0081     auto [binsPhi, binsZ] = config.bins;
0082 
0083     double layerR = protoLayer.medium(AxisDirection::AxisR);
0084     double layerZ = protoLayer.medium(AxisDirection::AxisZ);
0085     double layerHalfZ = 0.5 * protoLayer.range(AxisDirection::AxisZ);
0086     double layerThickness = protoLayer.range(AxisDirection::AxisR);
0087 
0088     ACTS_VERBOSE("Creating a cylindrical Layer:");
0089     ACTS_VERBOSE(" - with layer R     = " << layerR);
0090     ACTS_VERBOSE(" - from R min/max   = "
0091                  << protoLayer.min(AxisDirection::AxisR, false) << " / "
0092                  << protoLayer.max(AxisDirection::AxisR, false));
0093     ACTS_VERBOSE(" - with R thickness = " << layerThickness);
0094     ACTS_VERBOSE("   - incl envelope  = "
0095                  << protoLayer.envelope[AxisDirection::AxisR][0u] << " / "
0096                  << protoLayer.envelope[AxisDirection::AxisR][1u]);
0097     ACTS_VERBOSE(" - with z min/max   = "
0098                  << protoLayer.min(AxisDirection::AxisZ, false) << " (-"
0099                  << protoLayer.envelope[AxisDirection::AxisZ][0u] << ") / "
0100                  << protoLayer.max(AxisDirection::AxisZ, false) << " (+"
0101                  << protoLayer.envelope[AxisDirection::AxisZ][1u] << ")");
0102     ACTS_VERBOSE(" - z center         = " << layerZ);
0103     ACTS_VERBOSE(" - halflength z     = " << layerHalfZ);
0104 
0105     Transform3 layerTransform{Translation3(0, 0, layerZ)};
0106     ACTS_VERBOSE(" - layer z shift    = " << -layerZ);
0107 
0108     m_surfaceArray = sac.surfaceArrayOnCylinder(
0109         gctx, std::move(surfaces), binsPhi, binsZ, protoLayer, layerTransform);
0110   } else if (config.layerType == LayerType::Plane) {
0111     ACTS_ERROR("Plane layers are not yet supported");
0112     throw std::invalid_argument("Plane layers are not yet supported");
0113   } else {
0114     throw std::invalid_argument("Unknown layer type");
0115   }
0116 
0117   if (!m_surfaceArray) {
0118     ACTS_ERROR("Failed to create surface array");
0119     throw std::runtime_error("Failed to create surface array");
0120   }
0121 }
0122 
0123 void SurfaceArrayNavigationPolicy::initializeCandidates(
0124     [[maybe_unused]] const GeometryContext& gctx,
0125     const NavigationArguments& args, NavigationPolicyState& /*state*/,
0126     AppendOnlyNavigationStream& stream, const Logger& logger) const {
0127   ACTS_VERBOSE("SrfArrNavPol (volume=" << m_volume.volumeName() << ")");
0128 
0129   ACTS_VERBOSE("Querying sensitive surfaces at " << args.position.transpose());
0130   const auto sensitiveSurfaces =
0131       m_surfaceArray->neighbors(gctx, args.position, args.direction);
0132   ACTS_VERBOSE("~> Surface array reports " << sensitiveSurfaces.size()
0133                                            << " sensitive surfaces");
0134 
0135   for (const Surface* surface : sensitiveSurfaces) {
0136     stream.addSurfaceCandidate(*surface, args.tolerance);
0137   };
0138 }
0139 
0140 const Acts::SurfaceArray& SurfaceArrayNavigationPolicy::surfaceArray() const {
0141   return *m_surfaceArray;
0142 }
0143 
0144 void SurfaceArrayNavigationPolicy::connect(NavigationDelegate& delegate) const {
0145   connectDefault<SurfaceArrayNavigationPolicy>(delegate);
0146 }
0147 
0148 SurfaceArrayNavigationPolicy::~SurfaceArrayNavigationPolicy() = default;
0149 
0150 }  // namespace Acts