Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:24:18

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 /// DetraySurfaceGridsConverter converts surface grids from acts to detray
0025 /// format
0026 
0027 // convertGrid
0028 template <typename grid_type>
0029 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0030 DetraySurfaceGridsConverter::convertGrid(const grid_type& grid, bool swapAxis) {
0031   // Get the grid axes & potentially swap them
0032   detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd;
0033 
0034   auto axes = grid.axes();
0035   if (swapAxis && grid_type::DIM == 2u) {
0036     std::swap(axes[0u], axes[1u]);
0037   }
0038 
0039   // Fill the axes in the order they are
0040   for (unsigned int ia = 0u; ia < grid_type::DIM; ++ia) {
0041     detray::io::axis_payload axis_pd =
0042         DetrayConversionUtils::convertAxis(*axes[ia]);
0043     axis_pd.label = static_cast<detray::axis::label>(ia);
0044     grid_pd.axes.push_back(axis_pd);  // push axis to axes
0045   }
0046 
0047   // 1D connections
0048   if constexpr (grid_type::DIM == 1u) {
0049     for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0050       // Lookup bin
0051       typename grid_type::index_t lbin;
0052       detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0053 
0054       lbin[0u] = ib0;
0055       grid_bin_pd.content = grid.atLocalBins(lbin);
0056       // Corrected bin for detray
0057       lbin[0u] = ib0 - 1u;
0058       grid_bin_pd.loc_index =
0059           std::vector<unsigned int>(lbin.begin(), lbin.end());
0060       grid_pd.bins.push_back(grid_bin_pd);
0061     }
0062   }
0063 
0064   // 2D connections
0065   if constexpr (grid_type::DIM == 2u) {
0066     for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0067       for (unsigned int ib1 = 1u; ib1 <= axes[1u]->getNBins(); ++ib1) {
0068         typename grid_type::index_t lbin;
0069         // Lookup bin - respect swap (if it happened) for the lookup
0070         lbin[0u] = swapAxis ? ib1 : ib0;
0071         lbin[1u] = swapAxis ? ib0 : ib1;
0072 
0073         detray::io::grid_bin_payload<std::size_t> grid_bin_pd;
0074 
0075         nlohmann::json jBin;
0076         grid_bin_pd.content = grid.atLocalBins(lbin);
0077         // Corrected bin for detray
0078         lbin[0u] = ib0 - 1u;
0079         lbin[1u] = ib1 - 1u;
0080         grid_bin_pd.loc_index =
0081             std::vector<unsigned int>(lbin.begin(), lbin.end());
0082         grid_pd.bins.push_back(grid_bin_pd);
0083       }
0084     }
0085   }
0086 
0087   return grid_pd;
0088 }
0089 
0090 template <typename index_grid>
0091 detray::io::grid_payload<std::size_t, detray::io::accel_id>
0092 DetraySurfaceGridsConverter::convertImpl(const index_grid& indexGrid) {
0093   bool swapAxes = true;
0094 
0095   if constexpr (index_grid::grid_type::DIM == 2u) {
0096     // Check for axis swap
0097     swapAxes = (indexGrid.casts[0u] == AxisDirection::AxisZ &&
0098                 indexGrid.casts[1u] == AxisDirection::AxisPhi);
0099   }
0100 
0101   detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd =
0102       convertGrid(indexGrid.grid, swapAxes);
0103 
0104   return grid_pd;
0105 }
0106 
0107 // convert
0108 template <typename instance_type>
0109 std::optional<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0110 DetraySurfaceGridsConverter::convert(
0111     const Experimental::InternalNavigationDelegate& delegate,
0112     [[maybe_unused]] const instance_type& refInstance) {
0113   using GridType =
0114       typename instance_type::template grid_type<std::vector<std::size_t>>;
0115   // Defining a Delegate type
0116   using ConversionDelegateType =
0117       Experimental::IndexedSurfacesAllPortalsNavigation<
0118           GridType, Experimental::IndexGridNavigation>;
0119   using SubDelegateType = Experimental::IndexGrid<GridType>;
0120 
0121   // Get the instance
0122   const auto* instance = delegate.instance();
0123   auto castedDelegate = dynamic_cast<const ConversionDelegateType*>(instance);
0124 
0125   if (castedDelegate != nullptr) {
0126     // Get the surface updator
0127     detray::io::grid_payload<std::size_t, detray::io::accel_id> grid_pd;
0128     auto indexedSurfaces = std::get<SubDelegateType>(castedDelegate->updators);
0129     grid_pd = convertImpl<SubDelegateType>(indexedSurfaces);
0130     grid_pd.grid_link.type = static_cast<detray::io::accel_id>(
0131         DetrayJsonHelper::accelerationLink(indexedSurfaces.casts));
0132     grid_pd.grid_link.index = std::numeric_limits<std::size_t>::max();
0133     return grid_pd;
0134   }
0135 
0136   return std::nullopt;
0137 }
0138 
0139 template <typename... Args>
0140 std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0141 DetraySurfaceGridsConverter::unrollConvert(
0142     const Experimental::InternalNavigationDelegate& delegate,
0143     TypeList<Args...> /*unused*/) {
0144   std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0145       grid_pds;
0146 
0147   const auto convertAndPush = [&grid_pds](const auto& adele,
0148                                           const auto& args) -> void {
0149     auto grid_pd = convert(adele, args);
0150     if (grid_pd.has_value()) {
0151       grid_pds.push_back(*grid_pd);
0152     }
0153   };
0154 
0155   (convertAndPush(delegate, Args{}), ...);
0156 
0157   return grid_pds;
0158 }
0159 
0160 detray::io::detector_grids_payload<std::size_t, detray::io::accel_id>
0161 DetraySurfaceGridsConverter::convertSurfaceGrids(
0162     const Experimental::Detector& detector) {
0163   detray::io::detector_grids_payload<std::size_t, detray::io::accel_id>
0164       grids_pd = detray::io::detector_grids_payload<std::size_t,
0165                                                     detray::io::accel_id>();
0166   auto volumes = detector.volumes();
0167 
0168   for (const auto [iv, volume] : enumerate(volumes)) {
0169     std::vector<detray::io::grid_payload<std::size_t, detray::io::accel_id>>
0170         grid_pd = unrollConvert(volume->internalNavigation(),
0171                                 GridAxisGenerators::PossibleAxes{});
0172 
0173     for (auto& grid : grid_pd) {
0174       detray::io::single_link_payload lnk;
0175       lnk.link = iv;
0176       grid.owner_link = lnk;
0177       grids_pd.grids[iv].push_back(grid);
0178     }
0179   }
0180   return grids_pd;
0181 }
0182 
0183 }  // namespace ActsPlugins