File indexing completed on 2026-05-27 07:24:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
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
0021 #include <ostream>
0022
0023 namespace detray {
0024
0025 template <concepts::algebra algebra_t>
0026 struct bound_parameters_vector {
0027
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
0035 using vector_type = bound_vector<algebra_t>;
0036
0037
0038
0039
0040 bound_parameters_vector() = default;
0041
0042
0043 DETRAY_HOST_DEVICE
0044 explicit bound_parameters_vector(const vector_type& vec) : m_vector(vec) {
0045 assert(!this->is_invalid());
0046 }
0047
0048
0049
0050
0051
0052
0053
0054
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
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
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
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
0097 DETRAY_HOST_DEVICE
0098 const vector_type& vector() const { return m_vector; }
0099
0100
0101 DETRAY_HOST_DEVICE
0102 vector_type& vector() { return m_vector; }
0103
0104
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
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
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
0128 DETRAY_HOST_DEVICE
0129 scalar_type phi() const { return getter::element(m_vector, e_bound_phi, 0u); }
0130
0131
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
0139 DETRAY_HOST_DEVICE
0140 scalar_type theta() const {
0141 return getter::element(m_vector, e_bound_theta, 0u);
0142 }
0143
0144
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
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
0164 DETRAY_HOST_DEVICE
0165 scalar_type time() const {
0166 return getter::element(m_vector, e_bound_time, 0u);
0167 }
0168
0169
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
0177 DETRAY_HOST_DEVICE
0178 scalar_type qop() const {
0179 return getter::element(m_vector, e_bound_qoverp, 0u);
0180 }
0181
0182
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
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
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
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
0216 DETRAY_HOST_DEVICE
0217 vector3_type mom(const scalar_type q) const { return p(q) * dir(); }
0218
0219
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
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
0236
0237
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
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
0267
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
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
0280 using parameter_vector_type = bound_parameters_vector<algebra_t>;
0281 using covariance_type = bound_matrix<algebra_t>;
0282
0283
0284
0285
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
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
0321 DETRAY_HOST_DEVICE
0322 const geometry::identifier& surface_link() const { return m_identifier; }
0323
0324
0325 DETRAY_HOST_DEVICE
0326 void set_surface_link(geometry::identifier link) { m_identifier = link; }
0327
0328
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
0336 DETRAY_HOST_DEVICE
0337 covariance_type& covariance() { return m_covariance; }
0338
0339
0340 DETRAY_HOST_DEVICE
0341 const covariance_type& covariance() const { return m_covariance; }
0342
0343
0344 DETRAY_HOST_DEVICE
0345 void set_covariance(const covariance_type& c) { m_covariance = c; }
0346
0347
0348
0349
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
0360 return (m_covariance == matrix::zero<covariance_type>());
0361 }
0362
0363 private:
0364
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
0377 covariance_type m_covariance = matrix::zero<covariance_type>();
0378
0379 geometry::identifier m_identifier{};
0380 };
0381
0382 }