Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:12

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019-2020 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 http://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/TrackParametersConcept.hpp"
0015 #include "Acts/EventData/detail/PrintParameters.hpp"
0016 #include "Acts/Utilities/UnitVectors.hpp"
0017 
0018 #include <cassert>
0019 #include <cmath>
0020 #include <optional>
0021 #include <type_traits>
0022 
0023 namespace Acts {
0024 
0025 /// Track parameters not bound to a surface for a single track.
0026 ///
0027 /// @tparam particle_hypothesis_t Helper type to interpret the particle charge/momentum
0028 ///
0029 /// Parameters and covariance matrix are stored using the free parametrization
0030 /// defined in `enum FreeIndices`.
0031 template <class particle_hypothesis_t>
0032 class GenericFreeTrackParameters {
0033  public:
0034   using Scalar = ActsScalar;
0035   using ParametersVector = FreeVector;
0036   using CovarianceMatrix = FreeSquareMatrix;
0037   using ParticleHypothesis = particle_hypothesis_t;
0038 
0039   /// Construct from a parameters vector and particle charge.
0040   ///
0041   /// @param params Free parameters vector
0042   /// @param cov Free parameters covariance matrix
0043   /// @param particleHypothesis Particle hypothesis
0044   ///
0045   /// In principle, only the charge magnitude is needed her to allow unambiguous
0046   /// extraction of the absolute momentum. The particle charge is required as
0047   /// an input here to be consistent with the other constructors below that
0048   /// that also take the charge as an input. The charge sign is only used in
0049   /// debug builds to check for consistency with the q/p parameter.
0050   GenericFreeTrackParameters(const ParametersVector& params,
0051                              std::optional<CovarianceMatrix> cov,
0052                              ParticleHypothesis particleHypothesis)
0053       : m_params(params),
0054         m_cov(std::move(cov)),
0055         m_particleHypothesis(std::move(particleHypothesis)) {}
0056 
0057   /// Construct from four-position, angles, absolute momentum, and charge.
0058   ///
0059   /// @param pos4 Track position/time four-vector
0060   /// @param phi Transverse track direction angle
0061   /// @param theta Longitudinal track direction angle
0062   /// @param qOverP Charge over momentum
0063   /// @param cov Free parameters covariance matrix
0064   /// @param particleHypothesis Particle hypothesis
0065   GenericFreeTrackParameters(const Vector4& pos4, Scalar phi, Scalar theta,
0066                              Scalar qOverP, std::optional<CovarianceMatrix> cov,
0067                              ParticleHypothesis particleHypothesis)
0068       : m_params(FreeVector::Zero()),
0069         m_cov(std::move(cov)),
0070         m_particleHypothesis(std::move(particleHypothesis)) {
0071     auto dir = makeDirectionFromPhiTheta(phi, theta);
0072     m_params[eFreePos0] = pos4[ePos0];
0073     m_params[eFreePos1] = pos4[ePos1];
0074     m_params[eFreePos2] = pos4[ePos2];
0075     m_params[eFreeTime] = pos4[eTime];
0076     m_params[eFreeDir0] = dir[eMom0];
0077     m_params[eFreeDir1] = dir[eMom1];
0078     m_params[eFreeDir2] = dir[eMom2];
0079     m_params[eFreeQOverP] = qOverP;
0080   }
0081 
0082   /// Converts a free track parameter with a different hypothesis.
0083   template <typename other_particle_hypothesis_t>
0084   GenericFreeTrackParameters(
0085       const GenericFreeTrackParameters<other_particle_hypothesis_t>& other)
0086       : GenericFreeTrackParameters(other.parameters(),
0087                                    other.particleHypothesis(),
0088                                    other.covariance()) {}
0089 
0090   /// Converts an unknown bound track parameter.
0091   template <typename other_track_parameter_t>
0092   static GenericFreeTrackParameters create(
0093       const other_track_parameter_t& other) {
0094     static_assert(
0095         Concepts::FreeTrackParametersConcept<other_track_parameter_t>);
0096 
0097     return GenericFreeTrackParameters(
0098         other.parameters(), other.particleHypothesis(), other.covariance());
0099   }
0100 
0101   /// Parameters are not default constructible due to the charge type.
0102   GenericFreeTrackParameters() = delete;
0103   GenericFreeTrackParameters(const GenericFreeTrackParameters&) = default;
0104   GenericFreeTrackParameters(GenericFreeTrackParameters&&) = default;
0105   ~GenericFreeTrackParameters() = default;
0106   GenericFreeTrackParameters& operator=(const GenericFreeTrackParameters&) =
0107       default;
0108   GenericFreeTrackParameters& operator=(GenericFreeTrackParameters&&) = default;
0109 
0110   /// Parameters vector.
0111   const ParametersVector& parameters() const { return m_params; }
0112   /// Optional covariance matrix.
0113   const std::optional<CovarianceMatrix>& covariance() const { return m_cov; }
0114 
0115   /// Access a single parameter value identified by its index.
0116   ///
0117   /// @tparam kIndex Track parameter index
0118   template <FreeIndices kIndex>
0119   Scalar get() const {
0120     return m_params[kIndex];
0121   }
0122 
0123   /// Space-time position four-vector.
0124   Vector4 fourPosition() const {
0125     Vector4 pos4;
0126     pos4[ePos0] = m_params[eFreePos0];
0127     pos4[ePos1] = m_params[eFreePos1];
0128     pos4[ePos2] = m_params[eFreePos2];
0129     pos4[eTime] = m_params[eFreeTime];
0130     return pos4;
0131   }
0132   /// Spatial position three-vector.
0133   Vector3 position() const { return m_params.segment<3>(eFreePos0); }
0134   /// Time coordinate.
0135   Scalar time() const { return m_params[eFreeTime]; }
0136 
0137   /// Phi direction.
0138   Scalar phi() const { return phi(direction()); }
0139   /// Theta direction.
0140   Scalar theta() const { return theta(direction()); }
0141   /// Charge over momentum.
0142   Scalar qOverP() const { return m_params[eFreeQOverP]; }
0143 
0144   /// Unit direction three-vector, i.e. the normalized momentum three-vector.
0145   Vector3 direction() const {
0146     return m_params.segment<3>(eFreeDir0).normalized();
0147   }
0148   /// Absolute momentum.
0149   Scalar absoluteMomentum() const {
0150     return m_particleHypothesis.extractMomentum(m_params[eFreeQOverP]);
0151   }
0152   /// Transverse momentum.
0153   Scalar transverseMomentum() const {
0154     // direction vector w/ arbitrary normalization can be parametrized as
0155     //   [f*sin(theta)*cos(phi), f*sin(theta)*sin(phi), f*cos(theta)]
0156     // w/ f,sin(theta) positive, the transverse magnitude is then
0157     //   sqrt(f^2*sin^2(theta)) = f*sin(theta)
0158     Scalar transverseMagnitude =
0159         std::hypot(m_params[eFreeDir0], m_params[eFreeDir1]);
0160     // absolute magnitude is f by construction
0161     Scalar magnitude = std::hypot(transverseMagnitude, m_params[eFreeDir2]);
0162     // such that we can extract sin(theta) = f*sin(theta) / f
0163     return (transverseMagnitude / magnitude) * absoluteMomentum();
0164   }
0165   /// Momentum three-vector.
0166   Vector3 momentum() const { return absoluteMomentum() * direction(); }
0167 
0168   /// Particle electric charge.
0169   Scalar charge() const {
0170     return m_particleHypothesis.extractCharge(get<eFreeQOverP>());
0171   }
0172 
0173   /// Particle hypothesis.
0174   const ParticleHypothesis& particleHypothesis() const {
0175     return m_particleHypothesis;
0176   }
0177 
0178  private:
0179   FreeVector m_params;
0180   std::optional<FreeSquareMatrix> m_cov;
0181   // TODO use [[no_unique_address]] once we switch to C++20
0182   ParticleHypothesis m_particleHypothesis;
0183 
0184   /// Print information to the output stream.
0185   friend std::ostream& operator<<(std::ostream& os,
0186                                   const GenericFreeTrackParameters& tp) {
0187     detail::printFreeParameters(
0188         os, tp.parameters(),
0189         tp.covariance().has_value() ? &tp.covariance().value() : nullptr);
0190     return os;
0191   }
0192 };
0193 
0194 }  // namespace Acts