9#include <analysis/modules/PrintMCParticles/PrintMCParticlesModule.h>
10#include <analysis/dataobjects/StringWrapper.h>
12#include <mdst/dataobjects/MCParticle.h>
14#include <framework/geometry/B2Vector3.h>
16#include <framework/logging/LogConnectionConsole.h>
18#include <boost/format.hpp>
19#include <boost/algorithm/string.hpp>
21#include <TDatabasePDG.h>
22#include <Math/Vector3D.h>
37 std::string statusToString(
const MCParticle& mc)
39 static std::map<int, std::string> names {
50 std::vector<std::string> set;
51 for (
auto&& [status, name] : names) {
52 if (mc.hasStatus(status)) set.emplace_back(name);
54 return boost::join(set,
", ");
58 std::string g4ProcessToName(
int process)
60 static std::map<int, std::string> translation{
61 {1,
"CoulombScattering"},
63 {3,
"Bremsstrahlung"},
64 {4,
"PairProdByCharged"},
66 {6,
"AnnihilationToMuMu"},
67 {7,
"AnnihilationToHadrons"},
68 {8,
"NuclearStopping"},
69 {9,
"ElectronGeneralProcess"},
70 {10,
"MultipleScattering"},
72 {12,
"PhotoElectricEffect"},
73 {13,
"ComptonScattering"},
74 {14,
"GammaConversion"},
75 {15,
"GammaConversionToMuMu"},
76 {16,
"GammaGeneralProcess"},
77 {17,
"PositronGeneralProcess"},
78 {18,
"AnnihilationToTauTau"},
80 {22,
"Scintillation"},
81 {23,
"SynchrotronRadiation"},
82 {24,
"TransitionRadiation"},
83 {25,
"SurfaceReflection"},
84 {40,
"DarkBremsstrahlung"},
85 {49,
"MuonPairProdByCharged"},
86 {111,
"HadronElastic"},
87 {116,
"NeutronGeneral"},
88 {121,
"HadronInelastic"},
90 {132,
"MuAtomicCapture"},
92 {151,
"HadronAtRest"},
93 {152,
"LeptonAtRest"},
94 {161,
"ChargeExchange"},
97 {202,
"Decay_WithSpin"},
98 {203,
"Decay_PionMakeSpin"},
99 {210,
"Decay_Radioactive"},
100 {211,
"Decay_Unknown"},
101 {221,
"Decay_MuAtom "},
102 {231,
"Decay_External"},
103 {310,
"EMDissociation"},
105 if (
auto it = translation.find(process); it != translation.end()) {
108 return "[Unknown process]";
120 addParam(
"maxLevel",
m_maxLevel,
"Show only up to specified depth level, -1 means no limit", -1);
124 addParam(
"showStatus",
m_showStatus,
"Show extendend status information of the particle",
false);
142 m_output <<
"Content of MCParticle list" << std::endl;
146 std::vector<MCParticle*> first_gen;
148 if (mc.getMother() !=
nullptr)
continue;
149 first_gen.emplace_back(&mc);
166 particles.erase(std::remove_if(particles.begin(), particles.end(), [](
MCParticle * mc) {
167 return not mc->hasStatus(MCParticle::c_PrimaryParticle);
168 }), particles.end());
177 std::string colorStart[] = {
"",
""};
178 std::string colorEnd =
"";
181 colorStart[0] = anyExtraInfo ?
"\x1b[31;1m" :
"\x1b[31m";
182 colorStart[1] = anyExtraInfo ?
"\x1b[1m" :
"";
186 TDatabasePDG* pdb = TDatabasePDG::Instance();
189 const auto num_particles = particles.size();
190 size_t particle_index{0};
191 for (
const auto* mc : particles) {
193 const bool last = ++particle_index == num_particles;
194 m_output << indent << (last ?
"╰" :
"├");
197 TParticlePDG* pdef = pdb->GetParticle(mc->getPDG());
199 m_output <<
" (" << mc->getPDG() <<
")" << colorEnd;
202 auto daughters = mc->getDaughters();
207 const std::string newIndent = indent + (last ?
" " :
"│") +
" ";
209 const std::string propIndent =
"\n" + newIndent + (showDaughters ?
"│ " :
"");
211 if ((not showDaughters) and (not daughters.empty())) {
217 m_output << boost::format(
"mass=%.3g energy=%.3g charge=%d") % mc->getMass() % mc->getEnergy() % mc->getCharge();
223 m_output << boost::format(
"p=(%.3g, %.3g, %.3g) |p|=%.3g") % p.X() % p.Y() % p.Z() % p.Mag();
226 const ROOT::Math::XYZVector& v = mc->getVertex();
228 m_output << boost::format(
"production vertex=(%.3g, %.3g, %.3g), time=%.3g") % v.X() % v.Y() % v.Z() % mc->getProductionTime();
232 m_output <<
"status flags=" << statusToString(*mc);
235 m_output <<
"creation process=" << g4ProcessToName(mc->getSecondaryPhysicsProcess());
238 m_output <<
"list index=" << mc->getIndex();
241 if (showDaughters and anyExtraInfo)
m_output << propIndent;
246 printTree(daughters, level + 1, newIndent);
249 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
StoreObjPtr< StringWrapper > m_stringWrapper
string wrapper to store the MCDecayString
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_suppressPrint
Suppress print the information.
bool m_onlyPrimaries
Print only primary particles.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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.