Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-02 08:53:59

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