Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/include/Acts/EventData/ParticleHypothesis.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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/ParticleData.hpp"
0012 #include "Acts/Definitions/PdgParticle.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/ChargeHypothesis.hpp"
0015 
0016 #include <cassert>
0017 #include <iostream>
0018 
0019 namespace Acts {
0020 
0021 // TODO In principle the factory methods could provide a reference to a static
0022 // instance which would avoid copying the particle hypothesis and potentially
0023 // save some memory. But constexpr+static seems to require C++2b extension.
0024 
0025 /// @ingroup eventdata
0026 /// @defgroup eventdata-particlehypothesis Particle hypothesis for track reconstruction
0027 /// @{
0028 
0029 /// @brief Particle hypothesis used in reconstruction
0030 ///
0031 /// The reconstruction hypothesis consists of absolute PDG code, mass and
0032 /// absolute charge.
0033 class ParticleHypothesis final {
0034  public:
0035   /// Create a muon particle hypothesis
0036   /// @return Muon particle hypothesis with any charge type
0037   [[nodiscard]] static ParticleHypothesis muon() {
0038     static const ParticleHypothesis cache(PdgParticle::eMuon);
0039     return cache;
0040   }
0041   /// Create a charged pion particle hypothesis
0042   /// @return Charged pion particle hypothesis with any charge type
0043   [[nodiscard]] static ParticleHypothesis pion() {
0044     static const ParticleHypothesis cache(PdgParticle::ePionPlus);
0045     return cache;
0046   }
0047   /// Create an electron particle hypothesis
0048   /// @return Electron particle hypothesis with any charge type
0049   [[nodiscard]] static ParticleHypothesis electron() {
0050     static const ParticleHypothesis cache(PdgParticle::eElectron);
0051     return cache;
0052   }
0053   /// Create a charged kaon particle hypothesis
0054   /// @return Charged kaon particle hypothesis with any charge type
0055   [[nodiscard]] static ParticleHypothesis kaon() {
0056     static const ParticleHypothesis cache(PdgParticle::eKaonPlus);
0057     return cache;
0058   }
0059   /// Create a proton particle hypothesis
0060   /// @return Proton particle hypothesis with any charge type
0061   [[nodiscard]] static ParticleHypothesis proton() {
0062     static const ParticleHypothesis cache(PdgParticle::eProton);
0063     return cache;
0064   }
0065 
0066   /// Create a photon particle hypothesis
0067   /// @return Photon particle hypothesis with any charge type
0068   [[nodiscard]] static ParticleHypothesis photon() {
0069     static const ParticleHypothesis cache(PdgParticle::eGamma);
0070     return cache;
0071   }
0072   /// Create a neutral pion particle hypothesis
0073   /// @return Neutral pion particle hypothesis with any charge type
0074   [[nodiscard]] static ParticleHypothesis pion0() {
0075     static const ParticleHypothesis cache(PdgParticle::ePionZero);
0076     return cache;
0077   }
0078 
0079   /// Create a pion-like particle hypothesis with custom charge
0080   /// @param absoluteCharge The absolute charge value
0081   /// @return Pion-like particle hypothesis with any charge type
0082   [[nodiscard]] static ParticleHypothesis pionLike(float absoluteCharge) {
0083     return pion().withAlteredAbsoluteCharge(absoluteCharge);
0084   }
0085 
0086   /// Create a neutral geantino particle hypothesis (massless neutral particle)
0087   /// @return Neutral geantino particle hypothesis with any charge type
0088   [[nodiscard]] static ParticleHypothesis geantino() {
0089     static const ParticleHypothesis cache(PdgParticle::eInvalid, 0,
0090                                           ChargeHypothesis{0});
0091     return cache;
0092   }
0093   /// Create a charged geantino particle hypothesis with unit charge
0094   /// @return Charged geantino particle hypothesis with any charge type
0095   [[nodiscard]] static ParticleHypothesis chargedGeantino() {
0096     return geantino().withAlteredAbsoluteCharge(1 * UnitConstants::e);
0097   }
0098   /// Create a charged geantino particle hypothesis with custom charge
0099   /// @param absoluteCharge The absolute charge value
0100   /// @return Charged geantino particle hypothesis with any charge type
0101   [[nodiscard]] static ParticleHypothesis chargedGeantino(
0102       float absoluteCharge) {
0103     return geantino().withAlteredAbsoluteCharge(absoluteCharge);
0104   }
0105 
0106   /// Creates a particle hypothesis using absolute PDG, mass and the charge
0107   /// type.
0108   ///
0109   /// @param absPdg the absolute PDG
0110   /// @param mass the particle mass
0111   /// @param absCharge the absolute charge
0112   /// @param momentum the optional particle momentum
0113   constexpr ParticleHypothesis(PdgParticle absPdg, float mass, float absCharge,
0114                                std::optional<double> momentum = std::nullopt)
0115       : m_absPdg{absPdg},
0116         m_mass{mass},
0117         m_charge{absCharge},
0118         m_momentum{momentum} {
0119     assert(absPdg == makeAbsolutePdgParticle(absPdg) &&
0120            "pdg is expected to be absolute");
0121   }
0122 
0123   /// Creates a particle hypothesis using absolute PDG, mass and the charge
0124   /// type.
0125   ///
0126   /// @param absPdg the absolute PDG
0127   /// @param mass the particle mass
0128   /// @param charge the charge type
0129   /// @param momentum the optional particle momentum
0130   constexpr ParticleHypothesis(PdgParticle absPdg, float mass,
0131                                ChargeHypothesis charge,
0132                                std::optional<double> momentum = std::nullopt)
0133       : m_absPdg{absPdg}, m_mass{mass}, m_charge{charge}, m_momentum{momentum} {
0134     assert(absPdg == makeAbsolutePdgParticle(absPdg) &&
0135            "pdg is expected to be absolute");
0136   }
0137 
0138   /// Creates a particle hypothesis using the absolute PDG.
0139   /// The mass and charge is looked up using @ref findMass and @ref findCharge.
0140   /// If the lookup fails an exception is thrown.
0141   ///
0142   /// @param absPdg the absolute PDG
0143   /// @param momentum the optional particle momentum
0144   explicit ParticleHypothesis(PdgParticle absPdg,
0145                               std::optional<double> momentum = std::nullopt)
0146       : m_absPdg{absPdg},
0147         m_mass{findMass(absPdg).value()},
0148         m_charge{std::abs(findCharge(absPdg).value())},
0149         m_momentum{momentum} {
0150     assert(absPdg == makeAbsolutePdgParticle(absPdg) &&
0151            "pdg is expected to be absolute");
0152   }
0153 
0154   /// Create a new particle hypothesis with the same mass and charge but a
0155   /// different absolute PDG.
0156   /// @param absPdg The new absolute PDG value
0157   /// @return A new ParticleHypothesis with the updated absolute PDG
0158   [[nodiscard]] ParticleHypothesis withAlteredPdg(PdgParticle absPdg) const {
0159     return ParticleHypothesis(absPdg, mass(), absoluteCharge(), m_momentum);
0160   }
0161 
0162   /// Create a new particle hypothesis with the same absolute PDG and charge but
0163   /// a different mass.
0164   /// @param mass The new mass value
0165   /// @return A new ParticleHypothesis with the updated mass
0166   [[nodiscard]] ParticleHypothesis withAlteredMass(float mass) const {
0167     return ParticleHypothesis(absolutePdg(), mass, absoluteCharge(),
0168                               m_momentum);
0169   }
0170 
0171   /// Create a new particle hypothesis with the same absolute PDG and mass but a
0172   /// different charge.
0173   /// @param absoluteCharge The new absolute charge value
0174   /// @return A new ParticleHypothesis with the updated charge
0175   [[nodiscard]] ParticleHypothesis withAlteredAbsoluteCharge(
0176       float absoluteCharge) const {
0177     return ParticleHypothesis(absolutePdg(), mass(), absoluteCharge,
0178                               m_momentum);
0179   }
0180 
0181   /// Create a new particle hypothesis with the same absolute PDG and mass but a
0182   /// different momentum hypothesis.
0183   /// @param momentum The new momentum hypothesis value
0184   /// @return A new ParticleHypothesis with the updated momentum
0185   [[nodiscard]] ParticleHypothesis withMomentumHypothesis(
0186       double momentum) const {
0187     return ParticleHypothesis(absolutePdg(), mass(), absoluteCharge(),
0188                               momentum);
0189   }
0190 
0191   /// Create a new particle hypothesis with the same absolute PDG and mass but a
0192   /// different momentum hypothesis.
0193   /// @param momentum The new optional momentum hypothesis value
0194   /// @return A new ParticleHypothesis with the updated momentum
0195   [[nodiscard]] ParticleHypothesis withMomentumHypothesis(
0196       std::optional<double> momentum) const {
0197     return ParticleHypothesis(absolutePdg(), mass(), absoluteCharge(),
0198                               momentum);
0199   }
0200 
0201   /// Create a new particle hypothesis with the same absolute PDG and mass but
0202   /// no momentum hypothesis.
0203   /// @return A new ParticleHypothesis with no momentum hypothesis
0204   [[nodiscard]] ParticleHypothesis withoutMomentumHypothesis() const {
0205     return ParticleHypothesis(absolutePdg(), mass(), absoluteCharge(),
0206                               std::nullopt);
0207   }
0208 
0209   /// Get the hypothesized absolute PDG.
0210   /// @return The absolute PDG particle identifier
0211   [[nodiscard]] constexpr PdgParticle absolutePdg() const noexcept {
0212     return m_absPdg;
0213   }
0214 
0215   /// Get the hypothesized mass.
0216   /// @return The particle mass
0217   [[nodiscard]] constexpr float mass() const noexcept { return m_mass; }
0218 
0219   /// Get the hypothesized absolute charge.
0220   /// @return The absolute charge magnitude
0221   [[nodiscard]] float absoluteCharge() const noexcept {
0222     return m_charge.absoluteCharge();
0223   }
0224 
0225   /// Check if the particle hypothesis has a hypothesized momentum.
0226   /// @return True if a momentum hypothesis is present, false otherwise
0227   [[nodiscard]] bool hasMomentumHypothesis() const noexcept {
0228     return m_momentum.has_value();
0229   }
0230 
0231   /// Get the hypothesized momentum.
0232   /// @return The particle momentum
0233   [[nodiscard]] double momentumHypothesis() const { return m_momentum.value(); }
0234 
0235   /// Extracts the signed charge from the `q over p` track parameter using the
0236   /// charge hypothesis.
0237   ///
0238   /// @param qOverP the `q over p` track parameter.
0239   /// @return The extracted signed charge
0240   [[nodiscard]] constexpr float extractCharge(double qOverP) const noexcept {
0241     return m_charge.extractCharge(qOverP);
0242   }
0243 
0244   /// Extracts the particle momentum from the `q over p` track parameter using
0245   /// the charge hypothesis.
0246   ///
0247   /// @param qOverP the `q over p` track parameter.
0248   /// @return The extracted absolute momentum
0249   [[nodiscard]] constexpr double extractMomentum(double qOverP) const noexcept {
0250     if (m_momentum.has_value()) {
0251       return *m_momentum;
0252     }
0253     return m_charge.extractMomentum(qOverP);
0254   }
0255 
0256   /// Calculate the `q over p` track parameter with the given absolute momentum
0257   /// and charge.
0258   ///
0259   /// @param momentum the absolute momentum.
0260   /// @param signedQ the signed charge.
0261   /// @return The calculated charge over momentum ratio
0262   [[nodiscard]] constexpr double qOverP(double momentum,
0263                                         float signedQ) const noexcept {
0264     return m_charge.qOverP(momentum, signedQ);
0265   }
0266 
0267   /// Get the hypothesized charge.
0268   /// @return Reference to the charge type object
0269   [[nodiscard]] constexpr const ChargeHypothesis& charge() const noexcept {
0270     return m_charge;
0271   }
0272 
0273   /// Output stream representation of the particle hypothesis
0274   /// @param os Output stream to write to
0275   /// @return Modified output stream for chaining\n
0276   std::ostream& toStream(std::ostream& os) const {
0277     os << "ParticleHypothesis{absPdg=";
0278     if (auto shortString = pdgToShortAbsString(absolutePdg())) {
0279       os << *shortString;
0280     } else {
0281       os << absolutePdg();
0282     }
0283     os << ", mass=" << mass() << ", absCharge=" << absoluteCharge();
0284     if (hasMomentumHypothesis()) {
0285       os << ", momentum=" << momentumHypothesis();
0286     }
0287     os << "}";
0288     return os;
0289   }
0290 
0291   /// Output stream operator for particle hypothesis
0292   /// @param os Output stream to write to
0293   /// @param particleHypothesis The particle hypothesis to output
0294   /// @return Reference to output stream for chaining
0295   friend std::ostream& operator<<(
0296       std::ostream& os, const ParticleHypothesis& particleHypothesis) {
0297     return particleHypothesis.toStream(os);
0298   }
0299 
0300  private:
0301   PdgParticle m_absPdg{PdgParticle::eInvalid};
0302   float m_mass{0};
0303   ChargeHypothesis m_charge;
0304   std::optional<double> m_momentum;
0305 
0306   friend bool operator==(const ParticleHypothesis& lhs,
0307                          const ParticleHypothesis& rhs) = default;
0308 };
0309 
0310 /// @}
0311 
0312 }  // namespace Acts