|
|
|||
File indexing completed on 2025-10-25 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/Units.hpp" 0013 #include "Acts/EventData/ChargeConcept.hpp" 0014 0015 #include <cassert> 0016 #include <cmath> 0017 0018 namespace Acts { 0019 0020 /// @defgroup eventdata-charge Charge interpretation for track parameters 0021 /// 0022 /// Track parameters store a single coefficient that describes charge and 0023 /// momentum. This is either charge/momentum or 1/momentum, but the 0024 /// interpretation depends on what type of particle is described. In this code 0025 /// base this coefficient is always referred to as `qOverP` (or 0026 /// charge-over-momentum) even for uncharged particles. The following types are 0027 /// used to restrict the particle charge magnitude (at compile time) and support 0028 /// the umambigous extraction of charge and absolute momentum from said track 0029 /// parameter coefficient. 0030 /// 0031 /// All types are designed to be interchangeable. Each one can be 0032 /// constructed with the input charge magnitude 0033 /// 0034 /// ```cpp 0035 /// Charge c(1_e); 0036 /// ``` 0037 /// 0038 /// and can then be used to extract the charge value 0039 /// 0040 /// ```cpp 0041 /// auto q = c.extractCharge(qOverP); 0042 /// ``` 0043 /// 0044 /// or the absolute momentum 0045 /// 0046 /// ```cpp 0047 /// auto p = c.extractMomentum(qOverP); 0048 /// ``` 0049 /// 0050 /// from the charge-over-momentum track parameter. 0051 /// 0052 /// @{ 0053 0054 /// Charge and momentum interpretation for neutral particles. 0055 struct Neutral { 0056 constexpr Neutral() = default; 0057 0058 // TODO remove this method after grad refactor; currently track parameters 0059 // depend on it 0060 /// Construct and verify the input charge magnitude (in debug builds). 0061 /// 0062 /// This constructor is only provided to allow consistent construction. 0063 /// @param absQ Absolute charge magnitude (must be zero for neutral particles) 0064 constexpr explicit Neutral(float absQ) noexcept { 0065 assert((absQ == 0) && "Input charge must be zero"); 0066 (void)absQ; 0067 } 0068 0069 /// Get the absolute charge magnitude 0070 /// @return Always returns 0 for neutral particles 0071 constexpr float absQ() const noexcept { return 0; } 0072 0073 /// Extract the signed charge from q/p 0074 /// @return Always returns 0 for neutral particles 0075 constexpr float extractCharge(double /*qOverP*/) const noexcept { 0076 return 0.0f; 0077 } 0078 0079 /// Extract momentum magnitude from q/p 0080 /// @param qOverP Charge over momentum (must be positive for neutral particles) 0081 /// @return Momentum magnitude calculated as 1/qOverP 0082 constexpr double extractMomentum(double qOverP) const noexcept { 0083 assert(qOverP >= 0 && "qOverP cannot be negative"); 0084 return 1.0f / qOverP; 0085 } 0086 0087 /// Compute q/p from momentum and signed charge 0088 /// @param momentum Particle momentum magnitude 0089 /// @param signedQ Signed charge (must be 0 for neutral particles) 0090 /// @return Charge over momentum (1/momentum for neutral particles) 0091 constexpr double qOverP(double momentum, float signedQ) const noexcept { 0092 assert((signedQ != 0) && "charge must be 0"); 0093 (void)signedQ; 0094 return 1.0f / momentum; 0095 } 0096 0097 /// Compare for equality. 0098 /// 0099 /// This is always `true` as `Neutral` has no internal state. 0100 /// Must be available to provide a consistent interface. 0101 friend constexpr bool operator==(Neutral /*lhs*/, Neutral /*rhs*/) noexcept { 0102 return true; 0103 } 0104 }; 0105 0106 static_assert(ChargeConcept<Neutral>, "Neutral does not fulfill ChargeConcept"); 0107 0108 /// Charge and momentum interpretation for particles with +-e charge. 0109 struct SinglyCharged { 0110 constexpr SinglyCharged() = default; 0111 0112 // TODO remove this method after grad refactor; currently track parameters 0113 // depend on it 0114 /// Construct and verify the input charge magnitude (in debug builds). 0115 /// 0116 /// This constructor is only provided to allow consistent construction. 0117 /// @param absQ Absolute charge magnitude (must be e for singly charged particles) 0118 constexpr explicit SinglyCharged(float absQ) noexcept { 0119 assert((absQ == UnitConstants::e) && "Input charge magnitude must be e"); 0120 (void)absQ; 0121 } 0122 0123 /// Get the absolute charge magnitude 0124 /// @return Elementary charge magnitude e 0125 constexpr float absQ() const noexcept { return UnitConstants::e; } 0126 0127 /// Extract the signed charge from q/p 0128 /// @param qOverP Charge over momentum 0129 /// @return Signed elementary charge (+e or -e) 0130 constexpr float extractCharge(double qOverP) const noexcept { 0131 return std::copysign(UnitConstants::e, qOverP); 0132 } 0133 0134 /// Extract momentum magnitude from q/p 0135 /// @param qOverP Charge over momentum 0136 /// @return Momentum magnitude calculated as charge/qOverP 0137 constexpr double extractMomentum(double qOverP) const noexcept { 0138 return extractCharge(qOverP) / qOverP; 0139 } 0140 0141 /// Compute q/p from momentum and signed charge 0142 /// @param momentum Particle momentum magnitude 0143 /// @param signedQ Signed charge (must be ±e) 0144 /// @return Charge over momentum 0145 constexpr double qOverP(double momentum, float signedQ) const noexcept { 0146 assert((std::abs(signedQ) == UnitConstants::e) && 0147 "absolute charge must be e"); 0148 return signedQ / momentum; 0149 } 0150 0151 /// Compare for equality. 0152 /// 0153 /// This is always `true` as `SinglyCharged` has no internal state. 0154 /// Must be available to provide a consistent interface. 0155 friend constexpr bool operator==(SinglyCharged /*lhs*/, 0156 SinglyCharged /*rhs*/) noexcept { 0157 return true; 0158 } 0159 }; 0160 0161 static_assert(ChargeConcept<SinglyCharged>, 0162 "SinglyCharged does not fulfill ChargeConcept"); 0163 0164 /// Charge and momentum interpretation for arbitrarily charged but not neutral 0165 /// particles. 0166 class NonNeutralCharge { 0167 public: 0168 /// Construct with the magnitude of the input charge. 0169 /// @param absQ Absolute charge magnitude (must be positive for non-neutral particles) 0170 constexpr explicit NonNeutralCharge(float absQ) noexcept : m_absQ{absQ} { 0171 assert((0 < absQ) && "Input charge magnitude must be positive"); 0172 } 0173 /// Construct from a SinglyCharged particle 0174 constexpr explicit NonNeutralCharge(SinglyCharged /*unused*/) noexcept 0175 : m_absQ{UnitConstants::e} {} 0176 0177 /// Get the absolute charge magnitude 0178 /// @return Absolute charge magnitude 0179 constexpr float absQ() const noexcept { return m_absQ; } 0180 0181 /// Extract the signed charge from q/p 0182 /// @param qOverP Charge over momentum 0183 /// @return Signed charge with correct magnitude 0184 constexpr float extractCharge(double qOverP) const noexcept { 0185 return std::copysign(m_absQ, qOverP); 0186 } 0187 /// Extract momentum magnitude from q/p 0188 /// @param qOverP Charge over momentum 0189 /// @return Momentum magnitude calculated as charge/qOverP 0190 constexpr double extractMomentum(double qOverP) const noexcept { 0191 return extractCharge(qOverP) / qOverP; 0192 } 0193 0194 /// Compute q/p from momentum and signed charge 0195 /// @param momentum Particle momentum magnitude 0196 /// @param signedQ Signed charge (must match stored charge magnitude) 0197 /// @return Charge over momentum 0198 constexpr double qOverP(double momentum, float signedQ) const noexcept { 0199 assert(std::abs(signedQ) == m_absQ && "inconsistent charge"); 0200 return signedQ / momentum; 0201 } 0202 0203 /// Compare for equality. 0204 friend constexpr bool operator==(NonNeutralCharge lhs, 0205 NonNeutralCharge rhs) noexcept { 0206 return lhs.m_absQ == rhs.m_absQ; 0207 } 0208 0209 private: 0210 float m_absQ{}; 0211 }; 0212 0213 static_assert(ChargeConcept<NonNeutralCharge>, 0214 "NonNeutralCharge does not fulfill ChargeConcept"); 0215 0216 /// Charge and momentum interpretation for arbitrarily charged particles. 0217 /// 0218 /// Only a charge magnitude identical to zero is interpreted as representing a 0219 /// neutral particle. This avoids ambiguities that might arise from using an 0220 /// approximate comparison with an arbitrary epsilon. 0221 class AnyCharge { 0222 public: 0223 /// Construct with the magnitude of the input charge. 0224 /// @param absQ The absolute value of the charge magnitude 0225 constexpr explicit AnyCharge(float absQ) noexcept : m_absQ{absQ} { 0226 assert((0 <= absQ) && "Input charge magnitude must be zero or positive"); 0227 } 0228 /// Construct from a SinglyCharged particle 0229 constexpr explicit AnyCharge(SinglyCharged /*unused*/) noexcept 0230 : m_absQ{UnitConstants::e} {} 0231 /// Construct from a Neutral particle 0232 constexpr explicit AnyCharge(Neutral /*unused*/) noexcept {} 0233 0234 /// Get the absolute charge magnitude 0235 /// @return Absolute charge magnitude (0 for neutral particles) 0236 constexpr float absQ() const noexcept { return m_absQ; } 0237 0238 /// Extract the signed charge from q/p 0239 /// @param qOverP Charge over momentum 0240 /// @return Signed charge with correct magnitude (0 for neutral) 0241 constexpr float extractCharge(double qOverP) const noexcept { 0242 return std::copysign(m_absQ, qOverP); 0243 } 0244 /// Extract momentum magnitude from q/p 0245 /// @param qOverP Charge over momentum 0246 /// @return Momentum magnitude (handles both charged and neutral particles) 0247 constexpr double extractMomentum(double qOverP) const noexcept { 0248 return (m_absQ != 0.0f) ? extractCharge(qOverP) / qOverP : 1.0f / qOverP; 0249 } 0250 0251 /// Compute q/p from momentum and signed charge 0252 /// @param momentum Particle momentum magnitude 0253 /// @param signedQ Signed charge (must match stored charge magnitude) 0254 /// @return Charge over momentum (handles both charged and neutral particles) 0255 constexpr double qOverP(double momentum, float signedQ) const noexcept { 0256 assert(std::abs(signedQ) == m_absQ && "inconsistent charge"); 0257 return (m_absQ != 0.0f) ? signedQ / momentum : 1.0f / momentum; 0258 } 0259 0260 /// Compare for equality. 0261 friend constexpr bool operator==(AnyCharge lhs, AnyCharge rhs) noexcept { 0262 return lhs.m_absQ == rhs.m_absQ; 0263 } 0264 0265 private: 0266 float m_absQ{}; 0267 }; 0268 0269 static_assert(ChargeConcept<AnyCharge>, 0270 "AnyCharge does not fulfill ChargeConcept"); 0271 0272 /// @} 0273 0274 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|