Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:19

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 "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 /// DetraySurfaceGridsConverter converts surface grids from acts to detray
0023 /// format
0024 
0025 // convertAxis
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 // convertGrid
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   // Get the grid axes & potentially swap them
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   // Fill the axes in the order they are
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);  // push axis to axes
0062   }
0063 
0064   // 1D connections
0065   if constexpr (grid_type::DIM == 1u) {
0066     for (unsigned int ib0 = 1u; ib0 <= axes[0u]->getNBins(); ++ib0) {
0067       // Lookup bin
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       // Corrected bin for detray
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   // 2D connections
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         // Lookup bin - respect swap (if it happened) for the lookup
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         // Corrected bin for detray
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     // Check for axis swap
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 // convert
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   // Defining a Delegate type
0133   using ConversionDelegateType =
0134       Acts::Experimental::IndexedSurfacesAllPortalsNavigation<
0135           GridType, Acts::Experimental::IndexedSurfacesNavigation>;
0136   using SubDelegateType =
0137       Acts::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         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...> /*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 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 }  // namespace Acts