Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:09

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 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0013 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/Volume.hpp"
0016 #include "Acts/Utilities/AxisDefinitions.hpp"
0017 #include "Acts/Utilities/BinUtility.hpp"
0018 
0019 #include <numbers>
0020 #include <stdexcept>
0021 
0022 namespace Acts {
0023 
0024 /// @brief adjust the BinUtility bu to the dimensions of cylinder volume bounds
0025 ///
0026 /// @param bu BinUtility at source
0027 /// @param cBounds the Cylinder volume bounds to adjust to
0028 /// @param transform Transform for the adjusted @c BinUtility
0029 ///
0030 /// @return new updated BinUtiltiy
0031 BinUtility adjustBinUtility(const BinUtility& bu,
0032                             const CylinderVolumeBounds& cBounds,
0033                             const Transform3& transform) {
0034   // Default constructor
0035   BinUtility uBinUtil(transform);
0036   // The parameters from the cylinder bounds
0037   double minR = cBounds.get(CylinderVolumeBounds::eMinR);
0038   double maxR = cBounds.get(CylinderVolumeBounds::eMaxR);
0039   double minPhi = -cBounds.get(CylinderVolumeBounds::eHalfPhiSector);
0040   double maxPhi = cBounds.get(CylinderVolumeBounds::eHalfPhiSector);
0041   double minZ = -cBounds.get(CylinderVolumeBounds::eHalfLengthZ);
0042   double maxZ = cBounds.get(CylinderVolumeBounds::eHalfLengthZ);
0043   // Retrieve the binning data
0044   const std::vector<BinningData>& bData = bu.binningData();
0045   // Loop over the binning data and adjust the dimensions
0046   for (auto& bd : bData) {
0047     // The binning value
0048     AxisDirection bval = bd.binvalue;
0049     // Throw exceptions is stuff doesn't make sense:
0050     // - not the right binning value
0051     // - not equidistant
0052     if (bd.type == arbitrary) {
0053       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0054     } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi &&
0055                bval != AxisDirection::AxisZ) {
0056       throw std::invalid_argument("Cylinder volume binning must be: phi, r, z");
0057     }
0058     float min = 0;
0059     float max = 0;
0060     // Perform the value adjustment
0061     if (bval == AxisDirection::AxisPhi) {
0062       min = minPhi;
0063       max = maxPhi;
0064     } else if (bval == AxisDirection::AxisR) {
0065       min = minR;
0066       max = maxR;
0067     } else if (bval == AxisDirection::AxisZ) {
0068       min = minZ;
0069       max = maxZ;
0070     }
0071     // Create the updated BinningData
0072     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0073     uBinUtil += BinUtility(uBinData);
0074   }
0075 
0076   return uBinUtil;
0077 }
0078 
0079 /// @brief adjust the BinUtility bu to the dimensions of cutout cylinder volume
0080 /// bounds
0081 ///
0082 /// @param bu BinUtility at source
0083 /// @param cBounds the Cutout Cylinder volume bounds to adjust to
0084 /// @param transform Transform for the adjusted @c BinUtility
0085 ///
0086 /// @return new updated BinUtiltiy
0087 BinUtility adjustBinUtility(const BinUtility& bu,
0088                             const CutoutCylinderVolumeBounds& cBounds,
0089                             const Transform3& transform) {
0090   // Default constructor
0091   BinUtility uBinUtil(transform);
0092   // The parameters from the cutout cylinder bounds
0093   double minR = cBounds.get(CutoutCylinderVolumeBounds::eMinR);
0094   double maxR = cBounds.get(CutoutCylinderVolumeBounds::eMaxR);
0095   double minPhi = -std::numbers::pi;
0096   double maxPhi = std::numbers::pi;
0097   double minZ = -cBounds.get(CutoutCylinderVolumeBounds::eHalfLengthZ);
0098   double maxZ = cBounds.get(CutoutCylinderVolumeBounds::eHalfLengthZ);
0099   // Retrieve the binning data
0100   const std::vector<BinningData>& bData = bu.binningData();
0101   // Loop over the binning data and adjust the dimensions
0102   for (auto& bd : bData) {
0103     // The binning value
0104     AxisDirection bval = bd.binvalue;
0105     // Throw exceptions is stuff doesn't make sense:
0106     // - not the right binning value
0107     // - not equidistant
0108     if (bd.type == arbitrary) {
0109       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0110     } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi &&
0111                bval != AxisDirection::AxisZ) {
0112       throw std::invalid_argument(
0113           "Cutout cylinder volume binning must be: phi, r, z");
0114     }
0115     float min = 0;
0116     float max = 0;
0117     // Perform the value adjustment
0118     if (bval == AxisDirection::AxisPhi) {
0119       min = minPhi;
0120       max = maxPhi;
0121     } else if (bval == AxisDirection::AxisR) {
0122       min = minR;
0123       max = maxR;
0124     } else if (bval == AxisDirection::AxisZ) {
0125       min = minZ;
0126       max = maxZ;
0127     }
0128     // Create the updated BinningData
0129     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0130     uBinUtil += BinUtility(uBinData);
0131   }
0132 
0133   return uBinUtil;
0134 }
0135 
0136 /// @brief adjust the BinUtility bu to the dimensions of cuboid volume bounds
0137 ///
0138 /// @param bu BinUtility at source
0139 /// @param cBounds the Cuboid volume bounds to adjust to
0140 /// @param transform Transform for the adjusted @c BinUtility
0141 ///
0142 /// @return new updated BinUtiltiy
0143 BinUtility adjustBinUtility(const BinUtility& bu,
0144                             const CuboidVolumeBounds& cBounds,
0145                             const Transform3& transform) {
0146   // Default constructor
0147   BinUtility uBinUtil(transform);
0148   // The parameters from the cylinder bounds
0149   double minX = -cBounds.get(CuboidVolumeBounds::eHalfLengthX);
0150   double maxX = cBounds.get(CuboidVolumeBounds::eHalfLengthX);
0151   double minY = -cBounds.get(CuboidVolumeBounds::eHalfLengthY);
0152   double maxY = cBounds.get(CuboidVolumeBounds::eHalfLengthY);
0153   double minZ = -cBounds.get(CuboidVolumeBounds::eHalfLengthZ);
0154   double maxZ = cBounds.get(CuboidVolumeBounds::eHalfLengthZ);
0155   // Retrieve the binning data
0156   const std::vector<BinningData>& bData = bu.binningData();
0157   // Loop over the binning data and adjust the dimensions
0158   for (auto& bd : bData) {
0159     // The binning value
0160     AxisDirection bval = bd.binvalue;
0161     // Throw exceptions is stuff doesn't make sense:
0162     // - not the right binning value
0163     // - not equidistant
0164     if (bd.type == arbitrary) {
0165       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0166     } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY &&
0167                bval != AxisDirection::AxisZ) {
0168       throw std::invalid_argument("Cylinder volume binning must be: x, y, z");
0169     }
0170     float min = 0;
0171     float max = 0;
0172     // Perform the value adjustment
0173     if (bval == AxisDirection::AxisX) {
0174       min = minX;
0175       max = maxX;
0176     } else if (bval == AxisDirection::AxisY) {
0177       min = minY;
0178       max = maxY;
0179     } else if (bval == AxisDirection::AxisZ) {
0180       min = minZ;
0181       max = maxZ;
0182     }
0183     // Create the updated BinningData
0184     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0185     uBinUtil += BinUtility(uBinData);
0186   }
0187   return uBinUtil;
0188 }
0189 
0190 /// @brief adjust the BinUtility bu to a volume
0191 ///
0192 /// @param bu BinUtility at source
0193 /// @param volume Volume to which the adjustment is being done
0194 ///
0195 /// @return new updated BinUtiltiy
0196 BinUtility adjustBinUtility(const BinUtility& bu, const Volume& volume) {
0197   auto cyBounds =
0198       dynamic_cast<const CylinderVolumeBounds*>(&(volume.volumeBounds()));
0199   auto cutcylBounds =
0200       dynamic_cast<const CutoutCylinderVolumeBounds*>(&(volume.volumeBounds()));
0201   auto cuBounds =
0202       dynamic_cast<const CuboidVolumeBounds*>(&(volume.volumeBounds()));
0203 
0204   if (cyBounds != nullptr) {
0205     // Cylinder bounds
0206     return adjustBinUtility(bu, *cyBounds, volume.transform());
0207 
0208   } else if (cutcylBounds != nullptr) {
0209     // Cutout Cylinder bounds
0210     return adjustBinUtility(bu, *cutcylBounds, volume.transform());
0211 
0212   } else if (cuBounds != nullptr) {
0213     // Cuboid bounds
0214     return adjustBinUtility(bu, *cuBounds, volume.transform());
0215   }
0216 
0217   throw std::invalid_argument(
0218       "Bin adjustment not implemented for this volume yet!");
0219 }
0220 
0221 }  // namespace Acts