File indexing completed on 2025-10-16 08:03:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/Detray/DetraySurfaceGridsConverter.hpp"
0010
0011 #include "Acts/Detector/Detector.hpp"
0012 #include "Acts/Surfaces/Surface.hpp"
0013 #include "Acts/Utilities/BinningType.hpp"
0014 #include "Acts/Utilities/GridAxisGenerators.hpp"
0015 #include "ActsPlugins/Detray/DetrayConversionUtils.hpp"
0016 #include "ActsPlugins/Json/DetrayJsonHelper.hpp"
0017
0018 #include <stdexcept>
0019
0020 using namespace Acts;
0021
0022 namespace ActsPlugins {
0023
0024
0025
0026
0027
0028 detray::io::axis_payload DetraySurfaceGridsConverter::convertAxis(
0029 const IAxis& ia) {
0030 detray::io::axis_payload axis_pd;
0031 axis_pd.bounds = ia.getBoundaryType() == AxisBoundaryType::Bound
0032 ? detray::axis::bounds::e_closed
0033 : detray::axis::bounds::e_circular;
0034 axis_pd.binning = ia.isEquidistant() ? detray::axis::binning::e_regular
0035 : detray::axis::binning::e_irregular;
0036 axis_pd.bins = ia.getNBins();
0037 if (ia.isEquidistant()) {
0038 axis_pd.edges = {ia.getBinEdges().front(), ia.getBinEdges().back()};
0039 } else {
0040 axis_pd.edges = ia.getBinEdges();
0041 }
0042
0043 return axis_pd;
0044 }
0045
0046
0047 template <typename grid_type>
0048 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0049 DetraySurfaceGridsConverter::convertGrid(const grid_type& grid, bool swapAxis) {
0050
0051 detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd;
0052
0053 auto axes = grid.axes();
0054 if (swapAxis && grid_type::DIM == 2u) {
0055 std::swap(axes[0u], axes[1u]);
0056 }
0057
0058
0059 for (unsigned int ia = 0u; ia < grid_type::DIM; ++ia) {
0060 detray::io::axis_payload axis_pd = convertAxis(*axes[ia]);
0061 axis_pd.label = static_cast<detray::axis::label>(ia);
0062 grid_pd.axes.push_back(axis_pd);
0063 }
0064
0065
0066 if constexpr (grid_type::DIM == 1u) {
0067 for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0068
0069 typename grid_type::index_t lbin;
0070 detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0071
0072 lbin[0u] = ib0;
0073 grid_bin_pd.content = grid.atLocalBins(lbin);
0074
0075 lbin[0u] = ib0 - 1u;
0076 grid_bin_pd.loc_index =
0077 std::vector<unsigned int>(lbin.begin(), lbin.end());
0078 grid_pd.bins.push_back(grid_bin_pd);
0079 }
0080 }
0081
0082
0083 if constexpr (grid_type::DIM == 2u) {
0084 for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0085 for (unsigned int ib1 = 1u; ib1 <= axes[1u]->getNBins(); ++ib1) {
0086 typename grid_type::index_t lbin;
0087
0088 lbin[0u] = swapAxis ? ib1 : ib0;
0089 lbin[1u] = swapAxis ? ib0 : ib1;
0090
0091 detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0092
0093 nlohmann::json jBin;
0094 grid_bin_pd.content = grid.atLocalBins(lbin);
0095
0096 lbin[0u] = ib0 - 1u;
0097 lbin[1u] = ib1 - 1u;
0098 grid_bin_pd.loc_index =
0099 std::vector<unsigned int>(lbin.begin(), lbin.end());
0100 grid_pd.bins.push_back(grid_bin_pd);
0101 }
0102 }
0103 }
0104
0105 return grid_pd;
0106 }
0107
0108 template <typename index_grid>
0109 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0110 DetraySurfaceGridsConverter::convertImpl(const index_grid& indexGrid) {
0111 bool swapAxes = true;
0112
0113 if constexpr (index_grid::grid_type::DIM == 2u) {
0114
0115 swapAxes = (indexGrid.casts[0u] == AxisDirection::AxisZ &&
0116 indexGrid.casts[1u] == AxisDirection::AxisPhi);
0117 }
0118
0119 detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd =
0120 convertGrid(indexGrid.grid, swapAxes);
0121
0122 return grid_pd;
0123 }
0124
0125
0126 template <typename instance_type>
0127 std::optional<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0128 DetraySurfaceGridsConverter::convert(
0129 const Experimental::InternalNavigationDelegate& delegate,
0130 [[maybe_unused]] const instance_type& refInstance) {
0131 using GridType =
0132 typename instance_type::template grid_type<std::vector<std::size_t>>;
0133
0134 using ConversionDelegateType =
0135 Experimental::IndexedSurfacesAllPortalsNavigation<
0136 GridType, Experimental::IndexedSurfacesNavigation>;
0137 using SubDelegateType = 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 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 DetraySurfaceGridsConverter::unrollConvert(
0160 const Experimental::InternalNavigationDelegate& delegate,
0161 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 DetraySurfaceGridsConverter::convertSurfaceGrids(
0180 const 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] : enumerate(volumes)) {
0187 std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0188 grid_pd = unrollConvert(volume->internalNavigation(),
0189 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 }