File indexing completed on 2026-04-17 07:46:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Definitions/TrackParametrization.hpp"
0014 #include "Acts/EventData/TrackParameterHelpers.hpp"
0015 #include "Acts/EventData/TransformationHelpers.hpp"
0016 #include "Acts/EventData/detail/PrintParameters.hpp"
0017 #include "Acts/Utilities/MathHelpers.hpp"
0018 #include "Acts/Utilities/UnitVectors.hpp"
0019 #include "Acts/Utilities/VectorHelpers.hpp"
0020
0021 #include <cmath>
0022 #include <optional>
0023
0024 namespace Acts {
0025
0026
0027
0028
0029
0030 class FreeTrackParameters {
0031 public:
0032
0033 using ParametersVector = FreeVector;
0034
0035 using CovarianceMatrix = FreeMatrix;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 FreeTrackParameters(const FreeVector& params, std::optional<FreeMatrix> cov,
0049 ParticleHypothesis particleHypothesis)
0050 : m_params(params),
0051 m_cov(std::move(cov)),
0052 m_particleHypothesis(particleHypothesis) {
0053 assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063 FreeTrackParameters(const Vector4& pos4, const Vector3& dir, double qOverP,
0064 std::optional<FreeMatrix> cov,
0065 ParticleHypothesis particleHypothesis)
0066 : m_params(FreeVector::Zero()),
0067 m_cov(std::move(cov)),
0068 m_particleHypothesis(particleHypothesis) {
0069 m_params[eFreePos0] = pos4[ePos0];
0070 m_params[eFreePos1] = pos4[ePos1];
0071 m_params[eFreePos2] = pos4[ePos2];
0072 m_params[eFreeTime] = pos4[eTime];
0073 m_params[eFreeDir0] = dir[eMom0];
0074 m_params[eFreeDir1] = dir[eMom1];
0075 m_params[eFreeDir2] = dir[eMom2];
0076 m_params[eFreeQOverP] = qOverP;
0077
0078 assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 FreeTrackParameters(const Vector4& pos4, double phi, double theta,
0090 double qOverP, std::optional<FreeMatrix> cov,
0091 ParticleHypothesis particleHypothesis)
0092 : m_params(FreeVector::Zero()),
0093 m_cov(std::move(cov)),
0094 m_particleHypothesis(particleHypothesis) {
0095 auto dir = makeDirectionFromPhiTheta(phi, theta);
0096 m_params[eFreePos0] = pos4[ePos0];
0097 m_params[eFreePos1] = pos4[ePos1];
0098 m_params[eFreePos2] = pos4[ePos2];
0099 m_params[eFreeTime] = pos4[eTime];
0100 m_params[eFreeDir0] = dir[eMom0];
0101 m_params[eFreeDir1] = dir[eMom1];
0102 m_params[eFreeDir2] = dir[eMom2];
0103 m_params[eFreeQOverP] = qOverP;
0104
0105 assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0106 }
0107
0108
0109
0110 const FreeVector& parameters() const { return m_params; }
0111
0112
0113 const std::optional<FreeMatrix>& covariance() const { return m_cov; }
0114
0115
0116
0117
0118
0119 template <FreeIndices kIndex>
0120 double get() const {
0121 return m_params[kIndex];
0122 }
0123
0124
0125
0126 Vector4 fourPosition() const {
0127 Vector4 pos4;
0128 pos4[ePos0] = m_params[eFreePos0];
0129 pos4[ePos1] = m_params[eFreePos1];
0130 pos4[ePos2] = m_params[eFreePos2];
0131 pos4[eTime] = m_params[eFreeTime];
0132 return pos4;
0133 }
0134
0135
0136 Vector3 position() const { return m_params.segment<3>(eFreePos0); }
0137
0138
0139 double time() const { return m_params[eFreeTime]; }
0140
0141
0142
0143 double phi() const { return VectorHelpers::phi(direction()); }
0144
0145
0146 double theta() const { return VectorHelpers::theta(direction()); }
0147
0148
0149 double qOverP() const { return m_params[eFreeQOverP]; }
0150
0151
0152
0153 Vector3 direction() const {
0154 return m_params.segment<3>(eFreeDir0).normalized();
0155 }
0156
0157
0158 double absoluteMomentum() const {
0159 return m_particleHypothesis.extractMomentum(m_params[eFreeQOverP]);
0160 }
0161
0162
0163 double transverseMomentum() const {
0164
0165
0166
0167
0168 double transverseMagnitude2 =
0169 square(m_params[eFreeDir0]) + square(m_params[eFreeDir1]);
0170
0171 double magnitude2 = transverseMagnitude2 + square(m_params[eFreeDir2]);
0172
0173 return std::sqrt(transverseMagnitude2 / magnitude2) * absoluteMomentum();
0174 }
0175
0176
0177 Vector3 momentum() const { return absoluteMomentum() * direction(); }
0178
0179
0180
0181 double charge() const {
0182 return m_particleHypothesis.extractCharge(get<eFreeQOverP>());
0183 }
0184
0185
0186
0187 const ParticleHypothesis& particleHypothesis() const {
0188 return m_particleHypothesis;
0189 }
0190
0191
0192 void reflectInPlace() { m_params = reflectFreeParameters(m_params); }
0193
0194
0195
0196 FreeTrackParameters reflect() const {
0197 FreeTrackParameters reflected = *this;
0198 reflected.reflectInPlace();
0199 return reflected;
0200 }
0201
0202 private:
0203 FreeVector m_params;
0204 std::optional<FreeMatrix> m_cov;
0205
0206 ParticleHypothesis m_particleHypothesis;
0207
0208
0209 friend std::ostream& operator<<(std::ostream& os,
0210 const FreeTrackParameters& tp) {
0211 detail::printFreeParameters(
0212 os, tp.particleHypothesis(), tp.parameters(),
0213 tp.covariance().has_value() ? &tp.covariance().value() : nullptr);
0214 return os;
0215 }
0216 };
0217
0218 }