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