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/GeantTrackView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <G4Track.hh>
0010 
0011 #include "corecel/Types.hh"
0012 #include "corecel/math/Quantity.hh"
0013 #include "geocel/g4/Convert.hh"
0014 #include "celeritas/UnitTypes.hh"
0015 
0016 #include "GeantParticleView.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Access track data from Geant4 with Celeritas units and precision.
0023  *
0024  * This provides a uniform interface to G4Track data using Celeritas types and
0025  * units. Geant4 data are all in double precision.
0026  *
0027  * The const_reference version provides read-only access, while the reference
0028  * version adds setters.
0029  */
0030 template<Ownership W>
0031 class GeantTrackView
0032 {
0033     static_assert(W != Ownership::value, "GeantTrackView cannot own data");
0034 };
0035 
0036 //---------------------------------------------------------------------------//
0037 
0038 using GeantTrackViewConst = GeantTrackView<Ownership::const_reference>;
0039 using GeantTrackViewMutable = GeantTrackView<Ownership::reference>;
0040 
0041 //---------------------------------------------------------------------------//
0042 template<>
0043 class GeantTrackView<Ownership::const_reference>
0044 {
0045   public:
0046     //!@{
0047     //! \name Type aliases
0048     using real_type = double;
0049     using Energy = units::ClhepEnergy;
0050     using Length = lengthunits::ClhepLength;
0051     using Time = units::ClhepTime;
0052     using Real3 = Array<double, 3>;
0053     using ClhepLength3 = Array<Length, 3>;
0054     //!@}
0055 
0056   public:
0057     // Construct from G4Track
0058     explicit GeantTrackView(G4Track const& track) : t_(track) {}
0059 
0060     // Get particle definition view
0061     inline GeantParticleView particle() const;
0062 
0063     // Position in CLHEP length units (mm)
0064     inline auto pos() const -> ClhepLength3;
0065 
0066     // Momentum direction (unit vector)
0067     inline auto dir() const -> Real3;
0068 
0069     // Kinetic energy [MeV]
0070     inline Energy energy() const;
0071 
0072     // Global time in CLHEP time units (ns)
0073     inline Time time() const;
0074 
0075     //! Statistical weight
0076     real_type weight() const { return this->track().GetWeight(); }
0077 
0078     //! Access the G4 track directly
0079     G4Track const& track() const { return t_; }
0080 
0081     //! Access the G4 track directly (const)
0082     G4Track const& ctrack() const { return t_; }
0083 
0084   private:
0085     G4Track const& t_;
0086 };
0087 
0088 //---------------------------------------------------------------------------//
0089 template<>
0090 class GeantTrackView<Ownership::reference>
0091     : public GeantTrackView<Ownership::const_reference>
0092 {
0093     using Base = GeantTrackView<Ownership::const_reference>;
0094 
0095   public:
0096     //!@{
0097     //! \name Type aliases
0098     using Energy = typename Base::Energy;
0099     using Length = typename Base::Length;
0100     using Time = typename Base::Time;
0101     using Real3 = typename Base::Real3;
0102     using ClhepLength3 = typename Base::ClhepLength3;
0103     //!@}
0104 
0105   public:
0106     // Construct from mutable G4Track
0107     explicit GeantTrackView(G4Track& track) : Base(track) {}
0108 
0109     // Bring base class accessors into scope
0110     using Base::dir;
0111     using Base::energy;
0112     using Base::pos;
0113     using Base::time;
0114     using Base::weight;
0115 
0116     // Mutators
0117     inline void pos(ClhepLength3 const& position);
0118     inline void dir(Real3 const& direction);
0119     inline void energy(Energy e);
0120     inline void time(Time t);
0121 
0122     //! Set statistical weight
0123     void weight(real_type w) { this->track().SetWeight(w); }
0124 
0125     using Base::ctrack;
0126     using Base::track;
0127     //! Access mutable track reference (safe: constructed from non-const)
0128     G4Track& track() { return const_cast<G4Track&>(this->ctrack()); }
0129 };
0130 
0131 //---------------------------------------------------------------------------//
0132 // DEDUCTION GUIDES
0133 //---------------------------------------------------------------------------//
0134 
0135 // Deduce const_reference from const G4Track&
0136 GeantTrackView(G4Track const&) -> GeantTrackView<Ownership::const_reference>;
0137 
0138 // Deduce reference from mutable G4Track&
0139 GeantTrackView(G4Track&) -> GeantTrackView<Ownership::reference>;
0140 
0141 // Doxygen fails to deduce correct templated class
0142 #if !defined(__DOXYGEN__) || __DOXYGEN__ > 0x011600
0143 //---------------------------------------------------------------------------//
0144 // INLINE ACCESSOR DEFINITIONS
0145 //---------------------------------------------------------------------------//
0146 /*!
0147  * Get particle definition view.
0148  */
0149 GeantParticleView GeantTrackView<Ownership::const_reference>::particle() const
0150 {
0151     CELER_EXPECT(this->track().GetDefinition());
0152     return GeantParticleView{*this->track().GetDefinition()};
0153 }
0154 
0155 //---------------------------------------------------------------------------//
0156 /*!
0157  * Get position in CLHEP length units (mm).
0158  */
0159 auto GeantTrackView<Ownership::const_reference>::pos() const -> ClhepLength3
0160 {
0161     return make_quantity_array<Length>(to_array(this->track().GetPosition()));
0162 }
0163 
0164 //---------------------------------------------------------------------------//
0165 /*!
0166  * Get momentum direction.
0167  */
0168 auto GeantTrackView<Ownership::const_reference>::dir() const -> Real3
0169 {
0170     return to_array(this->track().GetMomentumDirection());
0171 }
0172 
0173 //---------------------------------------------------------------------------//
0174 /*!
0175  * Get kinetic energy in MeV.
0176  */
0177 auto GeantTrackView<Ownership::const_reference>::energy() const -> Energy
0178 {
0179     return Energy{this->track().GetKineticEnergy()};
0180 }
0181 
0182 //---------------------------------------------------------------------------//
0183 /*!
0184  * Get global time in CLHEP time units (ns).
0185  */
0186 auto GeantTrackView<Ownership::const_reference>::time() const -> Time
0187 {
0188     return Time{this->track().GetGlobalTime()};
0189 }
0190 
0191 //---------------------------------------------------------------------------//
0192 // INLINE MUTATOR DEFINITIONS
0193 //---------------------------------------------------------------------------//
0194 /*!
0195  * Set position in CLHEP length units (mm).
0196  */
0197 void GeantTrackView<Ownership::reference>::pos(ClhepLength3 const& position)
0198 {
0199     this->track().SetPosition(to_g4vector(value_as<Length>(position)));
0200 }
0201 
0202 //---------------------------------------------------------------------------//
0203 /*!
0204  * Set momentum direction.
0205  */
0206 void GeantTrackView<Ownership::reference>::dir(Real3 const& direction)
0207 {
0208     this->track().SetMomentumDirection(to_g4vector(direction));
0209 }
0210 
0211 //---------------------------------------------------------------------------//
0212 /*!
0213  * Set kinetic energy in MeV.
0214  */
0215 void GeantTrackView<Ownership::reference>::energy(Energy e)
0216 {
0217     this->track().SetKineticEnergy(e.value());
0218 }
0219 
0220 //---------------------------------------------------------------------------//
0221 /*!
0222  * Set global time in CLHEP time units (ns).
0223  */
0224 void GeantTrackView<Ownership::reference>::time(Time t)
0225 {
0226     this->track().SetGlobalTime(t.value());
0227 }
0228 #endif
0229 
0230 //---------------------------------------------------------------------------//
0231 }  // namespace celeritas