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