Back to home page

EIC code displayed by LXR

 
 

    


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

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/definitions/indexing.hpp"
0015 #include "detray/definitions/math.hpp"
0016 #include "detray/definitions/track_parametrization.hpp"
0017 #include "detray/definitions/units.hpp"
0018 #include "detray/geometry/identifier.hpp"
0019 
0020 // System include(s)
0021 #include <ostream>
0022 
0023 namespace detray {
0024 
0025 template <concepts::algebra algebra_t>
0026 struct bound_parameters_vector {
0027   /// @name Type definitions for the struct
0028   /// @{
0029   using algebra_type = algebra_t;
0030   using scalar_type = dscalar<algebra_t>;
0031   using point2_type = dpoint2D<algebra_t>;
0032   using vector3_type = dvector3D<algebra_t>;
0033 
0034   // Underlying vector type related to bound track vector.
0035   using vector_type = bound_vector<algebra_t>;
0036 
0037   /// @}
0038 
0039   /// Default constructor
0040   bound_parameters_vector() = default;
0041 
0042   /// Construct from a 6-dim vector of parameters
0043   DETRAY_HOST_DEVICE
0044   explicit bound_parameters_vector(const vector_type& vec) : m_vector(vec) {
0045     assert(!this->is_invalid());
0046   }
0047 
0048   /// Construct from single parameters
0049   ///
0050   /// @param loc_p the bound local position
0051   /// @param phi the global phi angle of the track direction
0052   /// @param theta the global theta angle of the track direction
0053   /// @param qop the q/p value
0054   /// @param t the time
0055   DETRAY_HOST_DEVICE
0056   bound_parameters_vector(const point2_type& loc_p, const scalar_type phi,
0057                           const scalar_type theta, const scalar_type qop,
0058                           const scalar_type t) {
0059     getter::set_block(m_vector, loc_p, e_bound_loc0, 0u);
0060     getter::element(m_vector, e_bound_phi, 0u) = phi;
0061     getter::element(m_vector, e_bound_theta, 0u) = theta;
0062     getter::element(m_vector, e_bound_qoverp, 0u) = qop;
0063     getter::element(m_vector, e_bound_time, 0u) = t;
0064 
0065     assert(!this->is_invalid());
0066   }
0067 
0068   /// @param rhs is the left hand side params for comparison
0069   DETRAY_HOST_DEVICE
0070   bool operator==(const bound_parameters_vector& rhs) const {
0071     for (unsigned int i = 0u; i < e_bound_size; i++) {
0072       const auto lhs_val = getter::element(m_vector, i, 0u);
0073       const auto rhs_val = getter::element(rhs.vector(), i, 0u);
0074 
0075       if (math::fabs(lhs_val - rhs_val) >
0076           std::numeric_limits<scalar_type>::epsilon()) {
0077         return false;
0078       }
0079     }
0080 
0081     return true;
0082   }
0083 
0084   /// Convenience access to the track parameters - const
0085   DETRAY_HOST_DEVICE
0086   scalar_type operator[](const std::size_t i) const {
0087     return getter::element(m_vector, static_cast<unsigned int>(i), 0u);
0088   }
0089 
0090   /// Convenience access to the track parameters - non-const
0091   DETRAY_HOST_DEVICE
0092   decltype(auto) operator[](const std::size_t i) {
0093     return getter::element(m_vector, static_cast<unsigned int>(i), 0u);
0094   }
0095 
0096   /// Access the track parameters as a 6-dim vector - const
0097   DETRAY_HOST_DEVICE
0098   const vector_type& vector() const { return m_vector; }
0099 
0100   /// Access the track parameters as a 6-dim vector - non-const
0101   DETRAY_HOST_DEVICE
0102   vector_type& vector() { return m_vector; }
0103 
0104   /// Set the underlying vector
0105   DETRAY_HOST_DEVICE
0106   void set_vector(const vector_type& v,
0107                   [[maybe_unused]] const bool skip_check = false) {
0108     m_vector = v;
0109     assert(skip_check || !this->is_invalid());
0110   }
0111 
0112   /// @returns the bound local position
0113   DETRAY_HOST_DEVICE
0114   point2_type bound_local() const {
0115     return {getter::element(m_vector, e_bound_loc0, 0u),
0116             getter::element(m_vector, e_bound_loc1, 0u)};
0117   }
0118 
0119   /// Set the bound local position
0120   DETRAY_HOST_DEVICE
0121   void set_bound_local(const point2_type& pos) {
0122     assert(math::isfinite(pos[0]));
0123     assert(math::isfinite(pos[1]));
0124     getter::set_block(m_vector, pos, e_bound_loc0, 0u);
0125   }
0126 
0127   /// @returns the global phi angle
0128   DETRAY_HOST_DEVICE
0129   scalar_type phi() const { return getter::element(m_vector, e_bound_phi, 0u); }
0130 
0131   /// Set the global phi angle
0132   DETRAY_HOST_DEVICE
0133   void set_phi(const scalar_type phi) {
0134     assert(math::fabs(phi) <= constant<scalar_type>::pi);
0135     getter::element(m_vector, e_bound_phi, 0u) = phi;
0136   }
0137 
0138   /// @returns the global theta angle
0139   DETRAY_HOST_DEVICE
0140   scalar_type theta() const {
0141     return getter::element(m_vector, e_bound_theta, 0u);
0142   }
0143 
0144   /// Set the global theta angle
0145   DETRAY_HOST_DEVICE
0146   void set_theta(const scalar_type theta) {
0147     assert(0.f < theta);
0148     assert(theta <= constant<scalar_type>::pi);
0149     getter::element(m_vector, e_bound_theta, 0u) = theta;
0150   }
0151 
0152   /// @returns the global track direction
0153   DETRAY_HOST_DEVICE
0154   vector3_type dir() const {
0155     const scalar_type phi{getter::element(m_vector, e_bound_phi, 0u)};
0156     const scalar_type theta{getter::element(m_vector, e_bound_theta, 0u)};
0157     const scalar_type sinTheta{math::sin(theta)};
0158 
0159     return {math::cos(phi) * sinTheta, math::sin(phi) * sinTheta,
0160             math::cos(theta)};
0161   }
0162 
0163   /// @returns the time
0164   DETRAY_HOST_DEVICE
0165   scalar_type time() const {
0166     return getter::element(m_vector, e_bound_time, 0u);
0167   }
0168 
0169   /// Set the time
0170   DETRAY_HOST_DEVICE
0171   void set_time(const scalar_type t) {
0172     assert(math::isfinite(t));
0173     getter::element(m_vector, e_bound_time, 0u) = t;
0174   }
0175 
0176   /// @returns the q/p value
0177   DETRAY_HOST_DEVICE
0178   scalar_type qop() const {
0179     return getter::element(m_vector, e_bound_qoverp, 0u);
0180   }
0181 
0182   /// Set the q/p value
0183   DETRAY_HOST_DEVICE
0184   void set_qop(const scalar_type qop) {
0185     assert(math::isfinite(qop));
0186     getter::element(m_vector, e_bound_qoverp, 0u) = qop;
0187   }
0188 
0189   /// @returns the q/p_T value
0190   DETRAY_HOST_DEVICE
0191   scalar_type qopT() const {
0192     const scalar_type theta{getter::element(m_vector, e_bound_theta, 0u)};
0193     const scalar_type sinTheta{math::sin(theta)};
0194     assert(sinTheta != 0.f);
0195     return getter::element(m_vector, e_bound_qoverp, 0u) / sinTheta;
0196   }
0197 
0198   /// @returns the q/p_z value
0199   DETRAY_HOST_DEVICE
0200   scalar_type qopz() const {
0201     const scalar_type theta{getter::element(m_vector, e_bound_theta, 0u)};
0202     const scalar_type cosTheta{math::cos(theta)};
0203     assert(cosTheta != 0.f);
0204     return getter::element(m_vector, e_bound_qoverp, 0u) / cosTheta;
0205   }
0206 
0207   /// @returns the absolute momentum
0208   DETRAY_HOST_DEVICE
0209   scalar_type p(const scalar_type q) const {
0210     assert(qop() != 0.f);
0211     assert(q * qop() > 0.f);
0212     return q / qop();
0213   }
0214 
0215   /// @returns the global momentum 3-vector
0216   DETRAY_HOST_DEVICE
0217   vector3_type mom(const scalar_type q) const { return p(q) * dir(); }
0218 
0219   /// @returns the transverse momentum
0220   DETRAY_HOST_DEVICE
0221   scalar_type pT(const scalar_type q) const {
0222     assert(qop() != 0.f);
0223     assert(q * qop() > 0.f);
0224     return math::fabs(q / qop() * vector::perp(dir()));
0225   }
0226 
0227   /// @returns the absolute momentum z-component
0228   DETRAY_HOST_DEVICE
0229   scalar_type pz(const scalar_type q) const {
0230     assert(qop() != 0.f);
0231     assert(q * qop() > 0.f);
0232     return math::fabs(q / qop() * dir()[2]);
0233   }
0234 
0235   /// @param do_check toggle checking (e.g. don't trigger assertions for
0236   /// documented errors)
0237   /// @returns true if the parameter vector contains invalid elements
0238   DETRAY_HOST_DEVICE
0239   constexpr bool is_invalid(const bool do_check = true) const {
0240     if (!do_check) {
0241       return false;
0242     }
0243     bool inv_elem{false};
0244     bool is_all_zero{true};
0245     for (std::size_t i = 0u; i < e_bound_size; ++i) {
0246       inv_elem = inv_elem || !math::isfinite(getter::element(m_vector, i, 0u));
0247       is_all_zero =
0248           is_all_zero && (math::fabs(getter::element(m_vector, i, 0u)) == 0.f);
0249     }
0250 
0251     return (inv_elem || is_all_zero);
0252   }
0253 
0254  private:
0255   /// Transform to a string for debugging output
0256   DETRAY_HOST
0257   friend std::ostream& operator<<(std::ostream& out_stream,
0258                                   const bound_parameters_vector& bparam) {
0259     out_stream << bparam.m_vector;
0260     return out_stream;
0261   }
0262 
0263   vector_type m_vector = matrix::zero<vector_type>();
0264 };
0265 
0266 /// Combine the bound track parameter vector with the covariance and associated
0267 /// surface
0268 template <concepts::algebra algebra_t>
0269 struct bound_track_parameters : public bound_parameters_vector<algebra_t> {
0270   using base_type = bound_parameters_vector<algebra_t>;
0271 
0272   /// @name Type definitions for the struct
0273   /// @{
0274   using algebra_type = algebra_t;
0275   using scalar_type = dscalar<algebra_t>;
0276   using point2_type = dpoint2D<algebra_t>;
0277   using vector3_type = dvector3D<algebra_t>;
0278 
0279   // Shorthand vector/matrix types related to bound track parameters.
0280   using parameter_vector_type = bound_parameters_vector<algebra_t>;
0281   using covariance_type = bound_matrix<algebra_t>;
0282 
0283   /// @}
0284 
0285   /// Default constructor sets the covaraicne to zero
0286   bound_track_parameters() = default;
0287 
0288   DETRAY_HOST_DEVICE
0289   bound_track_parameters(const geometry::identifier sf_idx,
0290                          const parameter_vector_type& vec,
0291                          const covariance_type& cov)
0292       : base_type(vec), m_covariance(cov), m_identifier(sf_idx) {}
0293 
0294   /// @param rhs is the left hand side params for comparison
0295   DETRAY_HOST_DEVICE
0296   bool operator==(const bound_track_parameters& rhs) const {
0297     if (m_identifier != rhs.surface_link()) {
0298       return false;
0299     }
0300 
0301     if (!base_type::operator==(rhs)) {
0302       return false;
0303     }
0304 
0305     for (unsigned int i = 0u; i < e_bound_size; i++) {
0306       for (unsigned int j = 0u; j < e_bound_size; j++) {
0307         const auto lhs_val = getter::element(m_covariance, i, j);
0308         const auto rhs_val = getter::element(rhs.covariance(), i, j);
0309 
0310         if (math::fabs(lhs_val - rhs_val) >
0311             std::numeric_limits<scalar_type>::epsilon()) {
0312           return false;
0313         }
0314       }
0315     }
0316 
0317     return true;
0318   }
0319 
0320   /// @returns the identifier of the associated surface
0321   DETRAY_HOST_DEVICE
0322   const geometry::identifier& surface_link() const { return m_identifier; }
0323 
0324   /// Set the identifier of the associated surface
0325   DETRAY_HOST_DEVICE
0326   void set_surface_link(geometry::identifier link) { m_identifier = link; }
0327 
0328   /// Set the track parameter vector
0329   DETRAY_HOST_DEVICE
0330   void set_parameter_vector(const parameter_vector_type& v,
0331                             const bool skip_check = false) {
0332     this->set_vector(v.vector(), skip_check);
0333   }
0334 
0335   /// @returns the track parameter covariance - non-const
0336   DETRAY_HOST_DEVICE
0337   covariance_type& covariance() { return m_covariance; }
0338 
0339   /// @returns the track parameter covariance - const
0340   DETRAY_HOST_DEVICE
0341   const covariance_type& covariance() const { return m_covariance; }
0342 
0343   /// Set the track parameter covariance
0344   DETRAY_HOST_DEVICE
0345   void set_covariance(const covariance_type& c) { m_covariance = c; }
0346 
0347   /// @param do_check toggle checking (e.g. don't trigger assertions for
0348   /// documented errors)
0349   /// @returns true if the parameter vector contains invalid elements
0350   DETRAY_HOST_DEVICE
0351   constexpr bool is_invalid(const bool do_check = true) const {
0352     if (!do_check) {
0353       return false;
0354     }
0355     if (base_type::is_invalid()) {
0356       return true;
0357     }
0358 
0359     // @TODO: Add tests positive semi-definite, check the determinant etc
0360     return (m_covariance == matrix::zero<covariance_type>());
0361   }
0362 
0363  private:
0364   /// Transform to a string for debugging output
0365   DETRAY_HOST
0366   friend std::ostream& operator<<(std::ostream& out_stream,
0367                                   const bound_track_parameters& bparam) {
0368     out_stream << "Surface: " << bparam.m_identifier << std::endl;
0369     out_stream << "Param.:\n " << static_cast<parameter_vector_type>(bparam)
0370                << std::endl;
0371     out_stream << "Cov.:\n" << bparam.m_covariance;
0372 
0373     return out_stream;
0374   }
0375 
0376   /// Bound covaraicne matrix of the track parameters
0377   covariance_type m_covariance = matrix::zero<covariance_type>();
0378   /// Identifier of the surface the track parameters are associated with
0379   geometry::identifier m_identifier{};
0380 };
0381 
0382 }  // namespace detray