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 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
42static double parseRequiredG4Value(const YAML::Node& node,
43 const string& key,
44 const string& fallback_unit,
45 const std::shared_ptr<GLogger>& logger) {
46 if (!node[key] || node[key].IsNull()) {
48 "Mandatory gparticle field <", key, "> is missing");
49 }
50 return parseG4Value(node, key, fallback_unit, 0.0, logger);
51}
52
53// Build a vector of configured Gparticle instances from the structured "gparticle" option node.
54// The detailed API contract is documented in gparticle_options.h.
55vector<GparticlePtr> getGParticlesFromOption(const std::shared_ptr<GOptions>& gopts, std::shared_ptr<GLogger>& logger) {
56 // Retrieve the structured option node that contains an array of particle definitions.
57 auto gparticle_node = gopts->getOptionNode("gparticle");
58
59 vector<GparticlePtr> gparticles;
60 gparticles.reserve(gparticle_node.size());
61
62 for (auto gparticle_item : gparticle_node) {
63 gparticles.emplace_back(std::make_shared<Gparticle>(
64 gopts->get_required_variable_in_option<string>(gparticle_item, "name"),
65 gopts->get_variable_in_option<int>(gparticle_item, "multiplicity", 1),
66
67 parseRequiredG4Value(gparticle_item, "p", "MeV", logger),
68 parseG4Value(gparticle_item, "delta_p", "MeV", 0, logger),
69 gopts->get_variable_in_option<string>(gparticle_item, "randomMomentumModel", "uniform"),
70
71 parseG4Value(gparticle_item, "theta", "deg", 0, logger),
72 parseG4Value(gparticle_item, "delta_theta", "deg", 0, logger),
73 gopts->get_variable_in_option<string>(gparticle_item, "randomThetaModel", "uniform"),
74 parseG4Value(gparticle_item, "phi", "deg", 0, logger),
75 parseG4Value(gparticle_item, "delta_phi", "deg", 0, logger),
76
77 parseG4Value(gparticle_item, "vx", "cm", 0, logger),
78 parseG4Value(gparticle_item, "vy", "cm", 0, logger),
79 parseG4Value(gparticle_item, "vz", "cm", 0, logger),
80 parseG4Value(gparticle_item, "delta_vx", "cm", 0, logger),
81 parseG4Value(gparticle_item, "delta_vy", "cm", 0, logger),
82 parseG4Value(gparticle_item, "delta_vz", "cm", 0, logger),
83
84 gopts->get_variable_in_option<string>(gparticle_item, "randomVertexModel", "uniform"),
85 logger
86 ));
87 }
88
89 return gparticles;
90}
91
92vector<GparticlePtr> getGParticles(const std::shared_ptr<GOptions>& gopts, std::shared_ptr<GLogger>& logger) {
93 auto gparticles = getGParticlesFromOption(gopts, logger);
94 auto source_particles = getGParticlesFromSources(gopts, logger);
95 gparticles.insert(gparticles.end(), source_particles.begin(), source_particles.end());
96 return gparticles;
97}
98
99
100// Define the gparticle option schema and its human-readable help text.
101// The detailed API contract is documented in gparticle_options.h.
104
105 string help = "Adds a particle to the event generator.\n\n";
106 help += "Kinematic values accept an explicit Geant4 unit (e.g. '4*GeV', '23*deg', '1*mm').\n";
107 help += "A plain number without a unit falls back to the field default: MeV for momentum,\n";
108 help += "deg for angles, cm for vertex coordinates. A warning is logged in that case.\n\n";
109 help += "Examples:\n";
110 help += " - 5 GeV electron along z:\n";
111 help += " -gparticle=\"[{name: e-, p: 5*GeV}]\"\n\n";
112 help += " - one electron and two protons spread in theta:\n";
113 help += " -gparticle=\"[{name: e-, p: 2300*MeV, theta: 23*deg},\n";
114 help += " {name: proton, multiplicity: 2, p: 1200*MeV, theta: 14*deg, delta_theta: 10*deg}]\"\n";
115
116 vector<GVariable> gparticle_v = {
117 {"name", goptions::REQUIRED, "Particle name (mandatory), e.g. \"proton\" or \"e-\""},
118 {"multiplicity", 1, "How many copies of this particle will be generated in each event"},
119 {"p", goptions::REQUIRED, "Particle momentum with unit, e.g. \"4*GeV\" or \"4000*MeV\". "
120 "Plain number falls back to MeV."},
121 {"delta_p", "0*MeV", "Particle momentum spread, centered on p (same unit convention as p)."},
122 {"randomMomentumModel", "uniform", "Momentum randomization. 'gaussian' uses deltas as sigmas."},
123 {"theta", "0*deg", "Particle polar angle, e.g. \"23*deg\" or \"0.4*rad\". "
124 "Plain number falls back to deg."},
125 {"delta_theta", "0*deg", "Particle polar angle spread, centered on theta."},
126 {"randomThetaModel", "uniform",
127 "Distribute cos(theta) or theta. 'cosine': cos(theta) is uniform. 'uniform': theta is uniform."},
128 {"phi", "0*deg", "Particle azimuthal angle, e.g. \"90*deg\". Plain number falls back to deg."},
129 {"delta_phi", "0*deg", "Particle azimuthal angle spread, centered on phi."},
130 {"vx", "0*cm", "Particle vertex x component, e.g. \"1*mm\". Plain number falls back to cm."},
131 {"vy", "0*cm", "Particle vertex y component."},
132 {"vz", "0*cm", "Particle vertex z component."},
133 {"delta_vx", "0*cm", "Particle vertex spread in x."},
134 {"delta_vy", "0*cm", "Particle vertex spread in y."},
135 {"delta_vz", "0*cm", "Particle vertex spread in z."},
136 {"randomVertexModel", "uniform",
137 "Vertex randomization. 'uniform': flat. 'gaussian': deltas are sigmas. 'sphere': uniform in sphere."}
138 };
139
140 goptions.defineOption("gparticle", "define the generator particle(s)", gparticle_v, help);
141
142 string file_help = "Adds particles to the event generator from particle-definition files. \n";
143 file_help += "The option is cumulative and each entry selects a reader by format and filename. \n \n";
144 file_help += "Built-in formats: \n";
145 for (const auto& format : supported_static_reader_formats()) { file_help += " - " + format + "\n"; }
146 file_help += "\n";
147 file_help += "Formats are case-insensitive. Additional formats can be provided by dynamic plugins named ";
148 file_help += "gparticle_<format>_plugin.gplugin exporting GParticleReaderFactory. \n \n";
149 file_help += "Example: \n";
150 file_help += "-gparticlefile=\"[{format: lund, filename: a.lund}]\" \n";
151
152 vector<GVariable> gparticlefile_v = {
153 {"format", goptions::REQUIRED, "Particle file format, for example \"lund\""},
154 {"filename", goptions::REQUIRED, "Input filename containing particle definitions"}
155 };
156
157 goptions.defineOption("gparticlefile", "define generator particles from file(s)", gparticlefile_v, file_help);
158
160
161 return goptions;
162}
163} // namespace gparticle
Conventions and error codes for the gparticle module.
Public API for defining and parsing gparticle-related options.
constexpr const char * GPARTICLE_LOGGER
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()
constexpr int EC__MANDATORY_NOT_FILLED
constexpr RequiredValue REQUIRED
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)