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