File indexing completed on 2026-09-27 08:11:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Propagator/detail/SympyCovarianceEngine.hpp"
0010
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/Propagator/detail/JacobianEngine.hpp"
0013 #include "Acts/Propagator/detail/SympyJacobianEngine.hpp"
0014
0015 #include "codegen/sympy_cov_math.hpp"
0016
0017 namespace Acts::detail {
0018
0019 namespace {
0020
0021
0022
0023
0024
0025
0026
0027
0028 void applyBoundCovarianceTransport(const BoundMatrix& jacobian,
0029 const BoundMatrix& in, BoundMatrix& out) {
0030 const auto j = std::span<const double, 36>(jacobian.data(), 36);
0031 const auto c = std::span<const double, 36>(in.data(), 36);
0032 const auto o = std::span<double, 36>(out.data(), 36);
0033 if (jacobian(eBoundQOverP, eBoundQOverP) == 1) {
0034 transportCovarianceToBoundVacuumImpl(c, j, o);
0035 } else {
0036 transportCovarianceToBoundDenseImpl(c, j, o);
0037 }
0038 }
0039
0040 }
0041
0042
0043 using Jacobian = BoundMatrix;
0044 using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
0045
0046 Result<BoundState> sympy::boundState(
0047 const GeometryContext& geoContext, const Surface& surface,
0048 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0049 FreeVector& freeToPathDerivatives, BoundToFreeMatrix& boundToFreeJacobian,
0050 const std::optional<FreeMatrix>& additionalFreeCovariance,
0051 FreeVector& freeParameters, const ParticleHypothesis& particleHypothesis,
0052 bool covTransport, double accumulatedPath,
0053 const FreeToBoundCorrection& freeToBoundCorrection) {
0054
0055 Result<BoundVector> bv =
0056 transformFreeToBoundParameters(freeParameters, surface, geoContext);
0057 if (!bv.ok()) {
0058 return bv.error();
0059 }
0060
0061
0062 std::optional<BoundMatrix> cov = std::nullopt;
0063 if (covTransport) {
0064
0065
0066
0067 Result<void> transportRes = transportCovarianceToBound(
0068 geoContext, surface, boundCovariance, fullTransportJacobian,
0069 freeToPathDerivatives, boundToFreeJacobian, additionalFreeCovariance,
0070 freeParameters, freeToBoundCorrection);
0071 if (!transportRes.ok()) {
0072 return transportRes.error();
0073 }
0074 cov = boundCovariance;
0075 }
0076
0077
0078 return std::make_tuple(
0079 BoundTrackParameters(surface.getSharedPtr(), *bv, std::move(cov),
0080 particleHypothesis),
0081 fullTransportJacobian, accumulatedPath);
0082 }
0083
0084 BoundState sympy::curvilinearState(
0085 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0086 FreeVector& freeToPathDerivatives, BoundToFreeMatrix& boundToFreeJacobian,
0087 const std::optional<FreeMatrix>& additionalFreeCovariance,
0088 const FreeVector& freeParameters,
0089 const ParticleHypothesis& particleHypothesis, bool covTransport,
0090 double accumulatedPath) {
0091 const Vector3& direction = freeParameters.segment<3>(eFreeDir0);
0092
0093
0094 std::optional<BoundMatrix> cov = std::nullopt;
0095 if (covTransport) {
0096
0097
0098
0099 transportCovarianceToCurvilinear(boundCovariance, fullTransportJacobian,
0100 freeToPathDerivatives, boundToFreeJacobian,
0101 additionalFreeCovariance, direction);
0102 cov = boundCovariance;
0103 }
0104
0105
0106 Vector4 pos4 = Vector4::Zero();
0107 pos4[ePos0] = freeParameters[eFreePos0];
0108 pos4[ePos1] = freeParameters[eFreePos1];
0109 pos4[ePos2] = freeParameters[eFreePos2];
0110 pos4[eTime] = freeParameters[eFreeTime];
0111 BoundTrackParameters curvilinearParams =
0112 BoundTrackParameters::createCurvilinear(
0113 pos4, direction, freeParameters[eFreeQOverP], std::move(cov),
0114 particleHypothesis);
0115
0116 return {std::move(curvilinearParams), fullTransportJacobian, accumulatedPath};
0117 }
0118
0119 Result<void> sympy::transportCovarianceToBound(
0120 const GeometryContext& geoContext, const Surface& surface,
0121 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0122 FreeVector& freeToPathDerivatives, BoundToFreeMatrix& boundToFreeJacobian,
0123 const std::optional<FreeMatrix>& additionalFreeCovariance,
0124 FreeVector& freeParameters,
0125 const FreeToBoundCorrection& freeToBoundCorrection) {
0126 FreeToBoundMatrix freeToBoundJacobian;
0127
0128
0129
0130 sympy::boundToBoundTransportJacobian(
0131 geoContext, surface, freeParameters, boundToFreeJacobian,
0132 freeToBoundJacobian, freeToPathDerivatives, fullTransportJacobian);
0133
0134 bool correction = false;
0135 if (freeToBoundCorrection) {
0136 FreeMatrix freeCovariance =
0137 boundToFreeJacobian * boundCovariance * boundToFreeJacobian.transpose();
0138
0139 auto transformer =
0140 detail::CorrectedFreeToBoundTransformer(freeToBoundCorrection);
0141 auto correctedRes =
0142 transformer(freeParameters, freeCovariance, surface, geoContext);
0143
0144 if (correctedRes.has_value()) {
0145 auto correctedValue = correctedRes.value();
0146 BoundVector boundParams = std::get<BoundVector>(correctedValue);
0147
0148 freeParameters =
0149 transformBoundToFreeParameters(surface, geoContext, boundParams);
0150
0151
0152 boundCovariance = std::get<BoundMatrix>(correctedValue);
0153
0154 correction = true;
0155 }
0156 }
0157
0158 if (!correction) {
0159
0160
0161 BoundMatrix newBoundCovariance;
0162 applyBoundCovarianceTransport(fullTransportJacobian, boundCovariance,
0163 newBoundCovariance);
0164 boundCovariance = newBoundCovariance;
0165 }
0166
0167 if (additionalFreeCovariance) {
0168 boundCovariance += freeToBoundJacobian * (*additionalFreeCovariance) *
0169 freeToBoundJacobian.transpose();
0170 }
0171
0172
0173
0174
0175 return reinitializeJacobians(geoContext, surface, freeToPathDerivatives,
0176 boundToFreeJacobian, freeParameters);
0177 }
0178
0179 void sympy::transportCovarianceToCurvilinear(
0180 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0181 FreeVector& freeToPathDerivatives, BoundToFreeMatrix& boundToFreeJacobian,
0182 const std::optional<FreeMatrix>& additionalFreeCovariance,
0183 const Vector3& direction) {
0184 FreeToBoundMatrix freeToBoundJacobian;
0185
0186
0187
0188 sympy::boundToCurvilinearTransportJacobian(
0189 direction, boundToFreeJacobian, freeToBoundJacobian,
0190 freeToPathDerivatives, fullTransportJacobian);
0191
0192
0193
0194 BoundMatrix newBoundCovariance;
0195 applyBoundCovarianceTransport(fullTransportJacobian, boundCovariance,
0196 newBoundCovariance);
0197 boundCovariance = newBoundCovariance;
0198
0199 if (additionalFreeCovariance) {
0200 boundCovariance += freeToBoundJacobian * (*additionalFreeCovariance) *
0201 freeToBoundJacobian.transpose();
0202 }
0203
0204
0205
0206
0207
0208 reinitializeJacobians(freeToPathDerivatives, boundToFreeJacobian, direction);
0209 }
0210
0211 }