Back to home page

EIC code displayed by LXR

 
 

    


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

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   constexpr Neutral(float absQ) noexcept {
0064     assert((absQ == 0) && "Input charge must be zero");
0065     (void)absQ;
0066   }
0067 
0068   constexpr float absQ() const noexcept { return 0; }
0069 
0070   constexpr float extractCharge(double /*qOverP*/) const noexcept {
0071     return 0.0f;
0072   }
0073 
0074   constexpr double extractMomentum(double qOverP) const noexcept {
0075     assert(qOverP >= 0 && "qOverP cannot be negative");
0076     return 1.0f / qOverP;
0077   }
0078 
0079   constexpr double qOverP(double momentum, float signedQ) const noexcept {
0080     assert((signedQ != 0) && "charge must be 0");
0081     (void)signedQ;
0082     return 1.0f / momentum;
0083   }
0084 
0085   /// Compare for equality.
0086   ///
0087   /// This is always `true` as `Neutral` has no internal state.
0088   /// Must be available to provide a consistent interface.
0089   friend constexpr bool operator==(Neutral /*lhs*/, Neutral /*rhs*/) noexcept {
0090     return true;
0091   }
0092 };
0093 
0094 static_assert(ChargeConcept<Neutral>, "Neutral does not fulfill ChargeConcept");
0095 
0096 /// Charge and momentum interpretation for particles with +-e charge.
0097 struct SinglyCharged {
0098   constexpr SinglyCharged() = default;
0099 
0100   // TODO remove this method after grad refactor; currently track parameters
0101   // depend on it
0102   /// Construct and verify the input charge magnitude (in debug builds).
0103   ///
0104   /// This constructor is only provided to allow consistent construction.
0105   constexpr SinglyCharged(float absQ) noexcept {
0106     assert((absQ == UnitConstants::e) && "Input charge magnitude must be e");
0107     (void)absQ;
0108   }
0109 
0110   constexpr float absQ() const noexcept { return UnitConstants::e; }
0111 
0112   constexpr float extractCharge(double qOverP) const noexcept {
0113     return std::copysign(UnitConstants::e, qOverP);
0114   }
0115 
0116   constexpr double extractMomentum(double qOverP) const noexcept {
0117     return extractCharge(qOverP) / qOverP;
0118   }
0119 
0120   constexpr double qOverP(double momentum, float signedQ) const noexcept {
0121     assert((std::abs(signedQ) == UnitConstants::e) &&
0122            "absolute charge must be e");
0123     return signedQ / momentum;
0124   }
0125 
0126   /// Compare for equality.
0127   ///
0128   /// This is always `true` as `SinglyCharged` has no internal state.
0129   /// Must be available to provide a consistent interface.
0130   friend constexpr bool operator==(SinglyCharged /*lhs*/,
0131                                    SinglyCharged /*rhs*/) noexcept {
0132     return true;
0133   }
0134 };
0135 
0136 static_assert(ChargeConcept<SinglyCharged>,
0137               "SinglyCharged does not fulfill ChargeConcept");
0138 
0139 /// Charge and momentum interpretation for arbitrarily charged but not neutral
0140 /// particles.
0141 class NonNeutralCharge {
0142  public:
0143   /// Construct with the magnitude of the input charge.
0144   constexpr NonNeutralCharge(float absQ) noexcept : m_absQ{absQ} {
0145     assert((0 < absQ) && "Input charge magnitude must be positive");
0146   }
0147   constexpr NonNeutralCharge(SinglyCharged /*unused*/) noexcept
0148       : m_absQ{UnitConstants::e} {}
0149 
0150   constexpr float absQ() const noexcept { return m_absQ; }
0151 
0152   constexpr float extractCharge(double qOverP) const noexcept {
0153     return std::copysign(m_absQ, qOverP);
0154   }
0155   constexpr double extractMomentum(double qOverP) const noexcept {
0156     return extractCharge(qOverP) / qOverP;
0157   }
0158 
0159   constexpr double qOverP(double momentum, float signedQ) const noexcept {
0160     assert(std::abs(signedQ) == m_absQ && "inconsistent charge");
0161     return signedQ / momentum;
0162   }
0163 
0164   /// Compare for equality.
0165   friend constexpr bool operator==(NonNeutralCharge lhs,
0166                                    NonNeutralCharge rhs) noexcept {
0167     return lhs.m_absQ == rhs.m_absQ;
0168   }
0169 
0170  private:
0171   float m_absQ{};
0172 };
0173 
0174 static_assert(ChargeConcept<NonNeutralCharge>,
0175               "NonNeutralCharge does not fulfill ChargeConcept");
0176 
0177 /// Charge and momentum interpretation for arbitrarily charged particles.
0178 ///
0179 /// Only a charge magnitude identical to zero is interpreted as representing a
0180 /// neutral particle. This avoids ambiguities that might arise from using an
0181 /// approximate comparison with an arbitrary epsilon.
0182 class AnyCharge {
0183  public:
0184   /// Construct with the magnitude of the input charge.
0185   constexpr AnyCharge(float absQ) noexcept : m_absQ{absQ} {
0186     assert((0 <= absQ) && "Input charge magnitude must be zero or positive");
0187   }
0188   constexpr AnyCharge(SinglyCharged /*unused*/) noexcept
0189       : m_absQ{UnitConstants::e} {}
0190   constexpr AnyCharge(Neutral /*unused*/) noexcept {}
0191 
0192   constexpr float absQ() const noexcept { return m_absQ; }
0193 
0194   constexpr float extractCharge(double qOverP) const noexcept {
0195     return std::copysign(m_absQ, qOverP);
0196   }
0197   constexpr double extractMomentum(double qOverP) const noexcept {
0198     return (m_absQ != 0.0f) ? extractCharge(qOverP) / qOverP : 1.0f / qOverP;
0199   }
0200 
0201   constexpr double qOverP(double momentum, float signedQ) const noexcept {
0202     assert(std::abs(signedQ) == m_absQ && "inconsistent charge");
0203     return (m_absQ != 0.0f) ? signedQ / momentum : 1.0f / momentum;
0204   }
0205 
0206   /// Compare for equality.
0207   friend constexpr bool operator==(AnyCharge lhs, AnyCharge rhs) noexcept {
0208     return lhs.m_absQ == rhs.m_absQ;
0209   }
0210 
0211  private:
0212   float m_absQ{};
0213 };
0214 
0215 static_assert(ChargeConcept<AnyCharge>,
0216               "AnyCharge does not fulfill ChargeConcept");
0217 
0218 /// @}
0219 
0220 }  // namespace Acts