File indexing completed on 2025-06-21 08:08:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/MultiWireVolumeBuilder.hpp"
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0013 #include "Acts/Geometry/TrapezoidPortalShell.hpp"
0014 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0015 #include "Acts/Navigation/InternalNavigation.hpp"
0016 #include "Acts/Navigation/MultiLayerNavigationPolicy.hpp"
0017 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0018 #include "Acts/Surfaces/SurfaceArray.hpp"
0019 #include "Acts/Utilities/Helpers.hpp"
0020 #include "Acts/Utilities/StringHelpers.hpp"
0021
0022 namespace Acts::Experimental {
0023
0024 MultiWireVolumeBuilder::MultiWireVolumeBuilder(
0025 const Config& config, std::unique_ptr<const Logger> logger)
0026 : m_config(config), m_logger(std::move(logger)) {
0027 if (m_config.mlSurfaces.empty()) {
0028 throw std::invalid_argument(
0029 "MultiWireStructureBuilder: No surfaces are given");
0030 } else if (m_config.binning.size() != 2u) {
0031 throw ::std::invalid_argument(
0032 "MultiWireStructureBuilder: Invalid binning provided");
0033 }
0034 }
0035
0036 std::unique_ptr<TrackingVolume> MultiWireVolumeBuilder::buildVolume(
0037 const GeometryContext& gctx) const {
0038
0039
0040 ACTS_VERBOSE("Building a tracking volume with name "
0041 << m_config.name << " ,translation"
0042 << toString(m_config.transform.translation())
0043 << " and number of surfaces " << m_config.mlSurfaces.size());
0044
0045 const auto& bounds =
0046 dynamic_pointer_cast<TrapezoidVolumeBounds>(m_config.bounds);
0047 if (bounds == nullptr) {
0048 throw std::runtime_error(
0049 "MultiWireVolumeBuilder: Invalid bounds - trapezoidal needed");
0050 }
0051
0052 std::unique_ptr<TrackingVolume> trackingVolume =
0053 std::make_unique<TrackingVolume>(m_config.transform, bounds,
0054 m_config.name);
0055
0056 SingleTrapezoidPortalShell portalShell(*trackingVolume);
0057 portalShell.applyToVolume();
0058
0059
0060 for (auto& surface : m_config.mlSurfaces) {
0061 trackingVolume->addSurface(surface);
0062 }
0063
0064 auto [protoAxisA, expansionA] = m_config.binning.at(0);
0065 auto [protoAxisB, expansionB] = m_config.binning.at(1);
0066
0067
0068 const auto& iaxisA = protoAxisA.getAxis();
0069 const auto& iaxisB = protoAxisB.getAxis();
0070
0071 if (iaxisA.getType() != AxisType::Equidistant ||
0072 iaxisB.getType() != AxisType::Equidistant) {
0073 throw std::runtime_error(
0074 "MultiWireVolumeBuilder: Binning axes need to be equidistant");
0075 }
0076
0077 Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisA(
0078 iaxisA.getBinEdges().front(), iaxisA.getBinEdges().back(),
0079 iaxisA.getNBins());
0080
0081 Axis<AxisType::Equidistant, AxisBoundaryType::Bound> axisB(
0082 iaxisB.getBinEdges().front(), iaxisB.getBinEdges().back(),
0083 iaxisB.getNBins());
0084
0085 Grid<std::vector<std::size_t>, decltype(axisA), decltype(axisB)> grid(axisA,
0086 axisB);
0087
0088
0089 IndexedSurfacesNavigation<decltype(grid)> indexedGrid(
0090 std::move(grid),
0091 {protoAxisA.getAxisDirection(), protoAxisB.getAxisDirection()});
0092
0093
0094
0095
0096 TryAllNavigationPolicy::Config tryAllConfig;
0097 tryAllConfig.portals = true;
0098 tryAllConfig.sensitives = false;
0099
0100 TryAllNavigationPolicy tryAllPolicy(gctx, *trackingVolume, *m_logger,
0101 tryAllConfig);
0102
0103
0104
0105
0106 MultiLayerNavigationPolicy::Config navConfig;
0107 navConfig.binExpansion = {expansionA, expansionB};
0108
0109 std::unique_ptr<NavigationPolicyFactory> factory =
0110 NavigationPolicyFactory::make()
0111 .add<TryAllNavigationPolicy>(tryAllConfig)
0112 .add<MultiLayerNavigationPolicy>(navConfig, indexedGrid)
0113 .asUniquePtr();
0114
0115 auto policyBase = factory->build(gctx, *trackingVolume, *m_logger);
0116
0117 trackingVolume->setNavigationPolicy(std::move(policyBase));
0118
0119 return trackingVolume;
0120 }
0121
0122 }