9#include "G4ParticleTable.hh"
10#include "Randomize.hh"
21 const std::string& arandomMomentumModel,
24 const std::string& arandomThetaModel,
33 const std::string& arandomVertexModel,
34 const std::shared_ptr<GLogger>& logger,
35 int agenerator_type) :
37 generator_type(agenerator_type),
38 multiplicity(amultiplicity),
43 delta_theta(adelta_theta),
46 delta_phi(adelta_phi),
47 v(G4ThreeVector(avx, avy, avz)),
48 delta_v(G4ThreeVector(adelta_vx, adelta_vy, adelta_vz)),
61 G4Event* anEvent)
const {
62 auto particleTable = G4ParticleTable::GetParticleTable();
63 std::vector<GparticleRuntimeRecord> runtime_records;
64 if (multiplicity > 0) { runtime_records.reserve(
static_cast<size_t>(multiplicity)); }
68 auto particleDef = particleTable->FindParticle(name);
72 double mass = particleDef->GetPDGMass();
73 particleGun->SetParticleDefinition(particleDef);
77 for (
int i = 0; i < multiplicity; i++) {
78 auto pmev = calculateMomentum();
79 auto kenergy = sqrt(pmev * pmev + mass * mass) - mass;
80 auto thetaRad = randomizeNumberFromSigmaWithModel(theta, delta_theta, randomThetaModel) / CLHEP::rad;
81 auto phiRad = randomizeNumberFromSigmaWithModel(phi, delta_phi,
gutilities::uniform) / CLHEP::rad;
82 auto beamDirection = calculateBeamDirection(thetaRad, phiRad);
83 auto vertex = calculateVertex();
85 runtime_records.push_back({
90 thetaRad * CLHEP::rad,
95 particleGun->SetParticleEnergy(kenergy);
96 particleGun->SetParticleMomentumDirection(beamDirection);
97 particleGun->SetParticlePosition(vertex);
98 particleGun->GeneratePrimaryVertex(anEvent);
100 log->info(2,
"Generated particle <", name,
"> pid ", pid,
101 ", p [MeV]: ", pmev / CLHEP::MeV,
102 ", theta [deg]: ", thetaRad / CLHEP::deg,
103 ", phi [deg]: ", phiRad / CLHEP::deg,
104 ", vertex [cm]: ", vertex / CLHEP::cm);
109 "Particle <", name,
"> not found in G4ParticleTable* ", particleTable);
114 "G4ParticleTable not found - G4ParticleGun*: ", particleGun);
117 return runtime_records;
121double Gparticle::calculateMomentum()
const {
123 double pmev = randomizeNumberFromSigmaWithModel(p, delta_p, randomMomentumModel);
128double Gparticle::calculateKinEnergy(
double mass)
const {
129 double pmev = calculateMomentum();
131 return sqrt(pmev * pmev + mass * mass) - mass;
135G4ThreeVector Gparticle::calculateBeamDirection(
double thetaRad,
double phiRad)
const {
136 G4ThreeVector pdir = G4ThreeVector(
137 cos(phiRad) * sin(thetaRad),
138 sin(phiRad) * sin(thetaRad),
145G4ThreeVector Gparticle::calculateVertex()
const {
148 switch (randomVertexModel) {
167 double max_radius = delta_v.r();
174 radius = x * x + y * y + z * z;
176 while (radius > max_radius * max_radius);
197double Gparticle::randomizeNumberFromSigmaWithModel(
double center,
double delta,
gutilities::randomModel model)
const {
201 return center + ( 2.0 * G4UniformRand() - 1.0 ) * delta;
205 return G4RandGauss::shoot(center, delta);
211 double lower = ( center - delta ) / CLHEP::rad;
212 double upper = ( center + delta ) / CLHEP::rad;
213 double center_rad = 0;
217 do { center_rad = acos(1 - 2 * G4UniformRand()); }
218 while (center_rad < lower || center_rad > upper);
222 center_rad = theta / CLHEP::rad;
225 return center_rad * CLHEP::rad;
242 constexpr int label_w = 15;
243 constexpr int value_w = 12;
246 auto show = [&](
const std::string& label,
const auto& value) {
247 os << left << setw(label_w) << label <<
' '
248 << setw(value_w) << right << setw(value_w) << value <<
'\n';
252 auto showf = [&](
const std::string& label,
double value,
int prec = 3) {
253 std::streamsize old_prec = os.precision();
254 auto old_flags = os.flags();
256 os << left << setw(label_w) << label <<
' '
257 << right << setw(value_w) << std::fixed
258 << std::setprecision(prec) << value <<
'\n';
260 os.precision(old_prec);
265 auto show_pm = [&](
const std::string& label,
266 double val,
double err,
268 std::streamsize old_prec = os.precision();
269 auto old_flags = os.flags();
271 os << left << setw(label_w) << label <<
' '
272 << right << setw(value_w) << std::fixed << setw(value_w)
273 << std::setprecision(prec) << val
274 <<
" ± " << std::setprecision(prec) << err <<
'\n';
276 os.precision(old_prec);
284 <<
" ┌─────────────────────────────────────────────────┐\n"
285 <<
" │ GParticle │\n"
286 <<
" └─────────────────────────────────────────────────┘\n";
291 os << left << setw(label_w) <<
" name:" << right << setw(value_w)
292 << gp.name <<
"(pid " << gp.pid <<
")\n";
294 show(
" multiplicity:", std::to_string(gp.multiplicity));
295 showf(
" mass [MeV]:", gp.get_mass());
299 gp.delta_p / CLHEP::MeV);
301 show(
" p model:",
to_string(gp.randomMomentumModel));
303 show_pm(
" theta [deg]:",
304 gp.theta / CLHEP::deg,
305 gp.delta_theta / CLHEP::deg);
307 show(
" theta model:",
to_string(gp.randomThetaModel));
309 show_pm(
" phi [deg]:",
311 gp.delta_phi / CLHEP::deg);
313 os << left << setw(label_w) <<
" vertex [cm]:" <<
' '
314 << gp.v <<
" ± " << gp.delta_v <<
'\n';
316 show(
" vertex model:",
to_string(gp.randomVertexModel));
322int Gparticle::get_pdg_id() {
323 auto particleTable = G4ParticleTable::GetParticleTable();
326 auto particleDef = particleTable->FindParticle(name);
328 if (particleDef !=
nullptr) {
return particleDef->GetPDGEncoding(); }
331 "Particle <", name,
"> not found in G4ParticleTable* ", particleTable);
336 "G4ParticleTable not found - G4ParticleGun*: ", particleTable);
341double Gparticle::get_mass()
const {
342 auto particleTable = G4ParticleTable::GetParticleTable();
345 auto particleDef = particleTable->FindParticle(name);
348 double mass = particleDef->GetPDGMass();
std::vector< GparticleRuntimeRecord > shootParticle(G4ParticleGun *particleGun, G4Event *anEvent) const
Shoots this particle configuration into a Geant4 event.
Gparticle(const std::string &name, int multiplicity, double p, double delta_p, const std::string &randomMomentumModel, double theta, double delta_theta, const std::string &thetaModel, double phi, double delta_phi, double avx, double avy, double avz, double adelta_vx, double adelta_vy, double adelta_vz, const std::string &randomVertexModel, const std::shared_ptr< GLogger > &logger, int generator_type=1)
Constructs a particle configuration from pre-converted G4-unit values.
Conventions and error codes for the gparticle module.
std::ostream & operator<<(std::ostream &os, const Gparticle &gp)
Definition of the Gparticle class used by the gparticle module.
constexpr int ERR_GPARTICLETABLENOTFOUND
G4ParticleTable could not be obtained (unexpected runtime state).
constexpr int ERR_GPARTICLENOTFOUND
Requested particle name was not found in the G4ParticleTable.
randomModel stringToRandomModel(const std::string &str)
constexpr const char * to_string(randomModel m) noexcept