Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:24

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