gparticle
Loading...
Searching...
No Matches
gparticle_options.cc
Go to the documentation of this file.
1// gparticle
2#include "gparticle_options.h"
4#include "gparticle_reader.h"
5
6// gemc
7#include "gfactory_options.h"
8#include "gutilities.h"
9
10// namespace to define options
11namespace gparticle {
12using std::string;
13using std::vector;
14
15// Reads a YAML scalar as a G4-unit-converted double.
16//
17// Accepted forms:
18// "20*deg" — explicit unit, passed directly to getG4Number().
19// "20" — plain number, falls back to fallback_unit with a logged warning.
20// Default units: angles → deg, momentum → MeV, lengths → cm.
21//
22// Returns default_g4val when the key is absent from the node (e.g. optional
23// fields whose schema entry uses NODFLT or whose default was already merged).
24static double parseG4Value(const YAML::Node& node,
25 const string& key,
26 const string& fallback_unit,
27 double default_g4val,
28 const std::shared_ptr<GLogger>& logger) {
29 if (!node[key]) return default_g4val;
30
31 const auto val = node[key].as<string>();
32 if (val.find('*') != string::npos) {
33 return gutilities::getG4Number(val);
34 }
35
36 // Plain number without a unit — apply the fallback and warn.
37 logger->warning("gparticle field <", key, "> value <", val, "> has no unit; assuming ",
38 fallback_unit, ". Use '", val, "*", fallback_unit, "' to suppress this warning.");
39 return gutilities::getG4Number(val + "*" + fallback_unit);
40}
41
42// Build a vector of configured Gparticle instances from the structured "gparticle" option node.
43// The detailed API contract is documented in gparticle_options.h.
44vector<GparticlePtr> getGParticlesFromOption(const std::shared_ptr<GOptions>& gopts, std::shared_ptr<GLogger>& logger) {
45 // Retrieve the structured option node that contains an array of particle definitions.
46 auto gparticle_node = gopts->getOptionNode("gparticle");
47
48 vector<GparticlePtr> gparticles;
49 gparticles.reserve(gparticle_node.size());
50
51 for (auto gparticle_item : gparticle_node) {
52 gparticles.emplace_back(std::make_shared<Gparticle>(
53 gopts->get_variable_in_option<string>(gparticle_item, "name", goptions::NODFLT),
54 gopts->get_variable_in_option<int>(gparticle_item, "multiplicity", 1),
55
56 parseG4Value(gparticle_item, "p", "MeV", GPARTICLENOTDEFINED, logger),
57 parseG4Value(gparticle_item, "delta_p", "MeV", 0, logger),
58 gopts->get_variable_in_option<string>(gparticle_item, "randomMomentumModel", "uniform"),
59
60 parseG4Value(gparticle_item, "theta", "deg", 0, logger),
61 parseG4Value(gparticle_item, "delta_theta", "deg", 0, logger),
62 gopts->get_variable_in_option<string>(gparticle_item, "randomThetaModel", "uniform"),
63 parseG4Value(gparticle_item, "phi", "deg", 0, logger),
64 parseG4Value(gparticle_item, "delta_phi", "deg", 0, logger),
65
66 parseG4Value(gparticle_item, "vx", "cm", 0, logger),
67 parseG4Value(gparticle_item, "vy", "cm", 0, logger),
68 parseG4Value(gparticle_item, "vz", "cm", 0, logger),
69 parseG4Value(gparticle_item, "delta_vx", "cm", 0, logger),
70 parseG4Value(gparticle_item, "delta_vy", "cm", 0, logger),
71 parseG4Value(gparticle_item, "delta_vz", "cm", 0, logger),
72
73 gopts->get_variable_in_option<string>(gparticle_item, "randomVertexModel", "uniform"),
74 logger
75 ));
76 }
77
78 return gparticles;
79}
80
81vector<GparticlePtr> getGParticles(const std::shared_ptr<GOptions>& gopts, std::shared_ptr<GLogger>& logger) {
82 auto gparticles = getGParticlesFromOption(gopts, logger);
83 auto source_particles = getGParticlesFromSources(gopts, logger);
84 gparticles.insert(gparticles.end(), source_particles.begin(), source_particles.end());
85 return gparticles;
86}
87
88
89// Define the gparticle option schema and its human-readable help text.
90// The detailed API contract is documented in gparticle_options.h.
93
94 string help = "Adds a particle to the event generator.\n\n";
95 help += "Kinematic values accept an explicit Geant4 unit (e.g. '4*GeV', '23*deg', '1*mm').\n";
96 help += "A plain number without a unit falls back to the field default: MeV for momentum,\n";
97 help += "deg for angles, cm for vertex coordinates. A warning is logged in that case.\n\n";
98 help += "Examples:\n";
99 help += " - 5 GeV electron along z:\n";
100 help += " -gparticle=\"[{name: e-, p: 5*GeV}]\"\n\n";
101 help += " - one electron and two protons spread in theta:\n";
102 help += " -gparticle=\"[{name: e-, p: 2300*MeV, theta: 23*deg},\n";
103 help += " {name: proton, multiplicity: 2, p: 1200*MeV, theta: 14*deg, delta_theta: 10*deg}]\"\n";
104
105 vector<GVariable> gparticle_v = {
106 {"name", goptions::NODFLT, "Particle name (mandatory), e.g. \"proton\" or \"e-\""},
107 {"multiplicity", 1, "How many copies of this particle will be generated in each event"},
108 {"p", goptions::NODFLT, "Particle momentum with unit, e.g. \"4*GeV\" or \"4000*MeV\". "
109 "Plain number falls back to MeV."},
110 {"delta_p", "0*MeV", "Particle momentum spread, centered on p (same unit convention as p)."},
111 {"randomMomentumModel", "uniform", "Momentum randomization. 'gaussian' uses deltas as sigmas."},
112 {"theta", "0*deg", "Particle polar angle, e.g. \"23*deg\" or \"0.4*rad\". "
113 "Plain number falls back to deg."},
114 {"delta_theta", "0*deg", "Particle polar angle spread, centered on theta."},
115 {"randomThetaModel", "uniform",
116 "Distribute cos(theta) or theta. 'cosine': cos(theta) is uniform. 'uniform': theta is uniform."},
117 {"phi", "0*deg", "Particle azimuthal angle, e.g. \"90*deg\". Plain number falls back to deg."},
118 {"delta_phi", "0*deg", "Particle azimuthal angle spread, centered on phi."},
119 {"vx", "0*cm", "Particle vertex x component, e.g. \"1*mm\". Plain number falls back to cm."},
120 {"vy", "0*cm", "Particle vertex y component."},
121 {"vz", "0*cm", "Particle vertex z component."},
122 {"delta_vx", "0*cm", "Particle vertex spread in x."},
123 {"delta_vy", "0*cm", "Particle vertex spread in y."},
124 {"delta_vz", "0*cm", "Particle vertex spread in z."},
125 {"randomVertexModel", "uniform",
126 "Vertex randomization. 'uniform': flat. 'gaussian': deltas are sigmas. 'sphere': uniform in sphere."}
127 };
128
129 goptions.defineOption("gparticle", "define the generator particle(s)", gparticle_v, help);
130
131 string file_help = "Adds particles to the event generator from particle-definition files. \n";
132 file_help += "The option is cumulative and each entry selects a reader by format and filename. \n \n";
133 file_help += "Built-in formats: \n";
134 for (const auto& format : supported_static_reader_formats()) { file_help += " - " + format + "\n"; }
135 file_help += "\n";
136 file_help += "Formats are case-insensitive. Additional formats can be provided by dynamic plugins named ";
137 file_help += "gparticle_<format>_plugin.gplugin exporting GParticleReaderFactory. \n \n";
138 file_help += "Example: \n";
139 file_help += "-gparticlefile=\"[{format: lund, filename: a.lund}]\" \n";
140
141 vector<GVariable> gparticlefile_v = {
142 {"format", goptions::NODFLT, "Particle file format, for example \"lund\""},
143 {"filename", goptions::NODFLT, "Input filename containing particle definitions"}
144 };
145
146 goptions.defineOption("gparticlefile", "define generator particles from file(s)", gparticlefile_v, file_help);
147
149
150 return goptions;
151}
152} // namespace gparticle
Conventions and error codes for the gparticle module.
Public API for defining and parsing gparticle-related options.
constexpr const char * GPARTICLE_LOGGER
#define GPARTICLENOTDEFINED
Sentinel value used to mark an unset/undefined numeric parameter.
vector< GparticlePtr > getGParticles(const std::shared_ptr< GOptions > &gopts, std::shared_ptr< GLogger > &logger)
Builds the list of generator particles from structured options.
vector< GparticlePtr > getGParticlesFromOption(const std::shared_ptr< GOptions > &gopts, std::shared_ptr< GLogger > &logger)
Builds inline generator particles from only the -gparticle option.
GOptions defineOptions()
Defines the structured options used by the gparticle module.
GOptions defineOptions()
const std::string NODFLT
const std::vector< std::string > & supported_static_reader_formats()
Returns built-in file-reader format tokens.
std::vector< GparticlePtr > getGParticlesFromSources(const std::shared_ptr< GOptions > &gopts, std::shared_ptr< GLogger > &logger)
Loads propagated particles from all configured file sources.
double getG4Number(const string &v, bool warnIfNotUnit=false)