DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
Geant4ParticlePrint.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #include <DD4hep/Printout.h>
16 #include <DD4hep/Primitives.h>
17 #include <DD4hep/InstanceCount.h>
19 #include <DDG4/Geant4Data.h>
21 
22 // Geant4 include files
23 #include <G4Event.hh>
24 
25 // C/C++ include files
26 #include <cstring>
27 
28 using namespace dd4hep::sim;
29 using PropertyMask = dd4hep::detail::ReferenceBitMask<const int>;
30 
33  : Geant4EventAction(ctxt,nam)
34 {
35  declareProperty("OutputType",m_outputType=3);
36  declareProperty("PrintBegin",m_printBegin=false);
37  declareProperty("PrintEnd", m_printEnd=true);
38  declareProperty("PrintGen", m_printGeneration=true);
39  declareProperty("PrintHits", m_printHits=false);
41 }
42 
46 }
47 
49 void Geant4ParticlePrint::makePrintout(const G4Event* e) const {
51  if ( parts ) {
52  const ParticleMap& particles = parts->particles();
53  print("+++ ******** MC Particle Printout for event ID:%d ********",e->GetEventID());
54  if ( (m_outputType&2) != 0 ) printParticleTree(e,particles); // Tree printout....
55  if ( (m_outputType&1) != 0 ) printParticles(0,particles); // Table printout....
56  return;
57  }
58  except("No Geant4MonteCarloTruth object present in the event structure to access the particle information!", c_name());
59 }
60 
64 }
65 
67 void Geant4ParticlePrint::begin(const G4Event* e) {
68  if ( m_printBegin ) makePrintout(e);
69 }
70 
72 void Geant4ParticlePrint::end(const G4Event* e) {
73  if ( m_printEnd ) makePrintout(e);
74 }
75 
76 void Geant4ParticlePrint::printParticle(const std::string& prefix, const G4Event* e, Geant4ParticleHandle p) const {
77  char equiv[32];
78  PropertyMask mask(p->reason);
79  PropertyMask status(p->status);
80  std::string proc_name = p.processName();
81  std::string proc_type = p.processTypeName();
82  int parent_id = p->parents.empty() ? -1 : *(p->parents.begin());
83 
84  equiv[0] = 0;
85  if ( p->parents.end() == p->parents.find(p->g4Parent) ) {
86  ::snprintf(equiv,sizeof(equiv),"/%d",p->g4Parent);
87  }
88  print("+++ %s ID:%7d %12s %6d%-7s %7s %3s %5d %3s %+.3e %-4s %-7s %-3s %-3s %2d [%s%s%s] %c%c%c%c",
89  prefix.c_str(),
90  p->id,
91  p.particleName().c_str(),
92  parent_id,equiv,
93  yes_no(mask.isSet(G4PARTICLE_PRIMARY)),
94  yes_no(mask.isSet(G4PARTICLE_HAS_SECONDARIES)),
95  int(p->daughters.size()),
96  yes_no(mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD)),
97  p.energy(),
98  yes_no(mask.isSet(G4PARTICLE_CREATED_CALORIMETER_HIT)),
99  yes_no(mask.isSet(G4PARTICLE_CREATED_TRACKER_HIT)),
100  yes_no(mask.isSet(G4PARTICLE_KEEP_PROCESS)),
101  mask.isSet(G4PARTICLE_KEEP_PARENT) ? "YES" : "",
102  p.numParent(),
103  proc_name.c_str(),
104  p->process ? "/" : "",
105  proc_type.c_str(),
106  status.isSet(G4PARTICLE_GEN_EMPTY) ? 'E' : '.',
107  status.isSet(G4PARTICLE_GEN_STABLE) ? 'S' : '.',
108  status.isSet(G4PARTICLE_GEN_DECAYED) ? 'D' : '.',
109  status.isSet(G4PARTICLE_GEN_DOCUMENTATION) ? 'd' : '.'
110  );
111  if ( e && m_printHits ) {
113  G4HCofThisEvent* hc = e->GetHCofThisEvent();
114  for (int ihc=0, nhc=hc->GetNumberOfCollections(); ihc<nhc; ++ihc) {
115  G4VHitsCollection* c = hc->GetHC(ihc);
116  Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(c);
117  if ( coll ) {
118  size_t nhits = coll->GetSize();
119  for(size_t i=0; i<nhits; ++i) {
120  Geant4HitData* h = coll->hit(i);
121  Geant4Tracker::Hit* trk_hit = dynamic_cast<Geant4Tracker::Hit*>(h);
122  if ( 0 != trk_hit ) {
123  Geant4HitData::Contribution& t = trk_hit->truth;
124  int trackID = t.trackID;
125  int trueID = truth->particleID(trackID);
126  if ( trueID == p->id ) {
127  print("+++ %20s %s[%d] (%+.2e,%+.2e,%+.2e)[mm]","",c->GetName().c_str(),i,
128  trk_hit->position.x(),trk_hit->position.y(),trk_hit->position.z());
129  }
130  }
131  Geant4Calorimeter::Hit* cal_hit = dynamic_cast<Geant4Calorimeter::Hit*>(h);
132  if ( 0 != cal_hit ) {
133  Geant4HitData::Contributions& contrib = cal_hit->truth;
134  for(Geant4HitData::Contributions::iterator j=contrib.begin(); j!=contrib.end(); ++j) {
136  int trackID = t.trackID;
137  int trueID = truth->particleID(trackID);
138  if ( trueID == p->id ) {
139  print("+++ %20s %s[%d] (%+.2e,%+.2e,%+.2e)[mm]","",c->GetName().c_str(),i,
140  cal_hit->position.x(),cal_hit->position.y(),cal_hit->position.z());
141  }
142  }
143  }
144  }
145  }
146  else {
147  print("+++ Hit unknown hit collection type: %s --> %s",
148  c->GetName().c_str(),typeName(typeid(*c)).c_str());
149  }
150  }
151  }
152 }
153 
155 void Geant4ParticlePrint::printParticles(const G4Event* e, const ParticleMap& particles) const {
156  int num_energy = 0;
157  int num_parent = 0;
158  int num_process = 0;
159  int num_primary = 0;
160  int num_secondaries = 0;
161  int num_calo_hits = 0;
162  int num_tracker_hits = 0;
163 
164  print("+++ MC Particles #Tracks:%7d ParticleType Parent/Geant4 "
165  "Primary Secondary Energy in [MeV] Calo Tracker Process/Par Details",
166  int(particles.size()));
167  for(ParticleMap::const_iterator i=particles.begin(); i!=particles.end(); ++i) {
168  Geant4ParticleHandle p = (*i).second;
169  PropertyMask mask(p->reason);
170  printParticle("MC Particle Track",e, p);
171  num_secondaries += int(p->daughters.size());
172  if ( mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) ) ++num_energy;
173  if ( mask.isSet(G4PARTICLE_PRIMARY) ) ++num_primary;
174  if ( mask.isSet(G4PARTICLE_CREATED_TRACKER_HIT) ) ++num_tracker_hits;
175  if ( mask.isSet(G4PARTICLE_CREATED_CALORIMETER_HIT) ) ++num_calo_hits;
176  if ( mask.isSet(G4PARTICLE_KEEP_PARENT) ) ++num_parent;
177  else if ( mask.isSet(G4PARTICLE_KEEP_PROCESS) ) ++num_process;
178  }
179  print("+++ MC Particles #Tracks:%7d ParticleType Parent/Geant4 "
180  "Primary Secondary Energy Calo Tracker Process/Par",
181  int(particles.size()));
182  print("+++ MC Particle Summary: %7d %10d %7d %7d %9d %5d %6d",
183  num_primary, num_secondaries, num_energy,
184  num_calo_hits,num_tracker_hits,num_process,num_parent);
185 }
186 
188  const ParticleMap& particles,
189  int level,
190  Geant4ParticleHandle p) const
191 {
192  char txt[64];
193  size_t len = sizeof(txt)-33; // Careful about overruns...
194  // Ensure we do not overwrite the array
195  if ( level>int(len)-3 ) level = len-3;
196 
197  ::snprintf(txt,sizeof(txt),"%5d ",level);
198  ::memset(txt+6,' ',len-6);
199  txt[len-1] = 0;
200  txt[len-2] = '>';
201  if ( size_t(level + 6) < len ) {
202  txt[level+6]='+';
203  ::memset(txt+level+6+1,'-',len-level-3-6);
204  }
205 
206  printParticle(txt, e, p);
207  // For all particles, the set of daughters must be contained in the record.
208  for( int id_dau : p->daughters ) {
209  auto iter = particles.find(id_dau);
210  if ( iter != particles.end() ) {
211  Geant4ParticleHandle dau = iter->second;
212  printParticleTree(e, particles, level+1, dau);
213  }
214  }
215 }
216 
218 void Geant4ParticlePrint::printParticleTree(const G4Event* e, const ParticleMap& particles) const {
219  print("+++ MC Particle Parent daughter relationships. [%d particles]",int(particles.size()));
220  print("+++ MC Particles %12s #Tracks:%7d %-12s Parent%-7s "
221  "Primary Secondary Energy %-8s Calo Tracker Process/Par Details",
222  "",int(particles.size()),"ParticleType","","in [MeV]");
223  for(ParticleMap::const_iterator i=particles.begin(); i!=particles.end(); ++i) {
224  Geant4ParticleHandle p = (*i).second;
225  PropertyMask mask(p->reason);
226  if ( mask.isSet(G4PARTICLE_PRIMARY) ) printParticleTree(e, particles, 0, p);
227  }
228 }
dd4hep::sim::G4PARTICLE_CREATED_TRACKER_HIT
@ G4PARTICLE_CREATED_TRACKER_HIT
Definition: Geant4Particle.h:64
dd4hep::sim::Geant4Tracker::Hit::position
Position position
Hit position.
Definition: Geant4Data.h:268
dd4hep::sim::Geant4ParticlePrint::~Geant4ParticlePrint
virtual ~Geant4ParticlePrint()
Default destructor.
Definition: Geant4ParticlePrint.cpp:44
dd4hep::sim::Geant4HitCollection::GetSize
virtual size_t GetSize() const override
Access the collection size.
Definition: Geant4HitCollection.h:321
dd4hep::sim::G4PARTICLE_ABOVE_ENERGY_THRESHOLD
@ G4PARTICLE_ABOVE_ENERGY_THRESHOLD
Definition: Geant4Particle.h:60
Geant4HitCollection.h
dd4hep::sim::Geant4ParticlePrint::m_printBegin
bool m_printBegin
Property: Flag to indicate output type at begin of event.
Definition: Geant4ParticlePrint.h:47
Geant4ParticlePrint.h
dd4hep::sim::G4PARTICLE_KEEP_PARENT
@ G4PARTICLE_KEEP_PARENT
Definition: Geant4Particle.h:62
dd4hep::sim::Geant4Particle::reason
int reason
Definition: Geant4Particle.h:111
dd4hep::sim::G4PARTICLE_GEN_STABLE
@ G4PARTICLE_GEN_STABLE
Definition: Geant4Particle.h:71
dd4hep::sim::Geant4ParticleHandle::particleName
std::string particleName() const
Access to the Geant4 particle name.
Definition: Geant4Particle.cpp:154
dd4hep::sim::Geant4ParticlePrint::m_printHits
bool m_printHits
Property: Flag to indicate output of hit data in tree.
Definition: Geant4ParticlePrint.h:53
dd4hep::sim::Geant4ParticleMap::particles
const ParticleMap & particles() const
Access the particle map.
Definition: Geant4Particle.h:361
dd4hep::sim::G4PARTICLE_KEEP_PROCESS
@ G4PARTICLE_KEEP_PROCESS
Definition: Geant4Particle.h:61
dd4hep::sim::Geant4Particle::id
int id
not persistent
Definition: Geant4Particle.h:108
dd4hep::sim::Geant4HitCollection
Generic hit container class using Geant4HitWrapper objects.
Definition: Geant4HitCollection.h:201
dd4hep::sim::Geant4ParticlePrint::ParticleMap
Geant4ParticleMap::ParticleMap ParticleMap
Definition: Geant4ParticlePrint.h:41
dd4hep::sim::Geant4ParticleHandle::processName
std::string processName() const
Access to the creator process name.
Definition: Geant4Particle.cpp:228
dd4hep::sim::Geant4HitCollection::hit
Geant4HitWrapper & hit(size_t which)
Access the hit wrapper.
Definition: Geant4HitCollection.h:325
G4VHitsCollection
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:47
dd4hep::sim::Geant4Particle::g4Parent
int g4Parent
not persistent
Definition: Geant4Particle.h:110
dd4hep::InstanceCount::increment
static void increment(T *)
Increment count according to type information.
Definition: InstanceCount.h:98
Geant4Data.h
dd4hep::sim::Geant4Context::event
Geant4Event & event() const
Access the geant4 event – valid only between BeginEvent() and EndEvent()!
Definition: Geant4Context.cpp:84
dd4hep::sim::Geant4ParticlePrint::Geant4ParticlePrint
Geant4ParticlePrint(Geant4Context *context, const std::string &nam)
Standard constructor.
Definition: Geant4ParticlePrint.cpp:32
dd4hep::sim::Geant4ParticlePrint::end
virtual void end(const G4Event *event) override
Post-event action callback.
Definition: Geant4ParticlePrint.cpp:72
dd4hep::sim::Geant4ParticlePrint::begin
virtual void begin(const G4Event *event) override
Pre-event action callback.
Definition: Geant4ParticlePrint.cpp:67
dd4hep::sim::G4PARTICLE_GEN_DOCUMENTATION
@ G4PARTICLE_GEN_DOCUMENTATION
Definition: Geant4Particle.h:73
dd4hep::sim::Geant4ParticleMap
Data structure to map particles produced during the generation and the simulation.
Definition: Geant4Particle.h:337
dd4hep::sim::Geant4Event::extension
T * extension(bool alert=true)
Access to type safe extension object. Exception is thrown if the object is invalid.
Definition: Geant4Context.h:151
dd4hep::sim::Geant4Action::except
void except(const char *fmt,...) const
Support of exceptions: Print fatal message and throw runtime_error.
Definition: Geant4Action.cpp:256
dd4hep::sim::G4PARTICLE_GEN_EMPTY
@ G4PARTICLE_GEN_EMPTY
Definition: Geant4Particle.h:70
dd4hep::sim::Geant4HitData::Contributions
std::vector< MonteCarloContrib > Contributions
Definition: Geant4Data.h:232
dd4hep::sim::Geant4EventAction
Concrete basic implementation of the Geant4 event action.
Definition: Geant4EventAction.h:53
dd4hep::sim::Geant4ParticlePrint::printParticles
void printParticles(const G4Event *e, const ParticleMap &particles) const
Print record of kept particles.
Definition: Geant4ParticlePrint.cpp:155
dd4hep::sim::Geant4Tracker::Hit
DDG4 tracker hit class used by the generic DDG4 tracker sensitive detector.
Definition: Geant4Data.h:263
dd4hep::sim::Geant4ParticleHandle::numParent
size_t numParent() const
Accessor to the number of particle parents.
Definition: Geant4Particle.h:282
dd4hep::sim::Geant4HitData
Base class for geant4 hit structures used by the default DDG4 sensitive detector implementations.
Definition: Geant4Data.h:110
dd4hep::sim::Geant4Action::declareProperty
Geant4Action & declareProperty(const std::string &nam, T &val)
Declare property.
Definition: Geant4Action.h:366
dd4hep::InstanceCount::decrement
static void decrement(T *)
Decrement count according to type information.
Definition: InstanceCount.h:102
dd4hep::sim::Geant4Particle::status
int status
Definition: Geant4Particle.h:116
dd4hep::sim::G4PARTICLE_GEN_DECAYED
@ G4PARTICLE_GEN_DECAYED
Definition: Geant4Particle.h:72
dd4hep::sim::Geant4ParticlePrint::m_printGeneration
bool m_printGeneration
Property: Flag to indicate output type as part of the generator action.
Definition: Geant4ParticlePrint.h:51
dd4hep::sim::Geant4Particle::daughters
Particles daughters
The list of daughters of this MC particle.
Definition: Geant4Particle.h:140
dd4hep::sim::Geant4Tracker::Hit::truth
Contribution truth
Monte Carlo / Geant4 information.
Definition: Geant4Data.h:276
dd4hep::sim::Geant4ParticleHandle::processTypeName
std::string processTypeName() const
Access to the creator process type name.
Definition: Geant4Particle.cpp:241
dd4hep::sim::Geant4ParticlePrint::printParticleTree
void printParticleTree(const G4Event *e, const ParticleMap &particles, int level, Geant4ParticleHandle p) const
Print tree of kept particles.
Definition: Geant4ParticlePrint.cpp:187
dd4hep::sim::Geant4Particle::process
const G4VProcess * process
Reference to the G4VProcess, which created this track.
Definition: Geant4Particle.h:145
dd4hep::sim::Geant4Calorimeter::Hit
DDG4 calorimeter hit class used by the generic DDG4 calorimeter sensitive detector.
Definition: Geant4Data.h:323
dd4hep::sim::Geant4ParticlePrint::makePrintout
void makePrintout(const G4Event *e) const
Print particle table.
Definition: Geant4ParticlePrint.cpp:49
dd4hep::sim::Geant4ParticleMap::particleID
int particleID(int track, bool throw_if_not_found=true) const
Access the equivalent track id (shortcut to the usage of TrackEquivalents)
Definition: Geant4Particle.cpp:541
dd4hep::sim::Geant4Action::print
void print(const char *fmt,...) const
Support for messages with variable output level using output level.
Definition: Geant4Action.cpp:144
dd4hep::sim::Geant4HitData::MonteCarloContrib::trackID
int trackID
Geant 4 Track identifier.
Definition: Geant4Data.h:141
dd4hep::sim::G4PARTICLE_HAS_SECONDARIES
@ G4PARTICLE_HAS_SECONDARIES
Definition: Geant4Particle.h:59
Primitives.h
dd4hep::sim
Namespace for the Geant4 based simulation part of the AIDA detector description toolkit.
Definition: Geant4Output2EDM4hep.cpp:49
PropertyMask
dd4hep::detail::ReferenceBitMask< int > PropertyMask
Definition: HepMC3EventReader.cpp:37
dd4hep::sim::Geant4Action::c_name
const char * c_name() const
Access name of the action.
Definition: Geant4Action.h:284
dd4hep::sim::Geant4Calorimeter::Hit::truth
Contributions truth
Hit contributions by individual particles.
Definition: Geant4Data.h:330
dd4hep::sim::Geant4ParticlePrint::printParticle
void printParticle(const std::string &prefix, const G4Event *e, Geant4ParticleHandle p) const
Definition: Geant4ParticlePrint.cpp:76
dd4hep::sim::Geant4ParticleHandle
Data structure to access derived MC particle information.
Definition: Geant4Particle.h:181
dd4hep::sim::Geant4Particle::parents
Particles parents
The list of parents of this MC particle.
Definition: Geant4Particle.h:138
dd4hep::sim::Geant4ParticlePrint::operator()
virtual void operator()(G4Event *event)
Generation action callback.
Definition: Geant4ParticlePrint.cpp:62
dd4hep::sim::G4PARTICLE_CREATED_CALORIMETER_HIT
@ G4PARTICLE_CREATED_CALORIMETER_HIT
Definition: Geant4Particle.h:63
dd4hep::sim::Geant4HitData::MonteCarloContrib
Utility class describing the monte carlo contribution of a given particle to a hit.
Definition: Geant4Data.h:138
dd4hep::sim::G4PARTICLE_PRIMARY
@ G4PARTICLE_PRIMARY
Definition: Geant4Particle.h:58
InstanceCount.h
dd4hep::sim::Geant4ParticleHandle::energy
double energy() const
Scalar particle energy.
Definition: Geant4Particle.h:308
dd4hep::sim::Geant4ParticlePrint::m_outputType
int m_outputType
Property: Flag to indicate output type: 1: TABLE, 2:TREE, 3:BOTH (default)
Definition: Geant4ParticlePrint.h:45
Printout.h
dd4hep::sim::Geant4Calorimeter::Hit::position
Position position
Hit position.
Definition: Geant4Data.h:328
dd4hep::sim::Geant4ParticlePrint::m_printEnd
bool m_printEnd
Property: Flag to indicate output type at end of event.
Definition: Geant4ParticlePrint.h:49
dd4hep::sim::Geant4Context
Generic context to extend user, run and event information.
Definition: Geant4Context.h:201
dd4hep::sim::Geant4Action::context
Geant4Context * context() const
Access the context.
Definition: Geant4Action.h:270