Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-04 09:03:21

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 #ifndef DDG4_GEANT4PARTICLE_H
0015 #define DDG4_GEANT4PARTICLE_H
0016 
0017 // Framework include files
0018 
0019 // ROOT includes
0020 #include <Math/Vector4D.h>
0021 
0022 // Geant4 forward declarations
0023 class G4ParticleDefinition;
0024 class G4VProcess;
0025 
0026 // C/C++ include files
0027 #include <set>
0028 #include <map>
0029 #include <unordered_map>
0030 #include <vector>
0031 #include <memory>
0032 
0033 /// Namespace for the AIDA detector description toolkit
0034 namespace dd4hep {
0035 
0036   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0037   namespace sim {
0038 
0039     // Forward declarations
0040     class Geant4Particle;
0041 
0042     /// Base class to extend the basic particle class used by DDG4 with user information
0043     /**
0044      *  \author  M.Frank
0045      *  \version 1.0
0046      *  \ingroup DD4HEP_SIMULATION
0047      */
0048     class ParticleExtension  {
0049     public:
0050       /// Default constructor
0051       ParticleExtension() {}
0052       /// Default destructor
0053       virtual ~ParticleExtension();
0054     };
0055 
0056     /// Track properties
0057     enum Geant4ParticleProperties {
0058       G4PARTICLE_CREATED_HIT             = 1<<1,
0059       G4PARTICLE_PRIMARY                 = 1<<2,
0060       G4PARTICLE_HAS_SECONDARIES         = 1<<3,
0061       G4PARTICLE_ABOVE_ENERGY_THRESHOLD  = 1<<4,
0062       G4PARTICLE_KEEP_PROCESS            = 1<<5,
0063       G4PARTICLE_KEEP_PARENT             = 1<<6,
0064       G4PARTICLE_CREATED_CALORIMETER_HIT = 1<<7,
0065       G4PARTICLE_CREATED_TRACKER_HIT     = 1<<8,
0066       G4PARTICLE_KEEP_USER               = 1<<9,
0067       G4PARTICLE_KEEP_ALWAYS             = 1<<10,
0068       G4PARTICLE_FORCE_KILL              = 1<<11,
0069       G4PARTICLE_STARTED_IN_CALORIMETER  = 1<<12, // True if the particle has interacted in a calorimeter region.
0070 
0071       // Generator status for a given particles: bit 0...4, agreed by many formats (HepMC, LCIO, ....):
0072       G4PARTICLE_GEN_EMPTY               = 1<<0,  // Empty line
0073       G4PARTICLE_GEN_STABLE              = 1<<1,  // undecayed particle, stable in the generator
0074       G4PARTICLE_GEN_DECAYED             = 1<<2,  // particle decayed in the generator
0075       G4PARTICLE_GEN_DOCUMENTATION       = 1<<3,  // documentation line
0076       G4PARTICLE_GEN_BEAM                = 1<<4,  // beam particle
0077 
0078       G4PARTICLE_GEN_OTHER               = 1<<9,  // any other generator status
0079 
0080       G4PARTICLE_GEN_GENERATOR           =        // Particle comes from generator
0081       (  G4PARTICLE_GEN_EMPTY+G4PARTICLE_GEN_STABLE+
0082          G4PARTICLE_GEN_DECAYED+G4PARTICLE_GEN_DOCUMENTATION+
0083          G4PARTICLE_GEN_BEAM+G4PARTICLE_GEN_OTHER),
0084       G4PARTICLE_GEN_STATUS              = 0x3FF, // Mask for generator status (bit 0...9)
0085       G4PARTICLE_GEN_STATUS_MASK         = 0xFFFF,// Mask for the raw generator status (max 65k values)
0086       // Simulation status of a given particle
0087       G4PARTICLE_SIM_CREATED             = 1<<10, // True if the particle has been created by the simulation program (rather than the generator)
0088       G4PARTICLE_SIM_BACKSCATTER         = 1<<11, // True if the particle is the result of a backscatter from a calorimeter shower.
0089       G4PARTICLE_SIM_DECAY_CALO          = 1<<12, // True if the particle has interacted in a calorimeter region.
0090       G4PARTICLE_SIM_DECAY_TRACKER       = 1<<13, // True if the particle has interacted in a tracking region.
0091       G4PARTICLE_SIM_STOPPED             = 1<<14, // True if the particle has been stopped by the simulation program.
0092       G4PARTICLE_SIM_LEFT_DETECTOR       = 1<<15, // True if the particle has left the world volume undecayed.
0093       G4PARTICLE_SIM_PARENT_RADIATED     = 1<<16, // True if the particle's vertex is not the endpoint of the  parent particle.
0094       G4PARTICLE_SIM_OVERLAY             = 1<<17, // True if the particle has been overlayed by the simulation (or digitization)  program.
0095 
0096       G4PARTICLE_LAST_NOTHING            = 1<<31
0097     };
0098 
0099     /// Data structure to store the MC particle information
0100     /**
0101      *  \author  M.Frank
0102      *  \version 1.0
0103      *  \ingroup DD4HEP_SIMULATION
0104      */
0105     class Geant4Particle {
0106     public:
0107       typedef std::set<int> Particles;
0108       /// Reference counter
0109       int ref                      { 0 };           //! not persistent
0110       int id                       { 0 };
0111       int originalG4ID             { 0 };           //! not persistent
0112       int g4Parent                 { 0 };
0113       int reason                   { 0 };
0114       int mask                     { 0 };
0115       int steps                    { 0 };
0116       int secondaries              { 0 };
0117       int pdgID                    { 0 };
0118       int status                   { 0 };
0119       int colorFlow[2]             { 0, 0 };
0120       unsigned short genStatus     { 0 };
0121       char  charge                 { 0 };
0122       char  _spare[1]              { 0 };
0123       float spin[3]                { 0E0,0E0,0E0 };
0124       // 12 ints + 4 bytes + 3 floats should be aligned to 8 bytes....
0125       /// The starting vertex
0126       double vsx  = 0E0, vsy  = 0E0, vsz = 0E0;
0127       /// The end vertex
0128       double vex  = 0E0, vey  = 0E0, vez = 0E0;
0129       /// The track momentum at the start vertex
0130       double psx  = 0E0, psy  = 0E0, psz = 0E0;
0131       /// The track momentum at the end vertex
0132       double pex  = 0E0, pey  = 0E0, pez = 0E0;
0133       /// Particle mass
0134       double mass       { 0E0 };
0135       /// Particle creation time
0136       double time       { 0E0 };
0137       /// Proper time
0138       double properTime { 0E0 };
0139       /// The list of parents of this MC particle
0140       Particles parents;
0141       /// The list of daughters of this MC particle
0142       Particles daughters;
0143 
0144       /// User data extension if required
0145       std::unique_ptr<ParticleExtension> extension  { };
0146       /// Reference to the G4VProcess, which created this track
0147       const G4VProcess *process = 0;             //! not persistent
0148 
0149     public:
0150       /// Default constructor
0151       Geant4Particle();
0152       /// Constructor with ID initialization
0153       Geant4Particle(int part_id);
0154       /// NO copy constructor
0155       Geant4Particle(const Geant4Particle& copy) = delete;
0156       /// Default destructor
0157       virtual ~Geant4Particle();
0158       /// NO assignment operation
0159       Geant4Particle& operator=(const Geant4Particle& copy) = delete;
0160       /// Increase reference count
0161       Geant4Particle* addRef()  {
0162         ++ref;
0163         return this;
0164       }
0165       /// Decrease reference count. Deletes object if NULL
0166       void release();
0167       /// Assignment operator
0168       Geant4Particle& get_data(Geant4Particle& c);
0169       /// Remove daughter from set
0170       void removeDaughter(int id_daughter);
0171       /// Charge accessor (for python etc.)
0172       int charge3() const  {  return charge; }
0173     };
0174 
0175 #ifndef __DDG4_STANDALONE_DICTIONARIES__
0176 
0177     /// Data structure to access derived MC particle information
0178     /**
0179      *  \author  M.Frank
0180      *  \version 1.0
0181      *  \ingroup DD4HEP_SIMULATION
0182      */
0183     class Geant4ParticleHandle {
0184     public:
0185       typedef ROOT::Math::PxPyPzM4D<double> FourVector;
0186       typedef ROOT::Math::Cartesian3D<double> ThreeVector;
0187     protected:
0188       /// Particle pointer
0189       Geant4Particle* particle;
0190 
0191     public:
0192       /// Default constructor
0193       Geant4ParticleHandle(Geant4Particle* part);
0194       /// Initializing constructor
0195       Geant4ParticleHandle(const Geant4ParticleHandle& h);
0196       /// Assignment operator
0197       Geant4ParticleHandle& operator=(Geant4Particle* part);
0198       /// Overloaded -> operator to access particle details
0199       Geant4Particle* operator->() const;
0200       /// Conversion  operator to pointer
0201       operator Geant4Particle*() const;
0202       /// Accessor to the number of particle parents
0203       size_t numParent() const;
0204       /// Accessor to the number of particle daughters
0205       size_t numDaughter() const;
0206       /// Scalar particle momentum squared
0207       double momentum2() const;
0208       /// Scalar particle energy
0209       double energy() const;
0210       /// Scalar particle momentum
0211       double momentum() const   {  return std::sqrt(momentum2());  }
0212       /// Geant4 charge of the particle
0213       double charge()  const    { return double(particle->charge); }
0214       /// Geant4 mass of the particle
0215       double mass() const       { return particle->mass;           }
0216       /// Geant4 time of the particle
0217       double time() const       { return particle->time;           }
0218       /// Access to the Geant4 particle name
0219       std::string particleName() const;
0220       /// Access to the Geant4 particle type
0221       std::string particleType() const;
0222       /// Access to the creator process name
0223       std::string processName() const;
0224       /// Access to the creator process type name
0225       std::string processTypeName() const;
0226       /// Access particle momentum, energy as 4 vector
0227       FourVector pxPyPzM() const;
0228       /// Access particle momentum, energy as 4 vector
0229       template <typename T> std::vector<T> pxPyPzM(T unit) const;
0230       /// Access particle momentum, energy as 4 vector
0231       ThreeVector startVertex() const;
0232       /// Access particle momentum, energy as 4 vector
0233       ThreeVector endVertex()  const;
0234       /// Access the Geant4 particle definition object (expensive!)
0235       const G4ParticleDefinition *definition() const;
0236 
0237       /// Various output formats:
0238 
0239       /// Output type 1:+++ "tag"   10 def:0xde4eaa8 [gamma     ,   gamma] reason:      20 E:+1.017927e+03  \#Par:  1/4    \#Dau:  2
0240       void dump1(int level, const std::string& src, const char* tag) const;
0241       /// Output type 2:+++ "tag"   20 G4:   7 def:0xde4eaa8 [gamma     ,   gamma] reason:      20 E:+3.304035e+01 in record:YES  \#Par:  1/18   \#Dau:  0
0242       void dump2(int level, const std::string& src, const char* tag, int g4id, bool inrec) const;
0243       /// Output type 3:+++ "tag" ID:  0 e-           status:00000014 type:       11 Vertex:(+0.00e+00,+0.00e+00,+0.00e+00) [mm] time: +0.00e+00 [ns] \#Par:  0 \#Dau:  4
0244       void dumpWithVertex(int level, const std::string& src, const char* tag) const;
0245       void dumpWithMomentum(int level, const std::string& src, const char* tag) const;
0246       void dumpWithMomentumAndVertex(int level, const std::string& src, const char* tag) const;
0247       static void header4(int level, const std::string& src, const char* tag);
0248       void dump4(int level, const std::string& src, const char* tag) const;
0249 
0250       /// Handlers
0251 
0252       /// Offset all particle identifiers (id, parents, daughters) by a constant number
0253       void offset(int off)  const;
0254 
0255       /// Access Geant4 particle definitions by regular expression
0256       static std::vector<G4ParticleDefinition*> g4DefinitionsRegEx(const std::string& expression);
0257       /// Access Geant4 particle definitions by exact match
0258       static G4ParticleDefinition* g4DefinitionsExact(const std::string& expression);
0259     };
0260 
0261     inline Geant4ParticleHandle::Geant4ParticleHandle(const Geant4ParticleHandle& c)
0262       : particle(c.particle) {
0263     }
0264 
0265     /// Initializing constructor
0266     inline Geant4ParticleHandle::Geant4ParticleHandle(Geant4Particle* p)
0267       : particle(p)  {
0268     }
0269 
0270     /// Overloaded -> operator to access particle details
0271     inline Geant4Particle* Geant4ParticleHandle::operator->() const  {
0272       return particle;
0273     }
0274     /// Assignment operator
0275     inline Geant4ParticleHandle& Geant4ParticleHandle::operator=(Geant4Particle* part) {
0276       particle = part;
0277       return *this;
0278     }
0279     /// Conversion  operator to pointer
0280     inline Geant4ParticleHandle::operator Geant4Particle*() const  {
0281       return particle;
0282     }
0283     /// Accessor to the number of particle parents
0284     inline size_t Geant4ParticleHandle::numParent() const   {
0285       return particle->parents.size();
0286     }
0287     /// Accessor to the number of particle daughters
0288     inline size_t Geant4ParticleHandle::numDaughter() const   {
0289       return particle->daughters.size();
0290     }
0291     /// Access patricle momentum, energy as 4 vector
0292     inline ROOT::Math::PxPyPzM4D<double> Geant4ParticleHandle::pxPyPzM() const {
0293       const Geant4Particle* p = particle;
0294       return ROOT::Math::PxPyPzM4D<double>(p->psx,p->psy,p->psz,p->mass);
0295     }
0296 
0297     /// Access start vertex as 3-vector
0298     inline ROOT::Math::Cartesian3D<double> Geant4ParticleHandle::startVertex() const {
0299       const Geant4Particle* p = particle;
0300       return ROOT::Math::Cartesian3D<double>(p->vsx,p->vsy,p->vsz);
0301     }
0302 
0303     /// Access end start vertex as 3-vector
0304     inline ROOT::Math::Cartesian3D<double> Geant4ParticleHandle::endVertex()  const {
0305       const Geant4Particle* p = particle;
0306       return ROOT::Math::Cartesian3D<double>(p->vex,p->vey,p->vez);
0307     }
0308 
0309     /// Scalar particle energy
0310     inline double Geant4ParticleHandle::energy() const {
0311       const Geant4Particle* p = particle;
0312       ROOT::Math::PxPyPzM4D<double> v(p->psx,p->psy,p->psz,p->mass);
0313       return v.E();
0314     }
0315 
0316     /// Scalar particle momentum squared
0317     inline double Geant4ParticleHandle::momentum2() const  {
0318       const Geant4Particle* p = particle;
0319       return (p->psx*p->psx + p->psy*p->psy + p->psz*p->psz);
0320     }
0321 
0322     /// Data structure to map particles produced during the generation and the simulation
0323     /**
0324      *  This data structure is added to the Geant4Event data extensions
0325      *  by the Geant4GenerationInit action.
0326      *  Particles are added:
0327      *  - During the generation if the required modules are activated
0328      *  - At the end of the handling of the MC truth are particles to be kept
0329      *    are inserted if the required modules are activated such as the
0330      *    Geant4ParticleHandler.
0331      *
0332      *  Note: This object takes OWNERSHIP of the inserted particles!
0333      *        beware of double deletion of objects!
0334      *
0335      *  \author  M.Frank
0336      *  \version 1.0
0337      *  \ingroup DD4HEP_SIMULATION
0338      */
0339     class Geant4ParticleMap  {
0340     public:
0341       typedef Geant4Particle          Particle;
0342       typedef std::map<int,Particle*>         ParticleMap;
0343       typedef std::unordered_map<int,int>    TrackEquivalents;
0344       /// Mapping of particles of this event
0345       ParticleMap particleMap; //! not persistent
0346       /// Map associating the G4Track identifiers with identifiers of existing MCParticles
0347       TrackEquivalents equivalentTracks;
0348 
0349     public:
0350       /// Default constructor
0351       Geant4ParticleMap() {}
0352       /// Default destructor
0353       virtual ~Geant4ParticleMap();
0354       /// Check if the particle map was ever filled (ie. some particle handler was present)
0355       bool isValid() const;
0356       /// Dump content
0357       void dump()  const;
0358       /// Clear particle maps
0359       void clear();
0360       /// Adopt particle maps
0361       void adopt(ParticleMap& pm, TrackEquivalents& equiv);
0362       /// Access the particle map
0363       const ParticleMap& particles() const  {  return particleMap; }
0364       /// Access the map of track equivalents
0365       const TrackEquivalents& equivalents() const  {  return equivalentTracks;  }
0366       /// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
0367       int particleID(int track, bool throw_if_not_found=true) const;
0368     };
0369 #endif
0370 
0371   }    // End namespace sim
0372 }      // End namespace dd4hep
0373 #endif // DDG4_GEANT4PARTICLE_H