9 #include <analysis/modules/PrintMCParticles/PrintMCParticlesModule.h>
11 #include <mdst/dataobjects/MCParticle.h>
13 #include <framework/logging/LogConnectionConsole.h>
15 #include <boost/format.hpp>
16 #include <boost/algorithm/string.hpp>
18 #include <TDatabasePDG.h>
33 std::string statusToString(
const MCParticle& mc)
35 static std::map<int, std::string> names {
46 std::vector<std::string> set;
47 for (
auto && [status, name] : names) {
48 if (mc.hasStatus(status)) set.emplace_back(name);
50 return boost::join(set,
", ");
54 std::string g4ProcessToName(
int process)
58 static std::map<int, std::string> translation{
59 {1,
"CoulombScattering"},
61 {3,
"Bremsstrahlung"},
62 {4,
"PairProdByCharged"},
64 {6,
"AnnihilationToMuMu"},
65 {7,
"AnnihilationToHadrons"},
66 {8,
"NuclearStopping"},
67 {9,
"ElectronGeneralProcess"},
68 {10,
"MultipleScattering"},
70 {12,
"PhotoElectricEffect"},
71 {13,
"ComptonScattering"},
72 {14,
"GammaConversion"},
73 {15,
"GammaConversionToMuMu"},
74 {16,
"GammaGeneralProcess"},
76 {22,
"Scintillation"},
77 {23,
"SynchrotronRadiation"},
78 {24,
"TransitionRadiation"},
79 {111,
"HadronElastic"},
80 {121,
"HadronInelastic"},
82 {132,
"MuAtomicCapture"},
84 {151,
"HadronAtRest"},
85 {152,
"LeptonAtRest"},
86 {161,
"ChargeExchange"},
87 {210,
"RadioactiveDecay"},
89 {202,
"Decay_WithSpin"} ,
90 {203,
"Decay_PionMakeSpin"} ,
91 {210,
"Decay_Radioactive"},
92 {211,
"Decay_Unknown"},
93 {221,
"Decay_MuAtom "},
94 {231,
"Decay_External"},
96 if (
auto it = translation.find(process); it != translation.end()) {
99 return "[Unknown process]";
111 addParam(
"maxLevel",
m_maxLevel,
"Show only up to specified depth level, -1 means no limit", -1);
115 addParam(
"showStatus",
m_showStatus,
"Show extendend status information of the particle",
false);
131 m_output <<
"Content of MCParticle list" << std::endl;
135 std::vector<MCParticle*> first_gen;
137 if (mc.getMother() !=
nullptr)
continue;
138 first_gen.emplace_back(&mc);
149 particles.erase(std::remove_if(particles.begin(), particles.end(), [](
MCParticle * mc) {
150 return not mc->hasStatus(MCParticle::c_PrimaryParticle);
151 }), particles.end());
160 std::string colorStart[] = {
"",
""};
161 std::string colorEnd =
"";
164 colorStart[0] = anyExtraInfo ?
"\x1b[31;1m" :
"\x1b[31m";
165 colorStart[1] = anyExtraInfo ?
"\x1b[1m" :
"";
169 TDatabasePDG* pdb = TDatabasePDG::Instance();
172 const auto num_particles = particles.size();
173 size_t particle_index{0};
174 for (
const auto* mc : particles) {
176 const bool last = ++particle_index == num_particles;
177 m_output << indent << (last ?
"╰" :
"├");
180 TParticlePDG* pdef = pdb->GetParticle(mc->getPDG());
182 m_output <<
" (" << mc->getPDG() <<
")" << colorEnd;
185 auto daughters = mc->getDaughters();
190 const std::string newIndent = indent + (last ?
" " :
"│") +
" ";
192 const std::string propIndent =
"\n" + newIndent + (showDaughters ?
"│ " :
"");
194 if ((not showDaughters) and (not daughters.empty())) {
200 m_output << boost::format(
"mass=%.3g energy=%.3g charge=%d") % mc->getMass() % mc->getEnergy() % mc->getCharge();
204 const TVector3& p = mc->getMomentum();
206 m_output << boost::format(
"p=(%.3g, %.3g, %.3g) |p|=%.3g") % p.X() % p.Y() % p.Z() % p.Mag();
209 const TVector3& v = mc->getVertex();
211 m_output << boost::format(
"production vertex=(%.3g, %.3g, %.3g), time=%.3g") % v.X() % v.Y() % v.Z() % mc->getProductionTime();
215 m_output <<
"status flags=" << statusToString(*mc);
218 m_output <<
"creation process=" << g4ProcessToName(mc->getSecondaryPhysicsProcess());
221 m_output <<
"list index=" << mc->getIndex();
224 if (showDaughters and anyExtraInfo)
m_output << propIndent;
229 printTree(daughters, level + 1, newIndent);
232 if (anyExtraInfo and not last)
m_output << newIndent << std::endl;
static bool terminalSupportsColors(int fileDescriptor)
Returns true if the given file descriptor is a tty and supports colors.
A Class to store the Monte Carlo particle information.
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
@ c_IsPHOTOSPhoton
bit 8: Particle is an radiative photon from PHOTOS
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_LeftDetector
bit 2: Particle left the detector (the simulation volume).
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
void setDescription(const std::string &description)
Sets the description of the module.
std::stringstream m_output
Buffer to keep all the output while building the tree.
virtual void initialize() override
init.
bool m_showProperties
Show remaining properties.
virtual void event() override
Method is called for each event.
StoreArray< MCParticle > m_mcparticles
store array for the MCParticles
bool m_showStatus
Show extended status information.
int m_maxLevel
Show only up to specified depth level.
PrintMCParticlesModule()
Constructor.
bool m_showVertices
Show particle production vertices.
void filterPrimaryOnly(std::vector< MCParticle * > &particles) const
if m_onlyPrimary is set remove all non primary particles from the given vector inplace
void printTree(const std::vector< MCParticle * > &particles, int level=1, const std::string &indent="")
Loops recursively over the MCParticle list and prints information about each particle.
bool m_showMomenta
Show particle momenta.
std::string m_particleList
The name of the MCParticle collection.
bool m_onlyPrimaries
Print only primary particles.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.