File indexing completed on 2026-05-27 07:24:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/propagator/detail/jacobian_cylindrical.hpp"
0011
0012 #include "detray/geometry/mask.hpp"
0013 #include "detray/geometry/shapes/cylinder2D.hpp"
0014 #include "detray/propagator/detail/jacobian_engine.hpp"
0015 #include "detray/tracks/tracks.hpp"
0016
0017
0018 #include "detray/test/framework/types.hpp"
0019
0020
0021 #include <gtest/gtest.h>
0022
0023
0024 #include <limits>
0025
0026 using namespace detray;
0027
0028 using test_algebra = test::algebra;
0029 using scalar = test::scalar;
0030 using point3 = test::point3;
0031 using vector3 = test::vector3;
0032 using transform3 = test::transform3;
0033
0034 constexpr scalar isclose{1e-5f};
0035
0036
0037 GTEST_TEST(detray_propagator, jacobian_cylindrical2D) {
0038 using jac_engine = detail::jacobian_engine<test_algebra>;
0039 using frame_type = cylindrical2D<test_algebra>;
0040
0041
0042 const vector3 z = {0.f, 0.f, 1.f};
0043 const vector3 x = {1.f, 0.f, 0.f};
0044 const point3 t = {2.f, 3.f, 4.f};
0045 const transform3 trf(t, z, x);
0046
0047 const point3 global1 = {3.4142136f, 4.4142136f, 9.f};
0048 const vector3 mom = {1.f, 2.f, 3.f};
0049 const scalar time{0.1f};
0050 const scalar charge{-1.f};
0051
0052 const scalar r{2.f};
0053 const scalar hz{detail::invalid_value<scalar>()};
0054 mask<cylinder2D, test_algebra> cyl{0u, r, -hz, hz};
0055
0056
0057 const free_track_parameters<test_algebra> free_params(global1, time, mom,
0058 charge);
0059
0060 const auto bound_vec =
0061 detail::free_to_bound_vector<cylindrical2D<test_algebra>>(trf,
0062 free_params);
0063 const auto free_params2 = detail::bound_to_free_vector(trf, cyl, bound_vec);
0064
0065
0066 ASSERT_NEAR(getter::element(bound_vec.bound_local(), e_bound_loc0),
0067 r * constant<scalar>::pi_4, isclose);
0068 ASSERT_NEAR(getter::element(bound_vec.bound_local(), e_bound_loc1), 5.f,
0069 isclose);
0070 ASSERT_NEAR(bound_vec.phi(), 1.1071487f, isclose);
0071 ASSERT_NEAR(bound_vec.theta(), 0.64052231f, isclose);
0072 ASSERT_NEAR(bound_vec.qop(), -1.f / 3.7416574f, isclose);
0073 ASSERT_NEAR(bound_vec.time(), 0.1f, isclose);
0074
0075
0076 for (unsigned int i = 0u; i < 8u; i++) {
0077 ASSERT_NEAR(free_params[i], free_params2[i], isclose);
0078 }
0079
0080
0081 const bound_matrix<test_algebra> J =
0082 jac_engine::free_to_bound_jacobian<frame_type>(trf, free_params) *
0083 jac_engine::bound_to_free_jacobian<frame_type>(trf, cyl, bound_vec);
0084
0085 for (unsigned int i = 0u; i < 6u; i++) {
0086 for (unsigned int j = 0u; j < 6u; j++) {
0087 if (i == j) {
0088 EXPECT_NEAR(getter::element(J, i, j), 1.f, isclose);
0089 } else {
0090 EXPECT_NEAR(getter::element(J, i, j), 0.f, isclose);
0091 }
0092 }
0093 }
0094 }
0095
0096 GTEST_TEST(detray_propagator, jacobian_concentric_cylindrical2D) {
0097 using jac_engine = detail::jacobian_engine<test_algebra>;
0098 using frame_type = concentric_cylindrical2D<test_algebra>;
0099
0100
0101 const transform3 identity{};
0102
0103 const point3 global1{constant<scalar>::sqrt2, constant<scalar>::sqrt2,
0104 static_cast<scalar>(9.f)};
0105 const vector3 mom{1.f, 2.f, 3.f};
0106 const scalar time{0.1f};
0107 const scalar charge{-1.f};
0108
0109 const scalar r{2.f};
0110 const scalar hz{detail::invalid_value<scalar>()};
0111 mask<concentric_cylinder2D, test_algebra> cyl{0u, r, -hz, hz};
0112
0113
0114 const free_track_parameters<test_algebra> free_params(global1, time, mom,
0115 charge);
0116
0117 const auto bound_vec =
0118 detail::free_to_bound_vector<concentric_cylindrical2D<test_algebra>>(
0119 identity, free_params);
0120 const auto free_params2 =
0121 detail::bound_to_free_vector(identity, cyl, bound_vec);
0122
0123
0124 ASSERT_NEAR(getter::element(bound_vec.bound_local(), e_bound_loc0),
0125 vector::phi(global1), isclose);
0126 ASSERT_NEAR(getter::element(bound_vec.bound_local(), e_bound_loc1), 9.f,
0127 isclose);
0128 ASSERT_NEAR(bound_vec.phi(), vector::phi(mom), isclose);
0129 ASSERT_NEAR(bound_vec.theta(), vector::theta(mom), isclose);
0130 ASSERT_NEAR(bound_vec.qop(), -1.f / vector::norm(mom), isclose);
0131 ASSERT_NEAR(bound_vec.time(), 0.1f, isclose);
0132
0133
0134 for (unsigned int i = 0u; i < 8u; i++) {
0135 ASSERT_NEAR(free_params[i], free_params2[i], isclose);
0136 }
0137
0138
0139 const bound_matrix<test_algebra> J =
0140 jac_engine::free_to_bound_jacobian<frame_type>(identity, free_params) *
0141 jac_engine::bound_to_free_jacobian<frame_type>(identity, cyl, bound_vec);
0142
0143 for (unsigned int i = 0u; i < 6u; i++) {
0144 for (unsigned int j = 0u; j < 6u; j++) {
0145 if (i == j) {
0146 EXPECT_NEAR(getter::element(J, i, j), 1.f, isclose);
0147 } else {
0148 EXPECT_NEAR(getter::element(J, i, j), 0.f, isclose);
0149 }
0150 }
0151 }
0152 }