Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-27 09:25:10

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/ext/GeantParticleView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <CLHEP/Units/SystemOfUnits.h>
0010 #include <G4ParticleDefinition.hh>
0011 #include <G4Version.hh>
0012 
0013 #include "corecel/math/Quantity.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/phys/PDGNumber.hh"
0016 
0017 #include "GeantUnits.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Access invariant particle data from Geant4 with exact quantities.
0024  *
0025  * This annotates the Geant4 view with the correct Quantities for seamless
0026  * integration with Celeritas.
0027  */
0028 class GeantParticleView
0029 {
0030   public:
0031     //!@{
0032     //! \name Type aliases
0033     using Charge = Quantity<units::EElectron, double>;
0034     using Mass = Quantity<units::MevPerCsq, double>;
0035     using Energy = units::ClhepEnergy;
0036     using InvClhepTime = Quantity<UnitInverse<units::Nanosecond>, double>;
0037     using real_type = double;
0038     //!@}
0039 
0040   public:
0041     // Construct from G4ParticleDefinition
0042     explicit GeantParticleView(G4ParticleDefinition const& def) : pd_(def) {}
0043 
0044     //! Name
0045     std::string const& name() const { return pd_.GetParticleName(); }
0046 
0047     //! PDG number
0048     PDGNumber pdg() const { return PDGNumber{pd_.GetPDGEncoding()}; }
0049 
0050     //! Rest mass [MeV / c^2]
0051     Mass mass() const { return Mass{pd_.GetPDGMass()}; }
0052 
0053     //! Charge [elemental charge e+]
0054     Charge charge() const { return Charge{pd_.GetPDGCharge()}; }
0055 
0056     // Decay constant
0057     inline InvClhepTime decay_constant() const;
0058 
0059     // Whether it is antimatter
0060     inline bool is_antiparticle() const;
0061 
0062     // Whether it is an optical photon
0063     inline bool is_optical_photon() const;
0064 
0065   private:
0066     G4ParticleDefinition const& pd_;
0067 };
0068 
0069 //---------------------------------------------------------------------------//
0070 /*!
0071  * Decay constant.
0072  */
0073 auto GeantParticleView::decay_constant() const -> InvClhepTime
0074 {
0075     if (pd_.GetPDGStable())
0076     {
0077         // Decay constant of zero is an infinite half-life, i.e., stable
0078         return zero_quantity();
0079     }
0080 
0081     return InvClhepTime{1 / pd_.GetPDGLifeTime()};
0082 }
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Whether it is an antiparticle.
0087  */
0088 bool GeantParticleView::is_antiparticle() const
0089 {
0090     return this->pdg() && this->pdg().get() < 0;
0091 }
0092 
0093 //---------------------------------------------------------------------------//
0094 /*!
0095  * Whether it is an optical photon.
0096  *
0097  * Newer versions of Geant4 have a special PDG number.
0098  */
0099 bool GeantParticleView::is_optical_photon() const
0100 {
0101     if constexpr (G4VERSION_NUMBER >= 1070)
0102     {
0103         // Special Geant4 internal terminology for optical photon
0104         return this->pdg() == PDGNumber{-22};
0105     }
0106     else
0107     {
0108         return this->pdg() == PDGNumber{0} && this->name() == "opticalphoton";
0109     }
0110 }
0111 
0112 //---------------------------------------------------------------------------//
0113 }  // namespace celeritas