Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:10:16

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019 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 http://mozilla.org/MPL/2.0/.
0008 
0009 ///////////////////////////////////////////////////////////////////
0010 // BinAdjustment.hpp, Acts project
0011 ///////////////////////////////////////////////////////////////////
0012 
0013 #pragma once
0014 
0015 #include "Acts/Definitions/Algebra.hpp"
0016 #include "Acts/Surfaces/CylinderBounds.hpp"
0017 #include "Acts/Surfaces/RadialBounds.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0021 #include "Acts/Utilities/BinUtility.hpp"
0022 
0023 #include <stdexcept>
0024 
0025 namespace Acts {
0026 
0027 /// @brief adjust the BinUtility bu to the dimensions of radial bounds
0028 ///
0029 /// @param bu BinUtility at source
0030 /// @param rBounds the Radial bounds to adjust to
0031 /// @param transform Transform for the adjusted @c BinUtility
0032 ///
0033 /// @return new updated BinUtiltiy
0034 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0035                                           const RadialBounds& rBounds,
0036                                           const Transform3& transform) {
0037   // Default constructor
0038   BinUtility uBinUtil(transform);
0039 
0040   // The parameters from the cylinder bounds
0041   double minR = rBounds.get(RadialBounds::eMinR);
0042   double maxR = rBounds.get(RadialBounds::eMaxR);
0043   double minPhi = rBounds.get(RadialBounds::eAveragePhi) -
0044                   rBounds.get(RadialBounds::eHalfPhiSector);
0045   double maxPhi = rBounds.get(RadialBounds::eAveragePhi) +
0046                   rBounds.get(RadialBounds::eHalfPhiSector);
0047   // Retrieve the binning data
0048   const std::vector<BinningData>& bData = bu.binningData();
0049   // Loop over the binning data and adjust the dimensions
0050   for (auto& bd : bData) {
0051     // The binning value
0052     BinningValue bval = bd.binvalue;
0053     // Throw exceptions is stuff doesn't make sense:
0054     // - not the right binning value
0055     // - not equidistant
0056     if (bd.type == arbitrary) {
0057       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0058     } else if (bval != binR && bval != binPhi) {
0059       throw std::invalid_argument("Disc binning must be: phi, r");
0060     }
0061     float min = 0., max = 0.;
0062     // Perform the value adjustment
0063     if (bval == binPhi) {
0064       min = minPhi;
0065       max = maxPhi;
0066     } else {
0067       min = minR;
0068       max = maxR;
0069     }
0070     // Create the updated BinningData
0071     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0072     uBinUtil += BinUtility(uBinData);
0073   }
0074   return uBinUtil;
0075 }
0076 
0077 /// @brief adjust the BinUtility bu to the dimensions of cylinder bounds
0078 ///
0079 /// @param bu BinUtility at source
0080 /// @param cBounds the Cylinder bounds to adjust to
0081 /// @param transform Transform for the adjusted @c BinUtility
0082 ///
0083 /// @return new updated BinUtiltiy
0084 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0085                                           const CylinderBounds& cBounds,
0086                                           const Transform3& transform) {
0087   // Default constructor
0088   BinUtility uBinUtil(transform);
0089 
0090   // The parameters from the cylinder bounds
0091   double cR = cBounds.get(CylinderBounds::eR);
0092   double cHz = cBounds.get(CylinderBounds::eHalfLengthZ);
0093   double avgPhi = cBounds.get(CylinderBounds::eAveragePhi);
0094   double halfPhi = cBounds.get(CylinderBounds::eHalfPhiSector);
0095   double minPhi = avgPhi - halfPhi;
0096   double maxPhi = avgPhi + halfPhi;
0097 
0098   // Retrieve the binning data
0099   const std::vector<BinningData>& bData = bu.binningData();
0100   // Loop over the binning data and adjust the dimensions
0101   for (auto& bd : bData) {
0102     // The binning value
0103     BinningValue bval = bd.binvalue;
0104     // Throw exceptions if stuff doesn't make sense:
0105     // - not the right binning value
0106     // - not equidistant
0107     if (bd.type == arbitrary) {
0108       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0109     } else if (bval != binRPhi && bval != binPhi && bval != binZ) {
0110       throw std::invalid_argument("Cylinder binning must be: rphi, phi, z");
0111     }
0112     float min = 0., max = 0.;
0113     // Perform the value adjustment
0114     if (bval == binPhi) {
0115       min = minPhi;
0116       max = maxPhi;
0117     } else if (bval == binRPhi) {
0118       min = cR * minPhi;
0119       max = cR * maxPhi;
0120     } else {
0121       min = -cHz;
0122       max = cHz;
0123     }
0124     // Create the updated BinningData
0125     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0126     uBinUtil += BinUtility(uBinData);
0127   }
0128   return uBinUtil;
0129 }
0130 
0131 /// @brief adjust the BinUtility bu to the dimensions of plane bounds
0132 ///
0133 /// @param bu BinUtility at source
0134 /// @param pBounds the Rectangle bounds to adjust to
0135 /// @param transform Transform for the adjusted @c BinUtility
0136 ///
0137 /// @return new updated BinUtiltiy
0138 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0139                                           const RectangleBounds& pBounds,
0140                                           const Transform3& transform) {
0141   // Default constructor
0142   BinUtility uBinUtil(transform);
0143 
0144   // The parameters from the cylinder bounds
0145   double minX = pBounds.get(RectangleBounds::eMinX);
0146   double minY = pBounds.get(RectangleBounds::eMinY);
0147   double maxX = pBounds.get(RectangleBounds::eMaxX);
0148   double maxY = pBounds.get(RectangleBounds::eMaxY);
0149 
0150   // Retrieve the binning data
0151   const std::vector<BinningData>& bData = bu.binningData();
0152   // Loop over the binning data and adjust the dimensions
0153   for (auto& bd : bData) {
0154     // The binning value
0155     BinningValue bval = bd.binvalue;
0156     // Throw exceptions if stuff doesn't make sense:
0157     // - not the right binning value
0158     // - not equidistant
0159     if (bd.type == arbitrary) {
0160       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0161     } else if (bval != binX && bval != binY) {
0162       throw std::invalid_argument("Rectangle binning must be: x, y. ");
0163     }
0164     float min = 0., max = 0.;
0165     // Perform the value adjustment
0166     if (bval == binX) {
0167       min = minX;
0168       max = maxX;
0169     } else {
0170       min = minY;
0171       max = maxY;
0172     }
0173     // Create the updated BinningData
0174     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0175     uBinUtil += BinUtility(uBinData);
0176   }
0177 
0178   return uBinUtil;
0179 }
0180 
0181 /// @brief adjust the BinUtility bu to the dimensions of plane bounds
0182 ///
0183 /// @param bu BinUtility at source
0184 /// @param pBounds the Trapezoid bounds to adjust to
0185 /// @param transform Transform for the adjusted @c BinUtility
0186 ///
0187 /// @return new updated BinUtiltiy
0188 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0189                                           const TrapezoidBounds& pBounds,
0190                                           const Transform3& transform) {
0191   // Default constructor
0192   BinUtility uBinUtil(transform);
0193 
0194   // The parameters from the cylinder bounds
0195 
0196   double halfX = std::max(pBounds.get(Acts::TrapezoidBounds::eHalfLengthXnegY),
0197                           pBounds.get(Acts::TrapezoidBounds::eHalfLengthXposY));
0198   double halfY = pBounds.get(Acts::TrapezoidBounds::eHalfLengthY);
0199 
0200   // Retrieve the binning data
0201   const std::vector<BinningData>& bData = bu.binningData();
0202   // Loop over the binning data and adjust the dimensions
0203   for (auto& bd : bData) {
0204     // The binning value
0205     BinningValue bval = bd.binvalue;
0206     // Throw exceptions if stuff doesn't make sense:
0207     // - not the right binning value
0208     // - not equidistant
0209     if (bd.type == arbitrary) {
0210       throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0211     } else if (bval != binX && bval != binY) {
0212       throw std::invalid_argument("Rectangle binning must be: x, y. ");
0213     }
0214     float min = 0., max = 0.;
0215     // Perform the value adjustment
0216     if (bval == binX) {
0217       min = -1 * halfX;
0218       max = halfX;
0219     } else {
0220       min = -1 * halfY;
0221       max = halfY;
0222     }
0223     // Create the updated BinningData
0224     BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0225     uBinUtil += BinUtility(uBinData);
0226   }
0227 
0228   return uBinUtil;
0229 }
0230 
0231 /// @brief adjust the BinUtility bu to a surface
0232 ///
0233 /// @param bu BinUtility at source
0234 /// @param surface Surface to which the adjustment is being done
0235 /// @param gctx Geometry context to get the surfaces transform
0236 ///
0237 /// @return new updated BinUtiltiy
0238 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0239                                           const Surface& surface,
0240                                           const GeometryContext& gctx) {
0241   // The surface type is a cylinder
0242   if (surface.type() == Surface::Cylinder) {
0243     // Cast to Cylinder bounds and return
0244     auto cBounds = dynamic_cast<const CylinderBounds*>(&(surface.bounds()));
0245     // Return specific adjustment
0246     return adjustBinUtility(bu, *cBounds, surface.transform(gctx));
0247 
0248   } else if (surface.type() == Surface::Disc) {
0249     // Cast to Cylinder bounds and return
0250     auto rBounds = dynamic_cast<const RadialBounds*>(&(surface.bounds()));
0251     // Return specific adjustment
0252     return adjustBinUtility(bu, *rBounds, surface.transform(gctx));
0253   } else if (surface.type() == Surface::Plane) {
0254     if (surface.bounds().type() == SurfaceBounds::eRectangle) {
0255       // Cast to Plane bounds and return
0256       auto pBounds = dynamic_cast<const RectangleBounds*>(&(surface.bounds()));
0257       // Return specific adjustment
0258       return adjustBinUtility(bu, *pBounds, surface.transform(gctx));
0259     } else if (surface.bounds().type() == SurfaceBounds::eTrapezoid) {
0260       // Cast to Plane bounds and return
0261       auto pBounds = dynamic_cast<const TrapezoidBounds*>(&(surface.bounds()));
0262       // Return specific adjustment
0263       return adjustBinUtility(bu, *pBounds, surface.transform(gctx));
0264     } else {
0265       throw std::invalid_argument(
0266           "Bin adjustment not implemented for this type of plane surface yet!");
0267     }
0268   }
0269 
0270   throw std::invalid_argument(
0271       "Bin adjustment not implemented for this surface yet!");
0272 }
0273 
0274 }  // namespace Acts