Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:48

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   using ParametersVector = FreeVector;
0037   using CovarianceMatrix = FreeSquareMatrix;
0038   using ParticleHypothesis = particle_hypothesis_t;
0039 
0040   /// Construct from a parameters vector and particle charge.
0041   ///
0042   /// @param params Free parameters vector
0043   /// @param cov Free parameters covariance matrix
0044   /// @param particleHypothesis Particle hypothesis
0045   ///
0046   /// In principle, only the charge magnitude is needed her to allow unambiguous
0047   /// extraction of the absolute momentum. The particle charge is required as
0048   /// an input here to be consistent with the other constructors below that
0049   /// that also take the charge as an input. The charge sign is only used in
0050   /// debug builds to check for consistency with the q/p parameter.
0051   GenericFreeTrackParameters(const ParametersVector& params,
0052                              std::optional<CovarianceMatrix> cov,
0053                              ParticleHypothesis particleHypothesis)
0054       : m_params(params),
0055         m_cov(std::move(cov)),
0056         m_particleHypothesis(std::move(particleHypothesis)) {
0057     assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0058   }
0059 
0060   /// Construct from four-position, direction, absolute momentum, and charge.
0061   ///
0062   /// @param pos4 Track position/time four-vector
0063   /// @param dir Track direction three-vector; normalization is ignored.
0064   /// @param qOverP Charge over momentum
0065   /// @param cov Free parameters covariance matrix
0066   /// @param particleHypothesis Particle hypothesis
0067   GenericFreeTrackParameters(const Vector4& pos4, const Vector3& dir,
0068                              double qOverP, std::optional<CovarianceMatrix> cov,
0069                              ParticleHypothesis particleHypothesis)
0070       : m_params(FreeVector::Zero()),
0071         m_cov(std::move(cov)),
0072         m_particleHypothesis(std::move(particleHypothesis)) {
0073     m_params[eFreePos0] = pos4[ePos0];
0074     m_params[eFreePos1] = pos4[ePos1];
0075     m_params[eFreePos2] = pos4[ePos2];
0076     m_params[eFreeTime] = pos4[eTime];
0077     m_params[eFreeDir0] = dir[eMom0];
0078     m_params[eFreeDir1] = dir[eMom1];
0079     m_params[eFreeDir2] = dir[eMom2];
0080     m_params[eFreeQOverP] = qOverP;
0081 
0082     assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0083   }
0084 
0085   /// Construct from four-position, angles, absolute momentum, and charge.
0086   ///
0087   /// @param pos4 Track position/time four-vector
0088   /// @param phi Transverse track direction angle
0089   /// @param theta Longitudinal track direction angle
0090   /// @param qOverP Charge over momentum
0091   /// @param cov Free parameters covariance matrix
0092   /// @param particleHypothesis Particle hypothesis
0093   GenericFreeTrackParameters(const Vector4& pos4, double phi, double theta,
0094                              double qOverP, std::optional<CovarianceMatrix> cov,
0095                              ParticleHypothesis particleHypothesis)
0096       : m_params(FreeVector::Zero()),
0097         m_cov(std::move(cov)),
0098         m_particleHypothesis(std::move(particleHypothesis)) {
0099     auto dir = makeDirectionFromPhiTheta(phi, theta);
0100     m_params[eFreePos0] = pos4[ePos0];
0101     m_params[eFreePos1] = pos4[ePos1];
0102     m_params[eFreePos2] = pos4[ePos2];
0103     m_params[eFreeTime] = pos4[eTime];
0104     m_params[eFreeDir0] = dir[eMom0];
0105     m_params[eFreeDir1] = dir[eMom1];
0106     m_params[eFreeDir2] = dir[eMom2];
0107     m_params[eFreeQOverP] = qOverP;
0108 
0109     assert(isFreeVectorValid(m_params) && "Invalid free parameters vector");
0110   }
0111 
0112   /// Converts a free track parameter with a different hypothesis.
0113   template <typename other_particle_hypothesis_t>
0114   GenericFreeTrackParameters(
0115       const GenericFreeTrackParameters<other_particle_hypothesis_t>& other)
0116       : GenericFreeTrackParameters(other.parameters(),
0117                                    other.particleHypothesis(),
0118                                    other.covariance()) {}
0119 
0120   /// Converts an unknown bound track parameter.
0121   template <typename other_track_parameter_t>
0122   static GenericFreeTrackParameters create(
0123       const other_track_parameter_t& other) {
0124     static_assert(FreeTrackParametersConcept<other_track_parameter_t>);
0125 
0126     return GenericFreeTrackParameters(
0127         other.parameters(), other.particleHypothesis(), other.covariance());
0128   }
0129 
0130   /// Parameters are not default constructible due to the charge type.
0131   GenericFreeTrackParameters() = delete;
0132   GenericFreeTrackParameters(const GenericFreeTrackParameters&) = default;
0133   GenericFreeTrackParameters(GenericFreeTrackParameters&&) = default;
0134   ~GenericFreeTrackParameters() = default;
0135   GenericFreeTrackParameters& operator=(const GenericFreeTrackParameters&) =
0136       default;
0137   GenericFreeTrackParameters& operator=(GenericFreeTrackParameters&&) = default;
0138 
0139   /// Parameters vector.
0140   const ParametersVector& parameters() const { return m_params; }
0141   /// Optional covariance matrix.
0142   const std::optional<CovarianceMatrix>& covariance() const { return m_cov; }
0143 
0144   /// Access a single parameter value identified by its index.
0145   ///
0146   /// @tparam kIndex Track parameter index
0147   template <FreeIndices kIndex>
0148   double get() const {
0149     return m_params[kIndex];
0150   }
0151 
0152   /// Space-time position four-vector.
0153   Vector4 fourPosition() const {
0154     Vector4 pos4;
0155     pos4[ePos0] = m_params[eFreePos0];
0156     pos4[ePos1] = m_params[eFreePos1];
0157     pos4[ePos2] = m_params[eFreePos2];
0158     pos4[eTime] = m_params[eFreeTime];
0159     return pos4;
0160   }
0161   /// Spatial position three-vector.
0162   Vector3 position() const { return m_params.segment<3>(eFreePos0); }
0163   /// Time coordinate.
0164   double time() const { return m_params[eFreeTime]; }
0165 
0166   /// Phi direction.
0167   double phi() const { return VectorHelpers::phi(direction()); }
0168   /// Theta direction.
0169   double theta() const { return VectorHelpers::theta(direction()); }
0170   /// Charge over momentum.
0171   double qOverP() const { return m_params[eFreeQOverP]; }
0172 
0173   /// Unit direction three-vector, i.e. the normalized momentum three-vector.
0174   Vector3 direction() const {
0175     return m_params.segment<3>(eFreeDir0).normalized();
0176   }
0177   /// Absolute momentum.
0178   double absoluteMomentum() const {
0179     return m_particleHypothesis.extractMomentum(m_params[eFreeQOverP]);
0180   }
0181   /// Transverse momentum.
0182   double transverseMomentum() const {
0183     // direction vector w/ arbitrary normalization can be parametrized as
0184     //   [f*sin(theta)*cos(phi), f*sin(theta)*sin(phi), f*cos(theta)]
0185     // w/ f,sin(theta) positive, the transverse magnitude is then
0186     //   sqrt(f^2*sin^2(theta)) = f*sin(theta)
0187     double transverseMagnitude2 =
0188         square(m_params[eFreeDir0]) + square(m_params[eFreeDir1]);
0189     // absolute magnitude is f by construction
0190     double magnitude2 = transverseMagnitude2 + square(m_params[eFreeDir2]);
0191     // such that we can extract sin(theta) = f*sin(theta) / f
0192     return std::sqrt(transverseMagnitude2 / magnitude2) * absoluteMomentum();
0193   }
0194   /// Momentum three-vector.
0195   Vector3 momentum() const { return absoluteMomentum() * direction(); }
0196 
0197   /// Particle electric charge.
0198   double charge() const {
0199     return m_particleHypothesis.extractCharge(get<eFreeQOverP>());
0200   }
0201 
0202   /// Particle hypothesis.
0203   const ParticleHypothesis& particleHypothesis() const {
0204     return m_particleHypothesis;
0205   }
0206 
0207   /// Reflect the parameters in place.
0208   void reflectInPlace() { m_params = reflectFreeParameters(m_params); }
0209 
0210   /// Reflect the parameters.
0211   /// @return Reflected parameters.
0212   GenericFreeTrackParameters<ParticleHypothesis> reflect() const {
0213     GenericFreeTrackParameters<ParticleHypothesis> reflected = *this;
0214     reflected.reflectInPlace();
0215     return reflected;
0216   }
0217 
0218  private:
0219   FreeVector m_params;
0220   std::optional<FreeSquareMatrix> m_cov;
0221   // TODO use [[no_unique_address]] once we switch to C++20
0222   ParticleHypothesis m_particleHypothesis;
0223 
0224   /// Print information to the output stream.
0225   friend std::ostream& operator<<(std::ostream& os,
0226                                   const GenericFreeTrackParameters& tp) {
0227     detail::printFreeParameters(
0228         os, tp.parameters(),
0229         tp.covariance().has_value() ? &tp.covariance().value() : nullptr);
0230     return os;
0231   }
0232 };
0233 
0234 }  // namespace Acts