Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-27 07:55:06

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 /// Track parameters not bound to a surface for a single track.
0028 ///
0029 /// @tparam particle_hypothesis_t Helper type to interpret the particle charge/momentum
0030 ///
0031 /// Parameters and covariance matrix are stored using the free parametrization
0032 /// defined in `enum FreeIndices`.
0033 template <class particle_hypothesis_t>
0034 class GenericFreeTrackParameters {
0035  public:
0036   /// Type alias for free track parameters vector
0037   using ParametersVector = FreeVector;
0038   /// Type alias for free track covariance matrix
0039   using CovarianceMatrix = FreeSquareMatrix;
0040   /// Type alias for particle hypothesis used in reconstruction
0041   using ParticleHypothesis = particle_hypothesis_t;
0042 
0043   /// Converts an unknown bound track parameter.
0044   /// @param other The other track parameters to convert from
0045   /// @return Free track parameters converted from the input parameters
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   /// Construct from a parameters vector and particle charge.
0054   ///
0055   /// @param params Free parameters vector
0056   /// @param cov Free parameters covariance matrix
0057   /// @param particleHypothesis Particle hypothesis
0058   ///
0059   /// In principle, only the charge magnitude is needed her to allow unambiguous
0060   /// extraction of the absolute momentum. The particle charge is required as
0061   /// an input here to be consistent with the other constructors below that
0062   /// that also take the charge as an input. The charge sign is only used in
0063   /// debug builds to check for consistency with the q/p parameter.
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   /// Construct from four-position, direction, absolute momentum, and charge.
0074   ///
0075   /// @param pos4 Track position/time four-vector
0076   /// @param dir Track direction three-vector; normalization is ignored.
0077   /// @param qOverP Charge over momentum
0078   /// @param cov Free parameters covariance matrix
0079   /// @param particleHypothesis Particle hypothesis
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   /// Construct from four-position, angles, absolute momentum, and charge.
0099   ///
0100   /// @param pos4 Track position/time four-vector
0101   /// @param phi Transverse track direction angle
0102   /// @param theta Longitudinal track direction angle
0103   /// @param qOverP Charge over momentum
0104   /// @param cov Free parameters covariance matrix
0105   /// @param particleHypothesis Particle hypothesis
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   /// Converts a free track parameter with a different hypothesis.
0126   /// @param other The other free track parameters to convert from
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   /// Parameters vector.
0135   /// @return Const reference to the free parameters vector
0136   const ParametersVector& parameters() const { return m_params; }
0137   /// Optional covariance matrix.
0138   /// @return Const reference to the optional covariance matrix
0139   const std::optional<CovarianceMatrix>& covariance() const { return m_cov; }
0140 
0141   /// Access a single parameter value identified by its index.
0142   ///
0143   /// @tparam kIndex Track parameter index
0144   /// @return The parameter value at the specified index
0145   template <FreeIndices kIndex>
0146   double get() const {
0147     return m_params[kIndex];
0148   }
0149 
0150   /// Space-time position four-vector.
0151   /// @return Four-dimensional position vector (x, y, z, t)
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   /// Spatial position three-vector.
0161   /// @return Three-dimensional position vector (x, y, z)
0162   Vector3 position() const { return m_params.segment<3>(eFreePos0); }
0163   /// Time coordinate.
0164   /// @return The time coordinate value
0165   double time() const { return m_params[eFreeTime]; }
0166 
0167   /// Phi direction.
0168   /// @return The azimuthal angle phi in radians
0169   double phi() const { return VectorHelpers::phi(direction()); }
0170   /// Theta direction.
0171   /// @return The polar angle theta in radians
0172   double theta() const { return VectorHelpers::theta(direction()); }
0173   /// Charge over momentum.
0174   /// @return The charge over momentum ratio
0175   double qOverP() const { return m_params[eFreeQOverP]; }
0176 
0177   /// Unit direction three-vector, i.e. the normalized momentum three-vector.
0178   /// @return Normalized direction vector
0179   Vector3 direction() const {
0180     return m_params.segment<3>(eFreeDir0).normalized();
0181   }
0182   /// Absolute momentum.
0183   /// @return The absolute momentum magnitude
0184   double absoluteMomentum() const {
0185     return m_particleHypothesis.extractMomentum(m_params[eFreeQOverP]);
0186   }
0187   /// Transverse momentum.
0188   /// @return The transverse momentum magnitude
0189   double transverseMomentum() const {
0190     // direction vector w/ arbitrary normalization can be parametrized as
0191     //   [f*sin(theta)*cos(phi), f*sin(theta)*sin(phi), f*cos(theta)]
0192     // w/ f,sin(theta) positive, the transverse magnitude is then
0193     //   sqrt(f^2*sin^2(theta)) = f*sin(theta)
0194     double transverseMagnitude2 =
0195         square(m_params[eFreeDir0]) + square(m_params[eFreeDir1]);
0196     // absolute magnitude is f by construction
0197     double magnitude2 = transverseMagnitude2 + square(m_params[eFreeDir2]);
0198     // such that we can extract sin(theta) = f*sin(theta) / f
0199     return std::sqrt(transverseMagnitude2 / magnitude2) * absoluteMomentum();
0200   }
0201   /// Momentum three-vector.
0202   /// @return Three-dimensional momentum vector
0203   Vector3 momentum() const { return absoluteMomentum() * direction(); }
0204 
0205   /// Particle electric charge.
0206   /// @return The particle electric charge
0207   double charge() const {
0208     return m_particleHypothesis.extractCharge(get<eFreeQOverP>());
0209   }
0210 
0211   /// Particle hypothesis.
0212   /// @return Reference to the particle hypothesis
0213   const ParticleHypothesis& particleHypothesis() const {
0214     return m_particleHypothesis;
0215   }
0216 
0217   /// Reflect the parameters in place.
0218   void reflectInPlace() { m_params = reflectFreeParameters(m_params); }
0219 
0220   /// Reflect the parameters.
0221   /// @return Reflected parameters.
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   // TODO use [[no_unique_address]] once we switch to C++20
0232   ParticleHypothesis m_particleHypothesis;
0233 
0234   /// Print information to the output stream.
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 }  // namespace Acts