Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-16 08:03:43

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 // convertAxis
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 // convertGrid
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   // Get the grid axes & potentially swap them
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   // Fill the axes in the order they are
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);  // push axis to axes
0063   }
0064 
0065   // 1D connections
0066   if constexpr (grid_type::DIM == 1u) {
0067     for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0068       // Lookup bin
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       // Corrected bin for detray
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   // 2D connections
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         // Lookup bin - respect swap (if it happened) for the lookup
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         // Corrected bin for detray
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     // Check for axis swap
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 // convert
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   // Defining a Delegate type
0134   using ConversionDelegateType =
0135       Experimental::IndexedSurfacesAllPortalsNavigation<
0136           GridType, Experimental::IndexedSurfacesNavigation>;
0137   using SubDelegateType = Experimental::IndexedSurfacesNavigation<GridType>;
0138 
0139   // Get the instance
0140   const auto* instance = delegate.instance();
0141   auto castedDelegate = dynamic_cast<const ConversionDelegateType*>(instance);
0142 
0143   if (castedDelegate != nullptr) {
0144     // Get the surface updator
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...> /*unused*/) {
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 }  // namespace ActsPlugins