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