Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:45:16

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/Common.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/Types.hpp"
0014 #include "Acts/Utilities/HashedString.hpp"
0015 
0016 namespace Acts {
0017 
0018 namespace detail_tp {
0019 inline constexpr HashedString kTipIndexKey = hashString("tipIndex");
0020 inline constexpr HashedString kStemIndexKey = hashString("stemIndex");
0021 inline constexpr HashedString kMeasurementsKey = hashString("nMeasurements");
0022 inline constexpr HashedString kHolesKey = hashString("nHoles");
0023 inline constexpr HashedString kOutliersKey = hashString("nOutliers");
0024 inline constexpr HashedString kSharedHitsKey = hashString("nSharedHits");
0025 inline constexpr HashedString kChi2Key = hashString("chi2");
0026 inline constexpr HashedString kNdfKey = hashString("ndf");
0027 inline constexpr HashedString kNextKey = hashString("next");
0028 }  // namespace detail_tp
0029 
0030 /// Common CRTP implementation shared by the various track proxy front-ends.
0031 /// The derived proxy only needs to expose the `component` helpers, while this
0032 /// base class wires up the commonly used convenience methods.
0033 ///
0034 /// @tparam Derived The proxy implementation inheriting from this base
0035 /// @tparam index_t The index type used by the proxy
0036 /// @tparam read_only Whether the proxy provides mutable access
0037 template <typename Derived, typename index_t, bool read_only>
0038 class TrackProxyCommon {
0039  protected:
0040   /// Cast to derived type
0041   /// @return Reference to the derived proxy
0042   constexpr Derived& derived() { return static_cast<Derived&>(*this); }
0043   /// Cast to derived type
0044   /// @return Const reference to the derived proxy
0045   constexpr const Derived& derived() const {
0046     return static_cast<const Derived&>(*this);
0047   }
0048 
0049  public:
0050   /// Index type used for referencing track states.
0051   using IndexType = index_t;
0052 
0053   /// Get the tip index, i.e. the entry point into the track state container.
0054   /// @return The tip index
0055   IndexType tipIndex() const {
0056     return derived().template component<IndexType, detail_tp::kTipIndexKey>();
0057   }
0058 
0059   /// Get a mutable reference to the tip index.
0060   /// @return Mutable reference to the tip index
0061   IndexType& tipIndex()
0062     requires(!read_only)
0063   {
0064     return derived().template component<IndexType, detail_tp::kTipIndexKey>();
0065   }
0066 
0067   /// Get the stem index, i.e. the innermost track state in the track.
0068   /// @return The stem index
0069   IndexType stemIndex() const {
0070     return derived().template component<IndexType, detail_tp::kStemIndexKey>();
0071   }
0072 
0073   /// Get a mutable reference to the stem index.
0074   /// @return Mutable reference to the stem index
0075   IndexType& stemIndex()
0076     requires(!read_only)
0077   {
0078     return derived().template component<IndexType, detail_tp::kStemIndexKey>();
0079   }
0080 
0081   /// Return whether the track is forward-linked, i.e. whether each track state
0082   /// has a valid next-state index. Forward-linking is required to use the
0083   /// inside-out @c trackStates() range.
0084   /// @return True if the track is forward-linked
0085   bool isForwardLinked() const { return stemIndex() != kTrackIndexInvalid; }
0086 
0087   /// Return the number of measurements assigned to this track.
0088   /// @return The number of measurements
0089   unsigned int nMeasurements() const {
0090     return derived()
0091         .template component<unsigned int, detail_tp::kMeasurementsKey>();
0092   }
0093 
0094   /// Return a mutable reference to the number of measurements.
0095   /// @return Mutable reference to the number of measurements
0096   unsigned int& nMeasurements()
0097     requires(!read_only)
0098   {
0099     return derived()
0100         .template component<unsigned int, detail_tp::kMeasurementsKey>();
0101   }
0102 
0103   /// Return the number of holes on this track.
0104   /// @return The number of holes
0105   unsigned int nHoles() const {
0106     return derived().template component<unsigned int, detail_tp::kHolesKey>();
0107   }
0108 
0109   /// Return a mutable reference to the number of holes.
0110   /// @return Mutable reference to the number of holes
0111   unsigned int& nHoles()
0112     requires(!read_only)
0113   {
0114     return derived().template component<unsigned int, detail_tp::kHolesKey>();
0115   }
0116 
0117   /// Return the number of outliers for this track.
0118   /// @return The number of outliers
0119   unsigned int nOutliers() const {
0120     return derived()
0121         .template component<unsigned int, detail_tp::kOutliersKey>();
0122   }
0123 
0124   /// Return a mutable reference to the number of outliers.
0125   /// @return Mutable reference to the number of outliers
0126   unsigned int& nOutliers()
0127     requires(!read_only)
0128   {
0129     return derived()
0130         .template component<unsigned int, detail_tp::kOutliersKey>();
0131   }
0132 
0133   /// Return the number of shared hits for this track.
0134   /// @return The number of shared hits
0135   unsigned int nSharedHits() const {
0136     return derived()
0137         .template component<unsigned int, detail_tp::kSharedHitsKey>();
0138   }
0139 
0140   /// Return a mutable reference to the number of shared hits.
0141   /// @return Mutable reference to the number of shared hits
0142   unsigned int& nSharedHits()
0143     requires(!read_only)
0144   {
0145     return derived()
0146         .template component<unsigned int, detail_tp::kSharedHitsKey>();
0147   }
0148 
0149   /// Return the local chi-squared contribution.
0150   /// @return The chi-squared value
0151   float chi2() const {
0152     return derived().template component<float, detail_tp::kChi2Key>();
0153   }
0154 
0155   /// Return a mutable reference to the local chi-squared contribution.
0156   /// @return Mutable reference to the chi-squared value
0157   float& chi2()
0158     requires(!read_only)
0159   {
0160     return derived().template component<float, detail_tp::kChi2Key>();
0161   }
0162 
0163   /// Return the number of degrees of freedom.
0164   /// @return The number of degrees of freedom
0165   unsigned int nDoF() const {
0166     return derived().template component<unsigned int, detail_tp::kNdfKey>();
0167   }
0168 
0169   /// Return a mutable reference to the number of degrees of freedom.
0170   /// @return Mutable reference to the number of degrees of freedom
0171   unsigned int& nDoF()
0172     requires(!read_only)
0173   {
0174     return derived().template component<unsigned int, detail_tp::kNdfKey>();
0175   }
0176 
0177   /// Access the theta parameter of the track at the reference surface
0178   /// @return The theta parameter
0179   double theta() const { return derived().parameters()[eBoundTheta]; }
0180 
0181   /// Access the phi parameter of the track at the reference surface
0182   /// @return The phi parameter
0183   double phi() const { return derived().parameters()[eBoundPhi]; }
0184 
0185   /// Access the loc0 parameter of the track at the reference surface
0186   /// @return The loc0 parameter
0187   double loc0() const { return derived().parameters()[eBoundLoc0]; }
0188 
0189   /// Access the loc1 parameter of the track at the reference surface
0190   /// @return The loc1 parameter
0191   double loc1() const { return derived().parameters()[eBoundLoc1]; }
0192 
0193   /// Access the time parameter of the track at the reference surface
0194   /// @return The time parameter
0195   double time() const { return derived().parameters()[eBoundTime]; }
0196 
0197   /// Access the q/p (curvature) parameter of the track at the reference surface
0198   /// @return The q/p parameter
0199   double qOverP() const { return derived().parameters()[eBoundQOverP]; }
0200 
0201   /// Get the charge
0202   /// @return The charge value
0203   double charge() const {
0204     return derived().particleHypothesis().extractCharge(qOverP());
0205   }
0206 
0207   /// Get the absolute momentum
0208   /// @return The absolute momentum value
0209   double absoluteMomentum() const {
0210     return derived().particleHypothesis().extractMomentum(qOverP());
0211   }
0212 
0213   /// Get the transverse momentum
0214   /// @return The transverse momentum value
0215   double transverseMomentum() const {
0216     return std::sin(derived().theta()) * derived().absoluteMomentum();
0217   }
0218 
0219   /// Get a unit vector along the track direction at the reference surface
0220   /// @return The direction unit vector
0221   Vector3 direction() const {
0222     return makeDirectionFromPhiTheta(derived().phi(), derived().theta());
0223   }
0224 
0225   /// Get the global momentum vector
0226   /// @return the global momentum vector
0227   Vector3 momentum() const {
0228     return derived().absoluteMomentum() * derived().direction();
0229   }
0230 
0231   /// Get the four-momentum vector: (px, py, pz, e)
0232   /// @return the four-momentum vector
0233   Vector4 fourMomentum() const {
0234     Vector4 p4 = Vector4::Zero();
0235 
0236     Vector3 p3 = derived().momentum();
0237     p4[eMom0] = p3[eMom0];
0238     p4[eMom1] = p3[eMom1];
0239     p4[eMom2] = p3[eMom2];
0240 
0241     float m = derived().particleHypothesis().mass();
0242     p4[eEnergy] = std::sqrt(m * m + p3.squaredNorm());
0243 
0244     return p4;
0245   }
0246 };
0247 
0248 }  // namespace Acts