Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:26

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 // Project include(s)
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/detail/qualifiers.hpp"
0014 #include "detray/geometry/coordinates/cartesian2D.hpp"
0015 #include "detray/geometry/detail/shape_utils.hpp"
0016 
0017 // System include(s)
0018 #include <limits>
0019 #include <string_view>
0020 
0021 namespace detray::tutorial {
0022 
0023 /// @brief Geometrical shape of a square.
0024 ///
0025 /// It is defined by the half length of the square (bounds[0]),
0026 /// and can be checked with a tolerance in t.
0027 class square2D {
0028  public:
0029   /// The name for this shape
0030   static constexpr std::string_view name = "square2D";
0031 
0032   enum boundaries : unsigned int {
0033     e_half_length = 0,  // < boundary value: the half length of the square
0034     e_size = 1u,        // < Number of boundary values for this shape
0035   };
0036 
0037   /// Container definition for the shape boundary values
0038   template <concepts::scalar scalar_t>
0039   using bounds_type = darray<scalar_t, boundaries::e_size>;
0040 
0041   /// Local coordinate frame for boundary checks: cartesian
0042   template <concepts::algebra algebra_t>
0043   using local_frame_type = cartesian2D<algebra_t>;
0044 
0045   /// Result type of a boundary check
0046   template <typename bool_t>
0047   using result_type = bool_t;
0048 
0049   /// Dimension of the local coordinate system
0050   static constexpr std::size_t dim{2u};
0051 
0052   /// @brief Find the minimum distance to any boundary.
0053   ///
0054   /// @note the point is expected to be given in local coordinates by the
0055   /// caller.
0056   ///
0057   /// @param bounds the boundary values for this shape
0058   /// @param loc_p the point to be checked in the local coordinate system
0059   ///
0060   /// @return the minimum distance.
0061   template <concepts::scalar scalar_t, concepts::point point_t>
0062   DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
0063       const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
0064     return math::min(math::fabs(math::fabs(loc_p[0]) - bounds[e_half_length]),
0065                      math::fabs(math::fabs(loc_p[1]) - bounds[e_half_length]));
0066   }
0067 
0068   /// @brief Check boundary values for a local point.
0069   /// @{
0070   /// @param bounds the boundary values for this shape
0071   /// @param trf the surface transform
0072   /// @param glob_p the point to be checked in the global coordinate system
0073   /// @param tol dynamic tolerance determined by caller
0074   ///
0075   /// @return true if the local point lies within the given boundaries.
0076   template <concepts::algebra algebra_t>
0077   DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
0078       const bounds_type<dscalar<algebra_t>> &bounds,
0079       const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
0080       const dscalar<algebra_t> tol =
0081           std::numeric_limits<dscalar<algebra_t>>::epsilon(),
0082       const dscalar<algebra_t> edge_tol = 0.f) const {
0083     // Get the full local position
0084     const dpoint2D<algebra_t> loc_p =
0085         local_frame_type<algebra_t>::global_to_local(trf, glob_p, {});
0086 
0087     return check_boundaries(bounds, loc_p, tol, edge_tol);
0088   }
0089 
0090   /// @brief Check boundary values for a local point.
0091   ///
0092   /// @note the point is expected to be given in local coordinates by the
0093   /// caller. For the conversion from global cartesian coordinates, the
0094   /// nested @c local_frame_type struct can be used.
0095   ///
0096   /// @param bounds the boundary values for this shape
0097   /// @param loc_p the point to be checked in the local coordinate system
0098   /// @param tol dynamic tolerance determined by caller
0099   ///
0100   /// @return true if the local point lies within the given boundaries.
0101   template <concepts::scalar scalar_t, concepts::point point_t>
0102   DETRAY_HOST_DEVICE inline auto check_boundaries(
0103       const bounds_type<scalar_t> &bounds, const point_t &loc_p,
0104       const scalar_t tol = std::numeric_limits<scalar_t>::epsilon()) const {
0105     return (math::fabs(loc_p[0]) <= bounds[e_half_length] + tol &&
0106             math::fabs(loc_p[1]) <= bounds[e_half_length] + tol);
0107   }
0108 
0109   /// @brief Lower and upper point for minimal axis aligned bounding box.
0110   ///
0111   /// Computes the min and max vertices in a local cartesian frame.
0112   ///
0113   /// @param bounds the boundary values for this shape
0114   /// @param env dynamic envelope around the shape
0115   ///
0116   /// @returns and array of coordinates that contains the lower point (first
0117   /// three values) and the upper point (latter three values) .
0118   template <concepts::algebra algebra_t>
0119   DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
0120       const bounds_type<dscalar<algebra_t>> &bounds,
0121       const dscalar<algebra_t> env =
0122           std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
0123     assert(env > 0.f);
0124     const dscalar<algebra_t> bound{bounds[e_half_length] + env};
0125     return {-bound, -bound, -env, bound, bound, env};
0126   }
0127 
0128   /// @brief Measure of the shape: Area
0129   ///
0130   /// @param bounds the boundary values for this shape
0131   ///
0132   /// @returns the rectangle area on the plane
0133   template <concepts::scalar scalar_t>
0134   DETRAY_HOST_DEVICE constexpr scalar_t measure(
0135       const bounds_type<scalar_t> &bounds) const {
0136     return area(bounds);
0137   }
0138 
0139   /// @brief The area of a the shape
0140   ///
0141   /// @param bounds the boundary values for this shape
0142   ///
0143   /// @returns the rectangle area.
0144   template <concepts::scalar scalar_t>
0145   DETRAY_HOST_DEVICE constexpr scalar_t area(
0146       const bounds_type<scalar_t> &bounds) const {
0147     return 4.f * bounds[e_half_length] * bounds[e_half_length];
0148   }
0149 
0150   /// @brief Merge two rectangle shapes
0151   ///
0152   /// @param bounds the boundary values for this shape
0153   /// @param o_bounds the boundary values for the other shape
0154   ///
0155   /// @returns merged bound values
0156   template <concepts::scalar scalar_t>
0157   DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
0158       const bounds_type<scalar_t> &bounds,
0159       const bounds_type<scalar_t> &o_bounds) const {
0160     bounds_type<scalar_t> new_bounds{};
0161 
0162     new_bounds[e_half_length] =
0163         math::max(bounds[e_half_length], o_bounds[e_half_length]);
0164 
0165     return new_bounds;
0166   }
0167 
0168   /// @returns the shapes centroid in local cartesian coordinates
0169   template <concepts::algebra algebra_t>
0170   DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
0171       const bounds_type<dscalar<algebra_t>> & /*unused*/) const {
0172     return {0.f, 0.f, 0.f};
0173   }
0174 
0175   /// Generate vertices in local cartesian frame
0176   ///
0177   /// @param bounds the boundary values for the stereo annulus
0178   /// @param n_seg is the number of line segments
0179   ///
0180   /// @return a generated list of vertices
0181   template <concepts::algebra algebra_t>
0182   DETRAY_HOST dvector<dpoint3D<algebra_t>> vertices(
0183       const bounds_type<dscalar<algebra_t>> &bounds, dindex /*ignored*/) const {
0184     using scalar_t = dscalar<algebra_t>;
0185     using point3_t = dpoint3D<algebra_t>;
0186     const scalar_t hl{bounds[e_half_length]};
0187     constexpr scalar_t zero{0.f};
0188 
0189     // left hand lower corner
0190     point3_t lh_lc{-hl, -hl, zero};
0191     // right hand lower corner
0192     point3_t rh_lc{hl, -hl, zero};
0193     // right hand upper corner
0194     point3_t rh_uc{hl, hl, zero};
0195     // left hand upper corner
0196     point3_t lh_uc{-hl, hl, zero};
0197 
0198     // Return the confining vertices
0199     return {lh_lc, rh_lc, rh_uc, lh_uc};
0200   }
0201 
0202   /// @brief Check consistency of boundary values.
0203   ///
0204   /// @param bounds the boundary values for this shape
0205   /// @param os output stream for error messages
0206   ///
0207   /// @return true if the bounds are consistent.
0208   template <concepts::scalar scalar_t>
0209   DETRAY_HOST constexpr bool check_consistency(
0210       const bounds_type<scalar_t> &bounds, std::ostream &os) const {
0211     if (constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
0212         bounds[e_half_length] < tol) {
0213       os << "DETRAY ERROR (HOST): Half lengths must be in the range (0, "
0214             "numeric_max)"
0215          << std::endl;
0216       return false;
0217     }
0218 
0219     return true;
0220   }
0221 };
0222 
0223 }  // namespace detray::tutorial