6 #ifndef Pythia8_InputParser_H 7 #define Pythia8_InputParser_H 10 #include "Pythia8/PythiaStdlib.h" 36 string extra =
"", ostream* stream = &cout,
37 string optName =
"h", set<string> aliases = {
"-help",
"H"}) :
38 usageText(usage), examplesText(examples), extraText(extra),
39 streamPtr(stream), helpFlag(optName) {
40 add(optName,
"false",
"Show this help message and exit.", aliases);
49 bool add(
const string& optName,
const string& defString,
50 const string& helpText =
"", set<string> aliases = {}) {
52 if (options.find(optName) != options.end() ||
53 aliasMap.find(optName) != aliasMap.end()) {
54 print(
"Name conflict for '" + optName +
"'.\n");
58 OptionInfo optInfo(optName, defString, helpText, aliases);
59 options[optName] = optInfo;
61 for (
const string& alias : aliases) {
62 if (options.find(alias) != options.end() ||
63 aliasMap.find(alias) != aliasMap.end()) {
64 print(
"Name conflict for alias '" + alias +
"'.\n");
67 aliasMap[alias] = optName;
73 bool require(
const string& optName,
const string& helpText =
"",
74 set<string> aliases = {}) {
75 if (!
add(optName,
"", helpText, aliases))
return false;
76 options[optName].required =
true;
82 enum Status {Valid = -1, Invalid = EXIT_FAILURE, Help = EXIT_SUCCESS};
86 bool valid =
parse(argc, argv);
87 if (!valid)
return Status::Invalid;
90 if (options.find(helpFlag) != options.end() && get<bool>(helpFlag)) {
92 if (usageText !=
"") out =
"Usage: " + usageText;
93 if (examplesText.size() > 0) {
94 out +=
"\nExample" + string(examplesText.size() > 1 ?
"s:" :
":");
95 for (
const string& text: examplesText) out +=
"\n\t" + text;
97 if (options.size() > 0) {
98 out +=
"\nOption" + string(options.size() > 1 ?
"s:\n" :
":\n")
101 print(out + extraText);
106 for (map<string, OptionInfo>::iterator opt = options.begin();
107 opt != options.end(); opt++) {
108 if (opt->second.required && !opt->second.provided) {
109 print(
"Option '-" + opt->first +
"' is required but was not set.\n" 110 "\t -" + opt->first +
" " + opt->second.helpText +
"\n");
114 return valid ? Status::Valid : Status::Invalid;
122 bool parse(
int& argc,
char** argv) {
123 for (
int i = 1; i < argc; ++i) {
124 string arg = argv[i];
127 string optName = arg.substr(1);
129 if (aliasMap.find(optName) != aliasMap.end())
130 optName = aliasMap[optName];
132 if (options.find(optName) != options.end()) {
135 if (i + 1 < argc && argv[i + 1][0] !=
'-') {
136 options[optName].stringValues.push_back(argv[++i]);
137 options[optName].provided =
true;
140 const string& def = options[optName].defaultValue;
141 if (def ==
"false" || def ==
"False" || def ==
"0" 143 options[optName].stringValues.push_back(
"true");
144 options[optName].provided =
true;
145 }
else if (def ==
"true" || def ==
"True" || def ==
"1" 147 options[optName].stringValues.push_back(
"false");
148 options[optName].provided =
true;
150 print(
"Failed to parse command line arguments.\n" 151 "No value passed for option '" +
string(arg) +
"'.\n");
156 print(
"Failed to parse command line arguments.\n" 157 "Unknown option '" +
string(arg) +
"'.\n");
167 bool has(
const string& optName)
const {
168 return options.find(optName) != options.end();
174 T
get(
const string& optName) {
176 print(
"Failed to find option '" + optName +
"'.\n");
180 const OptionInfo& optInfo = options.at(optName);
182 if (optInfo.stringValues.empty())
return T();
183 if (optInfo.stringValues.back().empty())
return T();
185 stringstream conv(optInfo.stringValues.back());
187 conv >> std::boolalpha >> value;
190 print(
"Failed to convert '" + optInfo.optName +
"'.\n");
201 print(
"Failed to find option '" + optName +
"'.\n");
205 const OptionInfo& optInfo = options.at(optName);
207 if (optInfo.stringValues.empty())
return values;
209 for (
const string& stringValue: optInfo.stringValues) {
210 if (stringValue.empty()) {
211 values.push_back(T());
214 stringstream conv(stringValue);
216 conv >> std::boolalpha >> value;
219 print(
"Failed to convert '" + optInfo.optName +
"'.\n");
222 values.push_back(value);
231 auto oItr = options.cbegin();
232 while (oItr != options.cend()) {
233 out <<
"\t-" << oItr->second.optName;
234 if (!oItr->second.aliases.empty()) {
236 auto aItr = oItr->second.aliases.cbegin();
237 while(aItr != oItr->second.aliases.cend()) {
239 if (++aItr != oItr->second.aliases.cend()) out <<
", ";
244 out <<
"\t" << oItr->second.helpText;
245 if (oItr->second.required)
246 out <<
" (required)";
247 else if (oItr->second.defaultValue !=
"")
248 out <<
" (default: " << oItr->second.defaultValue <<
")";
249 if (++oItr != options.cend()) out <<
"\n";
261 OptionInfo(
const string& n,
const string& v,
const string& h,
262 set<string> a) : optName(n), defaultValue(v),
263 stringValues(1, v), helpText(h), aliases(a) {}
266 vector<string> stringValues;
269 bool required{
false};
270 bool provided{
false};
275 vector<string> examplesText{};
277 ostream* streamPtr{};
281 void print(
string out) {
if (streamPtr !=
nullptr) *streamPtr << out;}
284 map<string, OptionInfo> options;
286 map<string, string> aliasMap;
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20