File indexing completed on 2025-10-25 07:55:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Vertexing/NumericalTrackLinearizer.hpp"
0010
0011 #include "Acts/EventData/TrackParameters.hpp"
0012 #include "Acts/Propagator/PropagatorOptions.hpp"
0013 #include "Acts/Utilities/Intersection.hpp"
0014 #include "Acts/Utilities/UnitVectors.hpp"
0015 #include "Acts/Vertexing/LinearizerTrackParameters.hpp"
0016
0017 #include <numbers>
0018
0019 Acts::Result<Acts::LinearizedTrack>
0020 Acts::NumericalTrackLinearizer::linearizeTrack(
0021 const BoundTrackParameters& params, double linPointTime,
0022 const Surface& perigeeSurface, const Acts::GeometryContext& gctx,
0023 const Acts::MagneticFieldContext& mctx,
0024 MagneticFieldProvider::Cache& ) const {
0025
0026 PropagatorPlainOptions pOptions(gctx, mctx);
0027
0028
0029
0030 pOptions.surfaceTolerance = m_cfg.targetTolerance;
0031
0032
0033
0034
0035
0036 Intersection3D intersection =
0037 perigeeSurface
0038 .intersect(gctx, params.position(gctx), params.direction(),
0039 BoundaryTolerance::Infinite())
0040 .closest();
0041
0042
0043
0044
0045
0046 pOptions.direction =
0047 Direction::fromScalarZeroAsPositive(intersection.pathLength());
0048
0049
0050 auto result =
0051 m_cfg.propagator->propagateToSurface(params, perigeeSurface, pOptions);
0052 if (!result.ok()) {
0053 return result.error();
0054 }
0055
0056
0057 auto endParams = *result;
0058 BoundVector perigeeParams = endParams.parameters();
0059
0060
0061 BoundSquareMatrix parCovarianceAtPCA = endParams.covariance().value();
0062 BoundSquareMatrix weightAtPCA = parCovarianceAtPCA.inverse();
0063
0064
0065
0066
0067
0068
0069
0070
0071 Acts::ActsVector<eLinSize> paramVec;
0072
0073
0074
0075
0076 Vector4 pca;
0077 Vector3 momentumAtPCA;
0078
0079
0080 {
0081 Vector3 globalCoords = endParams.position(gctx);
0082 double globalTime = endParams.time();
0083 double phi = perigeeParams(BoundIndices::eBoundPhi);
0084 double theta = perigeeParams(BoundIndices::eBoundTheta);
0085 double qOvP = perigeeParams(BoundIndices::eBoundQOverP);
0086
0087 paramVec << globalCoords, globalTime, phi, theta, qOvP;
0088 pca << globalCoords, globalTime;
0089 momentumAtPCA << phi, theta, qOvP;
0090 }
0091
0092
0093 ActsMatrix<eBoundSize, eLinSize> completeJacobian =
0094 ActsMatrix<eBoundSize, eLinSize>::Zero(eBoundSize, eLinSize);
0095
0096
0097 BoundVector newPerigeeParams;
0098
0099
0100 if (paramVec(eLinTheta) + m_cfg.delta > std::numbers::pi) {
0101 ACTS_ERROR(
0102 "Wiggled theta outside range, choose a smaller wiggle (i.e., delta)! "
0103 "You might need to decrease targetTolerance as well.");
0104 }
0105
0106
0107
0108
0109 for (unsigned int i = 0; i < eLinSize; i++) {
0110 Acts::ActsVector<eLinSize> paramVecCopy = paramVec;
0111
0112 paramVecCopy(i) += m_cfg.delta;
0113
0114
0115
0116
0117 Vector3 wiggledDir = makeDirectionFromPhiTheta(paramVecCopy(eLinPhi),
0118 paramVecCopy(eLinTheta));
0119
0120 BoundTrackParameters wiggledCurvilinearParams =
0121 BoundTrackParameters::createCurvilinear(
0122 paramVecCopy.template head<eLinPosSize>(), wiggledDir,
0123 paramVecCopy(eLinQOverP), std::nullopt, ParticleHypothesis::pion());
0124
0125
0126 intersection = perigeeSurface
0127 .intersect(gctx, paramVecCopy.template head<3>(),
0128 wiggledDir, BoundaryTolerance::Infinite())
0129 .closest();
0130 pOptions.direction =
0131 Direction::fromScalarZeroAsPositive(intersection.pathLength());
0132
0133
0134 auto newResult = m_cfg.propagator->propagateToSurface(
0135 wiggledCurvilinearParams, perigeeSurface, pOptions);
0136 if (!newResult.ok()) {
0137 return newResult.error();
0138 }
0139 newPerigeeParams = newResult->parameters();
0140
0141
0142 completeJacobian.array().col(i) =
0143 (newPerigeeParams - perigeeParams) / m_cfg.delta;
0144
0145
0146 completeJacobian(eLinPhi, i) =
0147 Acts::detail::difference_periodic(newPerigeeParams(eLinPhi),
0148 perigeeParams(eLinPhi),
0149 2 * std::numbers::pi) /
0150 m_cfg.delta;
0151 }
0152
0153
0154 ActsMatrix<eBoundSize, eLinPosSize> positionJacobian =
0155 completeJacobian.block<eBoundSize, eLinPosSize>(0, 0);
0156 ActsMatrix<eBoundSize, eLinMomSize> momentumJacobian =
0157 completeJacobian.block<eBoundSize, eLinMomSize>(0, eLinPosSize);
0158
0159
0160 BoundVector constTerm =
0161 perigeeParams - positionJacobian * pca - momentumJacobian * momentumAtPCA;
0162
0163 Vector4 linPoint;
0164 linPoint.head<3>() = perigeeSurface.center(gctx);
0165 linPoint[3] = linPointTime;
0166
0167 return LinearizedTrack(perigeeParams, parCovarianceAtPCA, weightAtPCA,
0168 linPoint, positionJacobian, momentumJacobian, pca,
0169 momentumAtPCA, constTerm);
0170 }