File indexing completed on 2026-04-04 07:47:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Propagator/detail/CovarianceEngine.hpp"
0010
0011 #include "Acts/Definitions/Common.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/BoundTrackParameters.hpp"
0014 #include "Acts/EventData/TransformationHelpers.hpp"
0015 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0016 #include "Acts/Propagator/detail/JacobianEngine.hpp"
0017 #include "Acts/Utilities/Result.hpp"
0018
0019 #include <optional>
0020 #include <system_error>
0021 #include <utility>
0022
0023 namespace Acts {
0024
0025
0026 using Jacobian = BoundMatrix;
0027 using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
0028
0029 Result<BoundState> detail::boundState(
0030 const GeometryContext& geoContext, const Surface& surface,
0031 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0032 FreeMatrix& freeTransportJacobian, FreeVector& freeToPathDerivatives,
0033 BoundToFreeMatrix& boundToFreeJacobian,
0034 const std::optional<FreeMatrix>& additionalFreeCovariance,
0035 FreeVector& freeParameters, const ParticleHypothesis& particleHypothesis,
0036 bool covTransport, double accumulatedPath,
0037 const FreeToBoundCorrection& freeToBoundCorrection) {
0038
0039 Result<BoundVector> bv =
0040 transformFreeToBoundParameters(freeParameters, surface, geoContext);
0041 if (!bv.ok()) {
0042 return bv.error();
0043 }
0044
0045
0046 std::optional<BoundMatrix> cov = std::nullopt;
0047 if (covTransport) {
0048
0049
0050
0051 transportCovarianceToBound(
0052 geoContext, surface, boundCovariance, fullTransportJacobian,
0053 freeTransportJacobian, freeToPathDerivatives, boundToFreeJacobian,
0054 additionalFreeCovariance, freeParameters, freeToBoundCorrection);
0055 cov = boundCovariance;
0056 }
0057
0058
0059 return std::make_tuple(
0060 BoundTrackParameters(surface.getSharedPtr(), *bv, std::move(cov),
0061 particleHypothesis),
0062 fullTransportJacobian, accumulatedPath);
0063 }
0064
0065 BoundState detail::curvilinearState(
0066 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0067 FreeMatrix& freeTransportJacobian, FreeVector& freeToPathDerivatives,
0068 BoundToFreeMatrix& boundToFreeJacobian,
0069 const std::optional<FreeMatrix>& additionalFreeCovariance,
0070 const FreeVector& freeParameters,
0071 const ParticleHypothesis& particleHypothesis, bool covTransport,
0072 double accumulatedPath) {
0073 const Vector3& direction = freeParameters.segment<3>(eFreeDir0);
0074
0075
0076 std::optional<BoundMatrix> cov = std::nullopt;
0077 if (covTransport) {
0078
0079
0080
0081 transportCovarianceToCurvilinear(boundCovariance, fullTransportJacobian,
0082 freeTransportJacobian,
0083 freeToPathDerivatives, boundToFreeJacobian,
0084 additionalFreeCovariance, direction);
0085 cov = boundCovariance;
0086 }
0087
0088
0089 Vector4 pos4 = Vector4::Zero();
0090 pos4[ePos0] = freeParameters[eFreePos0];
0091 pos4[ePos1] = freeParameters[eFreePos1];
0092 pos4[ePos2] = freeParameters[eFreePos2];
0093 pos4[eTime] = freeParameters[eFreeTime];
0094 BoundTrackParameters curvilinearParams =
0095 BoundTrackParameters::createCurvilinear(
0096 pos4, direction, freeParameters[eFreeQOverP], std::move(cov),
0097 particleHypothesis);
0098
0099 return {std::move(curvilinearParams), fullTransportJacobian, accumulatedPath};
0100 }
0101
0102 void detail::transportCovarianceToBound(
0103 const GeometryContext& geoContext, const Surface& surface,
0104 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0105 FreeMatrix& freeTransportJacobian, FreeVector& freeToPathDerivatives,
0106 BoundToFreeMatrix& boundToFreeJacobian,
0107 const std::optional<FreeMatrix>& additionalFreeCovariance,
0108 FreeVector& freeParameters,
0109 const FreeToBoundCorrection& freeToBoundCorrection) {
0110 FreeToBoundMatrix freeToBoundJacobian;
0111
0112
0113
0114 boundToBoundTransportJacobian(geoContext, surface, freeParameters,
0115 boundToFreeJacobian, freeTransportJacobian,
0116 freeToBoundJacobian, freeToPathDerivatives,
0117 fullTransportJacobian);
0118
0119 bool correction = false;
0120 if (freeToBoundCorrection) {
0121 BoundToFreeMatrix startBoundToFinalFreeJacobian =
0122 freeTransportJacobian * boundToFreeJacobian;
0123 FreeMatrix freeCovariance = startBoundToFinalFreeJacobian *
0124 boundCovariance *
0125 startBoundToFinalFreeJacobian.transpose();
0126
0127 auto transformer =
0128 detail::CorrectedFreeToBoundTransformer(freeToBoundCorrection);
0129 auto correctedRes =
0130 transformer(freeParameters, freeCovariance, surface, geoContext);
0131
0132 if (correctedRes.has_value()) {
0133 auto correctedValue = correctedRes.value();
0134 BoundVector boundParams = std::get<BoundVector>(correctedValue);
0135
0136 freeParameters =
0137 transformBoundToFreeParameters(surface, geoContext, boundParams);
0138
0139
0140 boundCovariance = std::get<BoundMatrix>(correctedValue);
0141
0142 correction = true;
0143 }
0144 }
0145
0146 if (!correction) {
0147
0148
0149 boundCovariance = fullTransportJacobian * boundCovariance *
0150 fullTransportJacobian.transpose();
0151 }
0152
0153 if (additionalFreeCovariance) {
0154 boundCovariance += freeToBoundJacobian * (*additionalFreeCovariance) *
0155 freeToBoundJacobian.transpose();
0156 }
0157
0158
0159
0160
0161
0162 reinitializeJacobians(geoContext, surface, freeTransportJacobian,
0163 freeToPathDerivatives, boundToFreeJacobian,
0164 freeParameters);
0165 }
0166
0167 void detail::transportCovarianceToCurvilinear(
0168 BoundMatrix& boundCovariance, BoundMatrix& fullTransportJacobian,
0169 FreeMatrix& freeTransportJacobian, FreeVector& freeToPathDerivatives,
0170 BoundToFreeMatrix& boundToFreeJacobian,
0171 const std::optional<FreeMatrix>& additionalFreeCovariance,
0172 const Vector3& direction) {
0173 FreeToBoundMatrix freeToBoundJacobian;
0174
0175
0176
0177 boundToCurvilinearTransportJacobian(
0178 direction, boundToFreeJacobian, freeTransportJacobian,
0179 freeToBoundJacobian, freeToPathDerivatives, fullTransportJacobian);
0180
0181
0182
0183 boundCovariance = fullTransportJacobian * boundCovariance *
0184 fullTransportJacobian.transpose();
0185
0186 if (additionalFreeCovariance) {
0187 boundCovariance += freeToBoundJacobian * (*additionalFreeCovariance) *
0188 freeToBoundJacobian.transpose();
0189 }
0190
0191
0192
0193
0194
0195
0196 reinitializeJacobians(freeTransportJacobian, freeToPathDerivatives,
0197 boundToFreeJacobian, direction);
0198 }
0199
0200 Result<BoundTrackParameters> detail::boundToBoundConversion(
0201 const GeometryContext& gctx, const BoundTrackParameters& boundParameters,
0202 const Surface& targetSurface, const Vector3& bField) {
0203 const auto& sourceSurface = boundParameters.referenceSurface();
0204
0205 FreeVector freePars = transformBoundToFreeParameters(
0206 sourceSurface, gctx, boundParameters.parameters());
0207
0208 auto res = transformFreeToBoundParameters(freePars, targetSurface, gctx);
0209
0210 if (!res.ok()) {
0211 return res.error();
0212 }
0213 BoundVector parOut = *res;
0214
0215 std::optional<BoundMatrix> covOut = std::nullopt;
0216
0217 if (boundParameters.covariance().has_value()) {
0218 BoundToFreeMatrix boundToFreeJacobian = sourceSurface.boundToFreeJacobian(
0219 gctx, freePars.segment<3>(eFreePos0), freePars.segment<3>(eFreeDir0));
0220
0221 FreeMatrix freeTransportJacobian = FreeMatrix::Identity();
0222
0223 FreeVector freeToPathDerivatives = FreeVector::Zero();
0224 freeToPathDerivatives.head<3>() = freePars.segment<3>(eFreeDir0);
0225
0226 freeToPathDerivatives.segment<3>(eFreeDir0) =
0227 bField.cross(freePars.segment<3>(eFreeDir0));
0228
0229 BoundMatrix boundToBoundJac;
0230 FreeToBoundMatrix freeToBoundJacobian;
0231 detail::boundToBoundTransportJacobian(
0232 gctx, targetSurface, freePars, boundToFreeJacobian,
0233 freeTransportJacobian, freeToBoundJacobian, freeToPathDerivatives,
0234 boundToBoundJac);
0235
0236 covOut = boundToBoundJac * (*boundParameters.covariance()) *
0237 boundToBoundJac.transpose();
0238 }
0239
0240 return BoundTrackParameters{targetSurface.getSharedPtr(), parOut, covOut,
0241 boundParameters.particleHypothesis()};
0242 }
0243
0244 }