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) 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/Units.hpp"
0013 #include "Acts/EventData/ChargeConcept.hpp"
0014 #include "Acts/Utilities/Concepts.hpp"
0015 
0016 #include <cassert>
0017 #include <cmath>
0018 
0019 namespace Acts {
0020 
0021 /// @defgroup eventdata-charge Charge interpretation for track parameters
0022 ///
0023 /// Track parameters store a single coefficient that describes charge and
0024 /// momentum. This is either charge/momentum or 1/momentum, but the
0025 /// interpretation depends on what type of particle is described. In this code
0026 /// base this coefficient is always referred to as `qOverP` (or
0027 /// charge-over-momentum) even for uncharged particles. The following types are
0028 /// used to restrict the particle charge magnitude (at compile time) and support
0029 /// the umambigous extraction of charge and absolute momentum from said track
0030 /// parameter coefficient.
0031 ///
0032 /// All types are designed to be interchangeable. Each one can be
0033 /// constructed with the input charge magnitude
0034 ///
0035 /// ```cpp
0036 /// Charge c(1_e);
0037 /// ```
0038 ///
0039 /// and can then be used to extract the charge value
0040 ///
0041 /// ```cpp
0042 /// auto q = c.extractCharge(qOverP);
0043 /// ```
0044 ///
0045 /// or the absolute momentum
0046 ///
0047 /// ```cpp
0048 /// auto p = c.extractMomentum(qOverP);
0049 /// ```
0050 ///
0051 /// from the charge-over-momentum track parameter.
0052 ///
0053 /// @{
0054 
0055 /// Charge and momentum interpretation for neutral particles.
0056 struct Neutral {
0057   constexpr Neutral() = default;
0058 
0059   // TODO remove this method after grad refactor; currently track parameters
0060   // depend on it
0061   /// Construct and verify the input charge magnitude (in debug builds).
0062   ///
0063   /// This constructor is only provided to allow consistent construction.
0064   constexpr Neutral(float absQ) noexcept {
0065     assert((absQ == 0) && "Input charge must be zero");
0066     (void)absQ;
0067   }
0068 
0069   constexpr float absQ() const noexcept { return 0; }
0070 
0071   constexpr float extractCharge(ActsScalar /*qOverP*/) const noexcept {
0072     return 0.0f;
0073   }
0074 
0075   constexpr ActsScalar extractMomentum(ActsScalar qOverP) const noexcept {
0076     assert(qOverP >= 0 && "qOverP cannot be negative");
0077     return 1.0f / qOverP;
0078   }
0079 
0080   constexpr ActsScalar qOverP(ActsScalar momentum,
0081                               float signedQ) const noexcept {
0082     assert((signedQ != 0) && "charge must be 0");
0083     (void)signedQ;
0084     return 1.0f / momentum;
0085   }
0086 
0087   /// Compare for equality.
0088   ///
0089   /// This is always `true` as `Neutral` has no internal state.
0090   /// Must be available to provide a consistent interface.
0091   friend constexpr bool operator==(Neutral /*lhs*/, Neutral /*rhs*/) noexcept {
0092     return true;
0093   }
0094 };
0095 
0096 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, Neutral);
0097 
0098 /// Charge and momentum interpretation for particles with +-e charge.
0099 struct SinglyCharged {
0100   constexpr SinglyCharged() = default;
0101 
0102   // TODO remove this method after grad refactor; currently track parameters
0103   // depend on it
0104   /// Construct and verify the input charge magnitude (in debug builds).
0105   ///
0106   /// This constructor is only provided to allow consistent construction.
0107   constexpr SinglyCharged(float absQ) noexcept {
0108     assert((absQ == UnitConstants::e) && "Input charge magnitude must be e");
0109     (void)absQ;
0110   }
0111 
0112   constexpr float absQ() const noexcept { return UnitConstants::e; }
0113 
0114   constexpr float extractCharge(ActsScalar qOverP) const noexcept {
0115     return std::copysign(UnitConstants::e, qOverP);
0116   }
0117 
0118   constexpr ActsScalar extractMomentum(ActsScalar qOverP) const noexcept {
0119     return extractCharge(qOverP) / qOverP;
0120   }
0121 
0122   constexpr ActsScalar qOverP(ActsScalar momentum,
0123                               float signedQ) const noexcept {
0124     assert((std::abs(signedQ) == UnitConstants::e) &&
0125            "absolute charge must be e");
0126     return signedQ / momentum;
0127   }
0128 
0129   /// Compare for equality.
0130   ///
0131   /// This is always `true` as `SinglyCharged` has no internal state.
0132   /// Must be available to provide a consistent interface.
0133   friend constexpr bool operator==(SinglyCharged /*lhs*/,
0134                                    SinglyCharged /*rhs*/) noexcept {
0135     return true;
0136   }
0137 };
0138 
0139 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, SinglyCharged);
0140 
0141 /// Charge and momentum interpretation for arbitrarily charged but not neutral
0142 /// particles.
0143 class NonNeutralCharge {
0144  public:
0145   /// Construct with the magnitude of the input charge.
0146   constexpr NonNeutralCharge(float absQ) noexcept : m_absQ{absQ} {
0147     assert((0 < absQ) && "Input charge magnitude must be positive");
0148   }
0149   constexpr NonNeutralCharge(SinglyCharged /*unused*/) noexcept
0150       : m_absQ{UnitConstants::e} {}
0151 
0152   constexpr float absQ() const noexcept { return m_absQ; }
0153 
0154   constexpr float extractCharge(ActsScalar qOverP) const noexcept {
0155     return std::copysign(m_absQ, qOverP);
0156   }
0157   constexpr ActsScalar extractMomentum(ActsScalar qOverP) const noexcept {
0158     return extractCharge(qOverP) / qOverP;
0159   }
0160 
0161   constexpr ActsScalar qOverP(ActsScalar momentum,
0162                               float signedQ) const noexcept {
0163     assert(std::abs(signedQ) == m_absQ && "inconsistent charge");
0164     return signedQ / momentum;
0165   }
0166 
0167   /// Compare for equality.
0168   friend constexpr bool operator==(NonNeutralCharge lhs,
0169                                    NonNeutralCharge rhs) noexcept {
0170     return lhs.m_absQ == rhs.m_absQ;
0171   }
0172 
0173  private:
0174   float m_absQ{};
0175 };
0176 
0177 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, NonNeutralCharge);
0178 
0179 /// Charge and momentum interpretation for arbitrarily charged particles.
0180 ///
0181 /// Only a charge magnitude identical to zero is interpreted as representing a
0182 /// neutral particle. This avoids ambiguities that might arise from using an
0183 /// approximate comparison with an arbitrary epsilon.
0184 class AnyCharge {
0185  public:
0186   /// Construct with the magnitude of the input charge.
0187   constexpr AnyCharge(float absQ) noexcept : m_absQ{absQ} {
0188     assert((0 <= absQ) && "Input charge magnitude must be zero or positive");
0189   }
0190   constexpr AnyCharge(SinglyCharged /*unused*/) noexcept
0191       : m_absQ{UnitConstants::e} {}
0192   constexpr AnyCharge(Neutral /*unused*/) noexcept {}
0193 
0194   constexpr float absQ() const noexcept { return m_absQ; }
0195 
0196   constexpr float extractCharge(ActsScalar qOverP) const noexcept {
0197     return std::copysign(m_absQ, qOverP);
0198   }
0199   constexpr ActsScalar extractMomentum(ActsScalar qOverP) const noexcept {
0200     return (m_absQ != 0.0f) ? extractCharge(qOverP) / qOverP : 1.0f / qOverP;
0201   }
0202 
0203   constexpr ActsScalar qOverP(ActsScalar momentum,
0204                               float signedQ) const noexcept {
0205     assert(std::abs(signedQ) == m_absQ && "inconsistent charge");
0206     return (m_absQ != 0.0f) ? signedQ / momentum : 1.0f / momentum;
0207   }
0208 
0209   /// Compare for equality.
0210   friend constexpr bool operator==(AnyCharge lhs, AnyCharge rhs) noexcept {
0211     return lhs.m_absQ == rhs.m_absQ;
0212   }
0213 
0214  private:
0215   float m_absQ{};
0216 };
0217 
0218 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, AnyCharge);
0219 
0220 /// @}
0221 
0222 }  // namespace Acts