File indexing completed on 2025-01-18 09:12:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Detray/DetraySurfaceGridsConverter.hpp"
0010
0011 #include "Acts/Detector/Detector.hpp"
0012 #include "Acts/Plugins/Detray/DetrayConversionUtils.hpp"
0013 #include "Acts/Plugins/Json/DetrayJsonHelper.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/BinningType.hpp"
0016 #include "Acts/Utilities/GridAxisGenerators.hpp"
0017
0018 #include <stdexcept>
0019
0020 namespace Acts {
0021
0022
0023
0024
0025
0026 detray::io::axis_payload Acts::DetraySurfaceGridsConverter::convertAxis(
0027 const Acts::IAxis& ia) {
0028 detray::io::axis_payload axis_pd;
0029 axis_pd.bounds = ia.getBoundaryType() == Acts::AxisBoundaryType::Bound
0030 ? detray::axis::bounds::e_closed
0031 : detray::axis::bounds::e_circular;
0032 axis_pd.binning = ia.isEquidistant() ? detray::axis::binning::e_regular
0033 : detray::axis::binning::e_irregular;
0034 axis_pd.bins = ia.getNBins();
0035 if (ia.isEquidistant()) {
0036 axis_pd.edges = {ia.getBinEdges().front(), ia.getBinEdges().back()};
0037 } else {
0038 axis_pd.edges = ia.getBinEdges();
0039 }
0040
0041 return axis_pd;
0042 }
0043
0044
0045 template <typename grid_type>
0046 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0047 Acts::DetraySurfaceGridsConverter::convertGrid(const grid_type& grid,
0048 bool swapAxis) {
0049
0050 detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd;
0051
0052 auto axes = grid.axes();
0053 if (swapAxis && grid_type::DIM == 2u) {
0054 std::swap(axes[0u], axes[1u]);
0055 }
0056
0057
0058 for (unsigned int ia = 0u; ia < grid_type::DIM; ++ia) {
0059 detray::io::axis_payload axis_pd = convertAxis(*axes[ia]);
0060 axis_pd.label = static_cast<detray::axis::label>(ia);
0061 grid_pd.axes.push_back(axis_pd);
0062 }
0063
0064
0065 if constexpr (grid_type::DIM == 1u) {
0066 for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0067
0068 typename grid_type::index_t lbin;
0069 detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0070
0071 lbin[0u] = ib0;
0072 grid_bin_pd.content = grid.atLocalBins(lbin);
0073
0074 lbin[0u] = ib0 - 1u;
0075 grid_bin_pd.loc_index =
0076 std::vector<unsigned int>(lbin.begin(), lbin.end());
0077 grid_pd.bins.push_back(grid_bin_pd);
0078 }
0079 }
0080
0081
0082 if constexpr (grid_type::DIM == 2u) {
0083 for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0084 for (unsigned int ib1 = 1u; ib1 <= axes[1u]->getNBins(); ++ib1) {
0085 typename grid_type::index_t lbin;
0086
0087 lbin[0u] = swapAxis ? ib1 : ib0;
0088 lbin[1u] = swapAxis ? ib0 : ib1;
0089
0090 detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0091
0092 nlohmann::json jBin;
0093 grid_bin_pd.content = grid.atLocalBins(lbin);
0094
0095 lbin[0u] = ib0 - 1u;
0096 lbin[1u] = ib1 - 1u;
0097 grid_bin_pd.loc_index =
0098 std::vector<unsigned int>(lbin.begin(), lbin.end());
0099 grid_pd.bins.push_back(grid_bin_pd);
0100 }
0101 }
0102 }
0103
0104 return grid_pd;
0105 }
0106
0107 template <typename index_grid>
0108 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0109 Acts::DetraySurfaceGridsConverter::convertImpl(const index_grid& indexGrid) {
0110 bool swapAxes = true;
0111
0112 if constexpr (index_grid::grid_type::DIM == 2u) {
0113
0114 swapAxes = (indexGrid.casts[0u] == Acts::AxisDirection::AxisZ &&
0115 indexGrid.casts[1u] == Acts::AxisDirection::AxisPhi);
0116 }
0117
0118 detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd =
0119 convertGrid(indexGrid.grid, swapAxes);
0120
0121 return grid_pd;
0122 }
0123
0124
0125 template <typename instance_type>
0126 std::optional<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0127 Acts::DetraySurfaceGridsConverter::convert(
0128 const Acts::Experimental::InternalNavigationDelegate& delegate,
0129 [[maybe_unused]] const instance_type& refInstance) {
0130 using GridType =
0131 typename instance_type::template grid_type<std::vector<std::size_t>>;
0132
0133 using ConversionDelegateType =
0134 Acts::Experimental::IndexedSurfacesAllPortalsNavigation<
0135 GridType, Acts::Experimental::IndexedSurfacesNavigation>;
0136 using SubDelegateType =
0137 Acts::Experimental::IndexedSurfacesNavigation<GridType>;
0138
0139
0140 const auto* instance = delegate.instance();
0141 auto castedDelegate = dynamic_cast<const ConversionDelegateType*>(instance);
0142
0143 if (castedDelegate != nullptr) {
0144
0145 detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd;
0146 auto indexedSurfaces = std::get<SubDelegateType>(castedDelegate->updators);
0147 grid_pd = convertImpl<SubDelegateType>(indexedSurfaces);
0148 grid_pd.grid_link.type = static_cast<detray::io::accel_id>(
0149 Acts::DetrayJsonHelper::accelerationLink(indexedSurfaces.casts));
0150 grid_pd.grid_link.index = std::numeric_limits<std::size_t>::max();
0151 return grid_pd;
0152 }
0153
0154 return std::nullopt;
0155 }
0156
0157 template <typename... Args>
0158 std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0159 Acts::DetraySurfaceGridsConverter::unrollConvert(
0160 const Acts::Experimental::InternalNavigationDelegate& delegate,
0161 Acts::TypeList<Args...> ) {
0162 std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0163 grid_pds;
0164
0165 const auto convertAndPush = [&grid_pds](const auto& adele,
0166 const auto& args) -> void {
0167 auto grid_pd = convert(adele, args);
0168 if (grid_pd.has_value()) {
0169 grid_pds.push_back(*grid_pd);
0170 }
0171 };
0172
0173 (convertAndPush(delegate, Args{}), ...);
0174
0175 return grid_pds;
0176 }
0177
0178 detray::io::detector_grids_payload<std::size_t, detray::io::accel_id>
0179 Acts::DetraySurfaceGridsConverter::convertSurfaceGrids(
0180 const Acts::Experimental::Detector& detector) {
0181 detray::io::detector_grids_payload<std::size_t, detray::io::accel_id>
0182 grids_pd = detray::io::detector_grids_payload<std::size_t,
0183 detray::io::accel_id>();
0184 auto volumes = detector.volumes();
0185
0186 for (const auto [iv, volume] : Acts::enumerate(volumes)) {
0187 std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0188 grid_pd = unrollConvert(volume->internalNavigation(),
0189 Acts::GridAxisGenerators::PossibleAxes{});
0190
0191 for (auto& grid : grid_pd) {
0192 detray::io::single_link_payload lnk;
0193 lnk.link = iv;
0194 grid.owner_link = lnk;
0195 grids_pd.grids[iv].push_back(grid);
0196 }
0197 }
0198 return grids_pd;
0199 }
0200
0201 }