File indexing completed on 2026-04-08 07:47:05
0001
0002
0003
0004
0005
0006
0007
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
0030
0031
0032
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& ,
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 }