Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-31 07:48:48

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/DetrayConversionUtils.hpp"
0010 
0011 #include <limits>
0012 #include <numbers>
0013 #include <stdexcept>
0014 
0015 using namespace Acts;
0016 
0017 namespace ActsPlugins {
0018 
0019 detray::axis::label DetrayConversionUtils::convertAxisDirection(
0020     AxisDirection bValue) {
0021   switch (bValue) {
0022     case AxisDirection::AxisX:
0023       return detray::axis::label::e_x;
0024     case AxisDirection::AxisY:
0025       return detray::axis::label::e_y;
0026     case AxisDirection::AxisZ:
0027       return detray::axis::label::e_z;
0028     case AxisDirection::AxisR:
0029       return detray::axis::label::e_r;
0030     case AxisDirection::AxisPhi:
0031       return detray::axis::label::e_phi;
0032     case AxisDirection::AxisRPhi:
0033       return detray::axis::label::e_rphi;
0034     default:
0035       throw std::invalid_argument(
0036           "DetrayMaterialConverter: unknown binning value detected.");
0037   }
0038 }
0039 
0040 detray::axis::bounds DetrayConversionUtils::convertBinningOption(
0041     BinningOption bOption) {
0042   // That's a bit of a mind bender, but the conversion is correct
0043   // closed -> axis are closed, i.e. circular
0044   // open -> axis are not closed, but the range is closed (no overflow bin) ->
0045   // closed
0046   switch (bOption) {
0047     case BinningOption::closed:
0048       return detray::axis::bounds::e_circular;
0049     case BinningOption::open:
0050       return detray::axis::bounds::e_closed;
0051     default:
0052       throw std::invalid_argument(
0053           "DetrayMaterialConverter: unknown binning option detected.");
0054   }
0055 }
0056 
0057 detray::axis::binning DetrayConversionUtils::convertBinningType(
0058     BinningType bType) {
0059   switch (bType) {
0060     case BinningType::equidistant:
0061       return detray::axis::binning::e_regular;
0062     case BinningType::arbitrary:
0063       return detray::axis::binning::e_irregular;
0064     default:
0065       throw std::invalid_argument(
0066           "DetrayMaterialConverter: unknown binning type detected.");
0067   }
0068 }
0069 
0070 detray::io::axis_payload DetrayConversionUtils::convertBinningData(
0071     const BinningData& bData) {
0072   detray::io::axis_payload axisPayload;
0073 
0074   // Number of bins
0075   axisPayload.bins = bData.bins();
0076   // Set the binning type
0077   axisPayload.binning = convertBinningType(bData.type);
0078   // Set the binning option
0079   axisPayload.bounds = convertBinningOption(bData.option);
0080   // Set the binning value
0081   axisPayload.label = convertAxisDirection(bData.binvalue);
0082   // Set the binning range
0083   axisPayload.edges = {};
0084   if (bData.type == BinningType::equidistant) {
0085     axisPayload.edges = {bData.min, bData.max};
0086   } else {
0087     axisPayload.edges.insert(axisPayload.edges.end(),
0088                              bData.boundaries().begin(),
0089                              bData.boundaries().end());
0090   }
0091   return axisPayload;
0092 }
0093 
0094 detray::io::axis_payload DetrayConversionUtils::convertAxis(
0095     const Acts::IAxis& axis) {
0096   detray::io::axis_payload axisPayload;
0097 
0098   // Number of bins
0099   axisPayload.bins = axis.getNBins();
0100   // Set the binning type and bin edges
0101   if (axis.isEquidistant()) {
0102     axisPayload.binning = detray::axis::binning::e_regular;
0103     axisPayload.edges = {axis.getMin(), axis.getMax()};
0104   } else {
0105     axisPayload.binning = detray::axis::binning::e_irregular;
0106     axisPayload.edges = axis.getBinEdges();
0107   }
0108   // Axis boundary behaviour
0109   switch (axis.getBoundaryType()) {
0110     using enum Acts::AxisBoundaryType;
0111     case Open:
0112       // Open interval: Overflow bins
0113       axisPayload.bounds = detray::axis::bounds::e_open;
0114       break;
0115     case Closed:
0116       // Periodic boundary conditions
0117       axisPayload.bounds = detray::axis::bounds::e_circular;
0118       break;
0119     case Bound:
0120       // Closed interval: no overflow bins
0121       axisPayload.bounds = detray::axis::bounds::e_closed;
0122       break;
0123   }
0124 
0125   return axisPayload;
0126 }
0127 
0128 detray::io::surface_material_payload DetrayConversionUtils::convertMaterialSlab(
0129     const Acts::MaterialSlab& slab) {
0130   detray::io::surface_material_payload matPayload;
0131 
0132   // Fill the material parameters and the thickness
0133   const auto& material = slab.material();
0134   matPayload.thickness = slab.thickness();
0135   matPayload.mat = detray::io::material_param_payload{
0136       {material.X0(), material.L0(), material.Ar(), material.Z(),
0137        material.massDensity(), material.molarDensity(), 0.}};
0138   matPayload.type = detray::io::material_id::slab;
0139 
0140   return matPayload;
0141 }
0142 
0143 detray::io::transform_payload DetrayConversionUtils::convertTransform(
0144     const Acts::Transform3& transform) {
0145   detray::io::transform_payload trfPayload;
0146 
0147   Eigen::Map<Acts::Vector3> tr{trfPayload.tr.data()};
0148   tr = transform.translation();
0149 
0150   Eigen::Map<Acts::SquareMatrix3> rot{trfPayload.rot.data()};
0151   rot = transform.linear();
0152 
0153   return trfPayload;
0154 }
0155 
0156 std::tuple<Acts::BinUtility, bool> DetrayConversionUtils::convertBinUtilityTo2D(
0157     const Acts::BinUtility& bUtility) {
0158   using enum Acts::AxisDirection;
0159   using enum Acts::BinningOption;
0160 
0161   // Return as-is if already 2D
0162   if (bUtility.dimensions() == 2u) {
0163     // Check if we need to swap for rphi-z -> z-rphi
0164     if (bUtility.binningData()[0u].binvalue == AxisZ &&
0165         bUtility.binningData()[1u].binvalue == AxisRPhi) {
0166       BinUtility nbUtility(bUtility.binningData()[1u]);
0167       nbUtility += BinUtility{bUtility.binningData()[0u]};
0168       return {std::move(nbUtility), true};
0169     }
0170     return {bUtility, false};
0171   }
0172 
0173   // Convert 1D to 2D
0174   if (bUtility.dimensions() == 1u) {
0175     BinUtility result = bUtility;
0176     bool swapped = false;
0177 
0178     if (bUtility.binningData()[0u].binvalue == AxisX) {
0179       // Turn to X-Y
0180       result += BinUtility(1u, std::numeric_limits<float>::lowest(),
0181                            std::numeric_limits<float>::max(), closed, AxisY);
0182     } else if (bUtility.binningData()[0u].binvalue == AxisY) {
0183       // Turn to X-Y (swap needed)
0184       BinUtility nbUtility(1u, std::numeric_limits<float>::lowest(),
0185                            std::numeric_limits<float>::max(), closed, AxisX);
0186       nbUtility += bUtility;
0187       result = std::move(nbUtility);
0188       swapped = true;
0189     } else if (bUtility.binningData()[0u].binvalue == AxisR) {
0190       // Turn to R-Phi
0191       result +=
0192           BinUtility(1u, -std::numbers::pi, std::numbers::pi, closed, AxisPhi);
0193     } else if (bUtility.binningData()[0u].binvalue == AxisZ) {
0194       // Turn to RPhi-Z (swap needed)
0195       BinUtility nbUtility(1u, -std::numbers::pi, std::numbers::pi, closed,
0196                            AxisPhi);
0197       nbUtility += bUtility;
0198       result = std::move(nbUtility);
0199       swapped = true;
0200     } else {
0201       throw std::invalid_argument("Unsupported binning for Detray");
0202     }
0203 
0204     return {result, swapped};
0205   }
0206 
0207   throw std::invalid_argument(
0208       "DetrayConversionUtils: BinUtility must be 1D or 2D");
0209 }
0210 
0211 }  // namespace ActsPlugins