Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:35

0001 #ifndef VECGEOM_SURFACE_WINDOWMASK_H
0002 #define VECGEOM_SURFACE_WINDOWMASK_H
0003 
0004 #ifndef WINDOW_ACCURATE_SAFETY
0005 #define WINDOW_ACCURATE_SAFETY 0
0006 #endif
0007 
0008 #include <VecGeom/surfaces/base/CommonTypes.h>
0009 
0010 namespace vgbrep {
0011 
0012 /// @brief Rectangular masks on plane surfaces.
0013 /// @tparam Real_t Precision type
0014 template <typename Real_t>
0015 struct WindowMask {
0016   using value_type = Real_t;
0017   Range<Real_t> rangeU; ///< Rectangle limits on x axis.
0018   Range<Real_t> rangeV; ///< Rectangle limits on y axis.
0019 
0020   WindowMask() = default;
0021   template <typename Real_i>
0022   WindowMask(Real_i u1, Real_i u2, Real_i v1, Real_i v2)
0023       : rangeU(static_cast<Real_t>(u1), static_cast<Real_t>(u2)),
0024         rangeV(static_cast<Real_t>(v1), static_cast<Real_t>(v2))
0025   {
0026   }
0027   template <typename Real_i>
0028   WindowMask(Real_i u, Real_i v)
0029       : rangeU(static_cast<Real_t>(-u), static_cast<Real_t>(u)), rangeV(static_cast<Real_t>(-v), static_cast<Real_t>(v))
0030   {
0031   }
0032   template <typename Real_i>
0033   WindowMask(const WindowMask<Real_i> &other)
0034       : rangeU(static_cast<Real_t>(other.rangeU[0]), static_cast<Real_t>(other.rangeU[1])),
0035         rangeV(static_cast<Real_t>(other.rangeV[0]), static_cast<Real_t>(other.rangeV[1]))
0036   {
0037   }
0038 
0039   /// @brief Get the half-size of the window as Vector2D
0040   /// @return Half-size
0041   Vector2D<Real_t> GetHalfSize() const
0042   {
0043     return Vector2D<Real_t>(0.5 * (rangeU[1] - rangeU[0]), 0.5 * (rangeV[1] - rangeV[0]));
0044   }
0045 
0046   /// @brief Get the center of the box as Vector2D
0047   /// @return Center vector
0048   Vector2D<Real_t> GetCenter() const
0049   {
0050     return Vector2D<Real_t>(0.5 * (rangeU[1] + rangeU[0]), 0.5 * (rangeV[1] + rangeV[0]));
0051   }
0052 
0053   /// @brief Fills the 3D extent of the window
0054   /// @param aMin Bottom extent corner
0055   /// @param aMax Top extent corner
0056   void Extent3D(Vector3D<Real_t> &aMin, Vector3D<Real_t> &aMax) const
0057   {
0058     aMin.Set(rangeU[0], rangeV[0], Real_t(0));
0059     aMax.Set(rangeU[1], rangeV[1], Real_t(0));
0060   }
0061 
0062   /// @brief Returns the extent of the window
0063   /// @param window Extent window to be filled
0064   void GetExtent(WindowMask<Real_t> &window) const
0065   {
0066     window.rangeU = rangeU;
0067     window.rangeV = rangeV;
0068   }
0069 
0070   VECCORE_ATT_HOST_DEVICE
0071   bool Inside(Vector3D<Real_t> const &local) const
0072   {
0073     return (local[0] > vecgeom::MakeMinusTolerant<true, Real_t>(rangeU[0], vecgeom::kToleranceStrict<Real_t>) &&
0074             local[0] < vecgeom::MakePlusTolerant<true, Real_t>(rangeU[1], vecgeom::kToleranceStrict<Real_t>) &&
0075             local[1] > vecgeom::MakeMinusTolerant<true, Real_t>(rangeV[0], vecgeom::kToleranceStrict<Real_t>) &&
0076             local[1] < vecgeom::MakePlusTolerant<true, Real_t>(rangeV[1], vecgeom::kToleranceStrict<Real_t>));
0077   }
0078 
0079   /// @brief Computes safe distance to the frame combining surface and frame safeties.
0080   /// @details Computes first the maximum signed distance to each edge on a single axis. Two versions
0081   ///  are supported:
0082   ///  - under-estimate (default): Just use the maximum between the edge and surface components
0083   ///  - accurate: Zero negative safety components, then use Pythagoras of surface and edge components
0084   /// @param local Projected point in local coordinates
0085   /// @param safetySurf Safety from non-projected point to the frame support surface.
0086   /// @return Safety distance to the rectangle mask.
0087   VECCORE_ATT_HOST_DEVICE
0088   Real_t Safety(Vector3D<Real_t> const &local, Real_t safetySurf, bool &valid) const
0089   {
0090     valid     = true;
0091     Real_t sx = vecCore::math::Max(local[0] - rangeU[1], rangeU[0] - local[0]);
0092     Real_t sy = vecCore::math::Max(local[1] - rangeV[1], rangeV[0] - local[1]);
0093     if (WINDOW_ACCURATE_SAFETY > 0) {
0094       // The following returns the accurate safety at the price of an extra square root per frame
0095       // meaning 6 for a box.
0096       sx = vecCore::math::Max(Real_t(0), sx);
0097       sy = vecCore::math::Max(Real_t(0), sy);
0098       return vecCore::math::Sqrt(sx * sx + sy * sy + safetySurf * safetySurf);
0099     } else {
0100       // The VecGeom box version just returns the maximum
0101       return vecCore::math::Max(sx, sy, safetySurf);
0102     }
0103   }
0104 
0105   /// @brief Safe distance from a point assumed inside the window
0106   /// @details Used on host only for frame checks
0107   /// @param local Projected point in local coordinates
0108   /// @return Safe distance
0109   Real_t SafetyInside(Vector3D<Real_t> const &local) const
0110   {
0111     Vector2D<Real_t> point(local[0], local[1]);
0112     point -= GetCenter();
0113     Real_t safety = (GetHalfSize() - point.Abs()).Min();
0114     return safety;
0115   }
0116 
0117   /// @brief Safe distance from a point assumed outside the window
0118   /// @details Used on host only for frame checks
0119   /// @param local Projected point in local coordinates
0120   /// @return Safe distance
0121   Real_t SafetyOutside(Vector3D<Real_t> const &local) const
0122   {
0123     Vector2D<Real_t> point(local[0], local[1]);
0124     point -= GetCenter();
0125     Real_t safety = (point.Abs() - GetHalfSize()).Max();
0126     return safety;
0127   }
0128 };
0129 
0130 } // namespace vgbrep
0131 
0132 #endif