1 #include "Framework/Conventions/GBuild.h"
2 #ifdef __GENIE_INCL_ENABLED__
13 #ifdef HAS_BOOST_PROGRAM_OPTIONS
17 #include "G4INCLLogger.hh"
18 #include "G4INCLParticleTable.hh"
19 #include "DatafilePaths.hh"
27 const std::string ConfigParser::suggestHelpMsg =
"You might want to run `INCLCascade --help' to get a help message.\n";
30 const std::string ConfigParser::theNoneName =
"none";
31 #ifdef INCL_DEEXCITATION_SMM
32 const std::string ConfigParser::theSMMName =
"SMM";
34 #ifdef INCL_DEEXCITATION_GEMINIXX
35 const std::string ConfigParser::theGEMINIXXName =
"GEMINIXX";
37 #ifdef INCL_DEEXCITATION_ABLAXX
38 const std::string ConfigParser::theABLAv3pName =
"ABLAv3p";
40 #ifdef INCL_DEEXCITATION_ABLA07
41 const std::string ConfigParser::theABLA07Name =
"ABLA07";
44 const std::string ConfigParser::listSeparator =
"\n \t";
46 ConfigParser::ConfigParser() :
47 runOptDesc(
"Run options"),
48 hiddenOptDesc(
"Hidden options"),
49 genericOptDesc(
"Generic options"),
50 physicsOptDesc(
"Physics options"),
51 deExcitationModelList(
52 listSeparator + theNoneName
53 #ifdef INCL_DEEXCITATION_ABLA07
54 + listSeparator + theABLA07Name
56 #ifdef INCL_DEEXCITATION_ABLAXX
57 + listSeparator + theABLAv3pName
59 #ifdef INCL_DEEXCITATION_GEMINIXX
60 + listSeparator + theGEMINIXXName
62 #ifdef INCL_DEEXCITATION_SMM
63 + listSeparator + theSMMName
68 defaultDeExcitationModel = theNoneName;
69 #ifdef INCL_DEEXCITATION_SMM
70 defaultDeExcitationModel = theSMMName;
72 #ifdef INCL_DEEXCITATION_GEMINIXX
73 defaultDeExcitationModel = theGEMINIXXName;
75 #ifdef INCL_DEEXCITATION_ABLAXX
76 defaultDeExcitationModel = theABLAv3pName;
78 #ifdef INCL_DEEXCITATION_ABLA07
79 defaultDeExcitationModel = theABLA07Name;
83 size_t defaultModelIndex = deExcitationModelList.find(defaultDeExcitationModel);
84 if(defaultModelIndex!=std::string::npos) {
85 deExcitationModelList = deExcitationModelList.substr(0, defaultModelIndex+defaultDeExcitationModel.size())
87 + deExcitationModelList.substr(defaultModelIndex+defaultDeExcitationModel.size(), std::string::npos);
91 hiddenOptDesc.add_options()
92 (
"input-file", po::value<std::string>(&config.inputFileName),
"input file")
93 (
"impact-parameter", po::value<double>(&config.impactParameter)->default_value(-1.),
"impact parameter")
94 (
"cascade-action", po::value<std::string>(&config.cascadeAction)->default_value(
"default"),
"cascade action:\n \tdefault (default)\n \tavatar-dump")
98 std::stringstream verbosityDescription;
99 verbosityDescription <<
"set verbosity level:\n"
100 <<
" 0: \tquiet, suppress all output messages\n"
101 <<
" " << G4INCL::InfoMsg <<
": \tminimal logging\n"
102 <<
" " << G4INCL::FatalMsg <<
": \tlog fatal error messages as well\n"
103 <<
" " << G4INCL::ErrorMsg <<
": \tlog error messages as well\n"
104 <<
" " << G4INCL::WarningMsg <<
": \tlog warning messages as well\n"
105 <<
" " << G4INCL::DebugMsg <<
": \tlog debug messages as well\n"
106 <<
" " << G4INCL::DataBlockMsg <<
": \tlog data-block messages as well";
108 genericOptDesc.add_options()
109 (
"help,h",
"produce this help message")
110 (
"version",
"print version string and exit")
114 std::stringstream randomSeedsDescription;
115 randomSeedsDescription <<
"comma-separated list of seeds for the random-number generator. Allowed seed range: "
116 << randomSeedMin <<
"-" << randomSeedMax <<
".";
118 runOptDesc.add_options()
119 (
"title", po::value<std::string>(&config.title)->default_value(
"INCL default run title"),
"run title")
120 (
"output,o", po::value<std::string>(&config.outputFileRoot),
"root for generating output file names. File-specific suffixes (.root, .out, etc.) will be appended to this root. Defaults to the input file name, if given; otherwise, defaults to a string composed of the explicitly specified options and of a customisable suffix, if provided using the -s option")
121 (
"suffix,s", po::value<std::string>(&config.fileSuffix),
"suffix to be appended to generated output file names")
122 (
"logfile,l", po::value<std::string>(&config.logFileName),
"log file name. Defaults to `<output_root>.log'. Use `-' if you want to redirect logging to stdout")
123 (
"number-shots,N", po::value<int>(&config.nShots),
"* number of shots")
124 (
"target,t", po::value<std::string>(&config.targetString),
"* target nuclide. Can be specified as Fe56, 56Fe, Fe-56, 56-Fe, Fe_56, 56_Fe or Fe. If the mass number is omitted, natural target composition is assumed.")
125 (
"projectile,p", po::value<std::string>(&config.projectileString),
"* projectile name:\n"
128 " \tpi+, piplus, pion+, pionplus\n"
129 " \tpi0, pizero, pion0, pionzero\n"
130 " \tpi-, piminus, pion-, pionminus\n"
131 " \td, t, a, deuteron, triton, alpha\n"
132 " \tHe-4, He4, 4He (and so on)")
133 (
"energy,E", po::value<double>(&config.projectileKineticEnergy),
"* total kinetic energy of the projectile, in MeV")
134 (
"verbose-event", po::value<int>(&config.verboseEvent)->default_value(-1),
"request verbose logging for the specified event only")
135 (
"random-number-generator", po::value<std::string>(&config.randomNumberGenerator)->default_value(
"Ranecu"),
"Random number generator to use:\n \tRanecu (2 seeds, default)\n \tRanecu3 (3 seeds)")
136 (
"random-seeds", po::value<std::string>(&config.randomSeeds)->default_value(
"666,777,1234"), randomSeedsDescription.str().c_str())
137 (
"autosave-frequency", po::value<unsigned int>(&config.autosaveFrequency)->default_value(10000),
"frequency between automatic saves of the output/log files")
139 (
"root-selection", po::value<std::string>(&config.rootSelectionString)->default_value(
""),
"ROOT selection for abridged output ROOT tree. For example: \"A==1 && Z==0 && theta<3\" selects only events where a neutron is scattered in the forward direction.")
140 (
"concise-root-tree", po::value<bool>(&config.conciseROOTTree)->default_value(
false),
"whether INCL++ should output a concise ROOT event tree:\n \ttrue, 1\n \tfalse, 0 (default)")
142 (
"inverse-kinematics", po::value<bool>(&config.inverseKinematics)->default_value(
false),
"whether INCL++ should output variables describing the reaction in inverse kinematics:\n \ttrue, 1\n \tfalse, 0 (default)")
143 (
"inclxx-datafile-path", po::value<std::string>(&config.INCLXXDataFilePath)->default_value(defaultINCLXXDatafilePath),
144 "path to the INCL++ data files")
145 #ifdef INCL_DEEXCITATION_ABLA07
146 (
"abla07-datafile-path", po::value<std::string>(&config.abla07DataFilePath)->default_value(defaultABLA07DatafilePath),
147 "path to the ABLA07 data files")
149 #ifdef INCL_DEEXCITATION_ABLAXX
150 (
"ablav3p-cxx-datafile-path", po::value<std::string>(&config.ablav3pCxxDataFilePath)->default_value(defaultABLAXXDatafilePath),
151 "path to the ABLAv3p data files")
153 #ifdef INCL_DEEXCITATION_GEMINIXX
154 (
"geminixx-datafile-path", po::value<std::string>(&config.geminixxDataFilePath)->default_value(defaultGEMINIXXDatafilePath),
155 "path to the GEMINI++ data files")
157 (
"verbosity,v", po::value<int>(&config.verbosity)->default_value(4), verbosityDescription.str().c_str())
161 physicsOptDesc.add_options()
162 (
"de-excitation,d", po::value<std::string>(&config.deExcitationString)->default_value(defaultDeExcitationModel.c_str()), (
"which de-excitation model to use:" + deExcitationModelList).c_str())
163 #ifdef INCL_DEEXCITATION_FERMI_BREAKUP
164 (
"max-mass-fermi-breakup", po::value<int>(&config.maxMassFermiBreakUp)->default_value(16),
"Maximum remnant mass for Fermi break-up (0-16). Default: 16.")
165 (
"max-charge-fermi-breakup", po::value<int>(&config.maxChargeFermiBreakUp)->default_value(8),
"Maximum remnant mass for Fermi break-up (0-8). Default: 8.")
167 (
"pauli", po::value<std::string>(&config.pauliString)->default_value(
"strict-statistical"),
"Pauli-blocking algorithm:\n"
168 " \tstrict-statistical (default)\n"
173 (
"cdpp", po::value<bool>(&config.CDPP)->default_value(
true),
"whether to apply CDPP after collisions:\n \ttrue, 1 (default)\n \tfalse, 0")
174 (
"coulomb", po::value<std::string>(&config.coulombString)->default_value(
"non-relativistic"),
"Coulomb-distortion algorithm:\n \tnon-relativistic (default)\n \tnone")
175 (
"potential", po::value<std::string>(&config.potentialString)->default_value(
"isospin-energy"),
"nucleon potential:\n \tisospin-energy-smooth\n \tisospin-energy (default)\n \tisospin\n \tconstant")
176 (
"pion-potential", po::value<bool>(&config.pionPotential)->default_value(
"true"),
"whether to use a pion potential:\n \ttrue, 1 (default)\n \tfalse, 0")
177 (
"local-energy-BB", po::value<std::string>(&config.localEnergyBBString)->default_value(
"first-collision"),
"local energy in baryon-baryon collisions:\n \talways\n \tfirst-collision (default)\n \tnever")
178 (
"local-energy-pi", po::value<std::string>(&config.localEnergyPiString)->default_value(
"first-collision"),
"local energy in pi-N collisions and in delta decays:\n \talways\n \tfirst-collision (default)\n \tnever")
179 (
"cluster-algorithm", po::value<std::string>(&config.clusterAlgorithmString)->default_value(
"intercomparison"),
"clustering algorithm for production of composites:\n \tintercomparison (default)\n \tnone")
180 (
"cluster-max-mass", po::value<int>(&config.clusterMaxMass)->default_value(8),
"maximum mass of produced composites:\n \tminimum 2\n \tmaximum 12")
181 (
"back-to-spectator", po::value<bool>(&config.backToSpectator)->default_value(
"true"),
"whether to use back-to-spectator:\n \ttrue, 1 (default)\n \tfalse, 0")
182 (
"use-real-masses", po::value<bool>(&config.useRealMasses)->default_value(
"true"),
"whether to use real masses for the outgoing particle energies:\n \ttrue, 1 (default)\n \tfalse, 0")
183 (
"separation-energies", po::value<std::string>(&config.separationEnergyString)->default_value(
"INCL"),
"how to assign the separation energies of the INCL nucleus:\n \tINCL (default)\n \treal\n \treal-light")
184 (
"fermi-momentum", po::value<std::string>(&config.fermiMomentumString)->default_value(
"constant"),
"how to assign the Fermi momentum of the INCL nucleus:\n \tconstant (default)\n \tconstant-light\n \tmass-dependent\n \t[a positive value]")
185 (
"cutNN", po::value<double>(&config.cutNN)->default_value(1910.),
"minimum CM energy for nucleon-nucleon collisions, in MeV. Default: 1910.")
186 (
"rp-correlation", po::value<double>(&config.rpCorrelationCoefficient)->default_value(1.),
"correlation coefficient for the r-p correlation. Default: 1 (full correlation).")
187 (
"rp-correlation-p", po::value<double>(&config.rpCorrelationCoefficientProton)->default_value(1.),
"correlation coefficient for the proton r-p correlation. Overrides the value specified using the rp-correlation option. Default: 1 (full correlation).")
188 (
"rp-correlation-n", po::value<double>(&config.rpCorrelationCoefficientNeutron)->default_value(1.),
"correlation coefficient for the neutron r-p correlation. Overrides the value specified using the rp-correlation option. Default: 1 (full correlation).")
189 (
"neutron-skin", po::value<double>(&config.neutronSkin)->default_value(0.),
"thickness of the neutron skin, in fm. Default: 0.")
190 (
"neutron-halo", po::value<double>(&config.neutronHalo)->default_value(0.),
"thickness of the neutron halo, in fm. Default: 0.")
191 (
"refraction", po::value<bool>(&config.refraction)->default_value(
false),
"whether to use refraction when particles are transmitted. Default: false.")
192 (
"cross-sections", po::value<std::string>(&config.crossSectionsString)->default_value(
"multipions"),
"cross-section parametrizations:\n"
193 " \tmultipions (default)\n"
194 " \ttruncated-multipions\n"
196 (
"max-number-multipions", po::value<int>(&config.maxNumberMultipions)->default_value(-1),
"maximum number of pions that can be produced in multipion collisions. When specified with arg>0, it enforces cross-sections=truncated-multipions. Default: -1 (no limit).")
197 (
"phase-space-generator", po::value<std::string>(&config.phaseSpaceGenerator)->default_value(
"raubold-lynch"),
"algorithm to generate phase-space decays:\n \tRaubold-Lynch (default)\n \tKopylov")
198 (
"hadronization-time", po::value<double>(&config.hadronizationTime)->default_value(0.),
"Hadronization time, in fm/c. Particles emerging from collisions are forbidden to recollide within this time. Default: 0.")
202 cmdLineOptions.add(hiddenOptDesc).add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
205 configFileOptions.add(runOptDesc).add(physicsOptDesc);
208 visibleOptions.add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
213 p.add(
"input-file", 1);
217 ConfigParser::~ConfigParser() {
220 G4INCL::Config *ConfigParser::parse(
int argc,
char *argv[]) {
228 po::command_line_style::default_style &
229 ~po::command_line_style::allow_guessing;
230 variablesMap.clear();
233 po::store(po::command_line_parser(argc, argv).
235 options(cmdLineOptions).positional(p).run(), variablesMap);
236 po::notify(variablesMap);
240 if(variablesMap.count(
"input-file")) {
241 std::ifstream inputFileStream(config.inputFileName.c_str());
242 if(!inputFileStream) {
243 std::cerr <<
"Cannot open input file: " << config.inputFileName <<
'\n';
247 po::parsed_options parsedOptions = po::parse_config_file(inputFileStream, configFileOptions,
true);
250 std::vector<std::string> unhandledOptions =
251 po::collect_unrecognized(parsedOptions.options, po::exclude_positional);
252 bool ignoreNext =
false;
253 const std::string match =
"-datafile-path";
254 for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(),
e=unhandledOptions.end(); i!=
e; ++i) {
259 if(i->rfind(match) == i->length()-match.length()) {
260 std::cout <<
"# Ignoring unrecognized option " << *i <<
'\n';
263 std::cerr <<
"Error: unrecognized option " << *i <<
'\n';
264 std::cerr << suggestHelpMsg;
270 po::store(parsedOptions, variablesMap);
271 po::notify(variablesMap);
273 inputFileStream.close();
277 std::string configFileName;
278 const char *
const configFileVar = getenv(
"INCLXXRC");
280 configFileName = configFileVar;
282 const char *
const homeDirectoryPointer = getenv(
"HOME");
283 if(homeDirectoryPointer) {
284 std::string homeDirectory(homeDirectoryPointer);
285 configFileName = homeDirectory +
"/.inclxxrc";
287 std::cerr <<
"Could not determine the user's home directory. "
288 <<
"Are you running Linux, Unix or BSD?"<< std::endl;
293 std::ifstream configFileStream(configFileName.c_str());
294 if(configFileStream) {
295 std::cout <<
"# Reading config file " << configFileName << std::endl;
298 po::parsed_options parsedOptions = po::parse_config_file(configFileStream, configFileOptions,
true);
299 po::store(parsedOptions, variablesMap);
302 std::vector<std::string> unhandledOptions =
303 po::collect_unrecognized(parsedOptions.options, po::exclude_positional);
304 bool ignoreNext =
false;
305 const std::string match =
"-datafile-path";
306 for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(),
e=unhandledOptions.end(); i!=
e; ++i) {
311 if(i->rfind(match) == i->length()-match.length()) {
312 std::cout <<
"Ignoring unrecognized option " << *i << std::endl;
315 std::cerr <<
"Error: unrecognized option " << *i << std::endl;
316 std::cerr << suggestHelpMsg;
322 po::store(parsedOptions, variablesMap);
323 po::notify(variablesMap);
325 configFileStream.close();
334 if(variablesMap.count(
"help")) {
336 <<
"Usage: INCLCascade [options] <input_file>" << std::endl
337 << std::endl <<
"Options marked with a * are compulsory, i.e. they must be provided either on\nthe command line or in the input file." << std::endl
338 << visibleOptions << std::endl;
343 if(variablesMap.count(
"version")) {
344 std::cout <<
"INCL++ version " << config.getVersionString() << std::endl;
349 std::string missingOption(
"");
350 if(!variablesMap.count(
"number-shots"))
351 missingOption =
"number-shots";
352 else if(!variablesMap.count(
"target"))
353 missingOption =
"target";
354 else if(!variablesMap.count(
"projectile"))
355 missingOption =
"projectile";
356 else if(!variablesMap.count(
"energy"))
357 missingOption =
"energy";
358 if(!missingOption.empty()) {
359 std::cerr <<
"Required option " << missingOption <<
" is missing." << std::endl;
360 std::cerr << suggestHelpMsg;
365 config.projectileSpecies = G4INCL::ParticleSpecies(config.projectileString);
366 if(config.projectileSpecies.theType == G4INCL::UnknownParticle) {
367 std::cerr <<
"Error: unrecognized particle type " << config.projectileString << std::endl;
368 std::cerr << suggestHelpMsg;
373 if(variablesMap.count(
"target")) {
374 config.targetSpecies = G4INCL::ParticleSpecies(config.targetString);
375 if(config.targetSpecies.theType!=G4INCL::Composite) {
376 std::cerr <<
"Unrecognized target. You specified: " << config.targetString << std::endl
377 <<
" The target nuclide must be specified in one of the following forms:" << std::endl
378 <<
" Fe56, 56Fe, Fe-56, 56-Fe, Fe_56, 56_Fe, Fe" << std::endl
379 <<
" You can also use IUPAC element names (such as Uuh)." << std::endl;
380 std::cerr << suggestHelpMsg;
383 if(config.targetSpecies.theA==0)
384 config.naturalTarget =
true;
388 if(variablesMap.count(
"pauli")) {
389 std::string pauliNorm = config.pauliString;
390 std::transform(pauliNorm.begin(), pauliNorm.end(), pauliNorm.begin(), ::tolower);
391 if(pauliNorm==
"statistical")
392 config.pauliType = G4INCL::StatisticalPauli;
393 else if(pauliNorm==
"strict")
394 config.pauliType = G4INCL::StrictPauli;
395 else if(pauliNorm==
"strict-statistical")
396 config.pauliType = G4INCL::StrictStatisticalPauli;
397 else if(pauliNorm==
"global")
398 config.pauliType = G4INCL::GlobalPauli;
399 else if(pauliNorm==
"none")
400 config.pauliType = G4INCL::NoPauli;
402 std::cerr <<
"Unrecognized Pauli-blocking algorithm. Must be one of:" << std::endl
403 <<
" strict-statistical (default)" << std::endl
404 <<
" strict" << std::endl
405 <<
" statistical" << std::endl
406 <<
" global" << std::endl
407 <<
" none" << std::endl;
408 std::cerr << suggestHelpMsg;
414 if(variablesMap.count(
"coulomb")) {
415 std::string coulombNorm = config.coulombString;
416 std::transform(coulombNorm.begin(), coulombNorm.end(), coulombNorm.begin(), ::tolower);
417 if(coulombNorm==
"non-relativistic")
418 config.coulombType = G4INCL::NonRelativisticCoulomb;
419 else if(coulombNorm==
"none")
420 config.coulombType = G4INCL::NoCoulomb;
422 std::cerr <<
"Unrecognized Coulomb-distortion algorithm. Must be one of:" << std::endl
423 <<
" non-relativistic (default)" << std::endl
424 <<
" none" << std::endl;
425 std::cerr << suggestHelpMsg;
431 if(variablesMap.count(
"potential")) {
432 std::string potentialNorm = config.potentialString;
433 std::transform(potentialNorm.begin(), potentialNorm.end(), potentialNorm.begin(), ::tolower);
434 if(potentialNorm==
"isospin-energy-smooth") {
435 config.potentialType = G4INCL::IsospinEnergySmoothPotential;
436 }
else if(potentialNorm==
"isospin-energy") {
437 config.potentialType = G4INCL::IsospinEnergyPotential;
438 }
else if(potentialNorm==
"isospin")
439 config.potentialType = G4INCL::IsospinPotential;
440 else if(potentialNorm==
"constant")
441 config.potentialType = G4INCL::ConstantPotential;
443 std::cerr <<
"Unrecognized potential type. Must be one of:" << std::endl
444 <<
" isospin-energy-smooth" << std::endl
445 <<
" isospin-energy (default)" << std::endl
446 <<
" isospin" << std::endl
447 <<
" constant" << std::endl;
448 std::cerr << suggestHelpMsg;
454 if(variablesMap.count(
"local-energy-BB")) {
455 std::string localEnergyBBNorm = config.localEnergyBBString;
456 std::transform(localEnergyBBNorm.begin(), localEnergyBBNorm.end(), localEnergyBBNorm.begin(), ::tolower);
457 if(localEnergyBBNorm==
"always") {
458 config.localEnergyBBType = G4INCL::AlwaysLocalEnergy;
459 }
else if(localEnergyBBNorm==
"first-collision")
460 config.localEnergyBBType = G4INCL::FirstCollisionLocalEnergy;
461 else if(localEnergyBBNorm==
"never")
462 config.localEnergyBBType = G4INCL::NeverLocalEnergy;
464 std::cerr <<
"Unrecognized local-energy-BB type. Must be one of:" << std::endl
465 <<
" always" << std::endl
466 <<
" first-collision (default)" << std::endl
467 <<
" never" << std::endl;
468 std::cerr << suggestHelpMsg;
474 if(variablesMap.count(
"local-energy-pi")) {
475 std::string localEnergyPiNorm = config.localEnergyPiString;
476 std::transform(localEnergyPiNorm.begin(), localEnergyPiNorm.end(), localEnergyPiNorm.begin(), ::tolower);
477 if(localEnergyPiNorm==
"always") {
478 config.localEnergyPiType = G4INCL::AlwaysLocalEnergy;
479 }
else if(localEnergyPiNorm==
"first-collision")
480 config.localEnergyPiType = G4INCL::FirstCollisionLocalEnergy;
481 else if(localEnergyPiNorm==
"never")
482 config.localEnergyPiType = G4INCL::NeverLocalEnergy;
484 std::cerr <<
"Unrecognized local-energy-pi type. Must be one of:" << std::endl
485 <<
" always" << std::endl
486 <<
" first-collision" << std::endl
487 <<
" never (default)" << std::endl;
488 std::cerr << suggestHelpMsg;
494 if(variablesMap.count(
"de-excitation")) {
495 std::string deExcitationNorm = config.deExcitationString;
496 std::transform(deExcitationNorm.begin(),
497 deExcitationNorm.end(),
498 deExcitationNorm.begin(), ::tolower);
499 if(deExcitationNorm==
"none")
500 config.deExcitationType = G4INCL::DeExcitationNone;
501 #ifdef INCL_DEEXCITATION_ABLAXX
502 else if(deExcitationNorm==
"ablav3p")
503 config.deExcitationType = G4INCL::DeExcitationABLAv3p;
505 #ifdef INCL_DEEXCITATION_ABLA07
506 else if(deExcitationNorm==
"abla07")
507 config.deExcitationType = G4INCL::DeExcitationABLA07;
509 #ifdef INCL_DEEXCITATION_SMM
510 else if(deExcitationNorm==
"smm")
511 config.deExcitationType = G4INCL::DeExcitationSMM;
513 #ifdef INCL_DEEXCITATION_GEMINIXX
514 else if(deExcitationNorm==
"geminixx")
515 config.deExcitationType = G4INCL::DeExcitationGEMINIXX;
518 std::cerr <<
"Unrecognized de-excitation model. "
519 <<
"Must be one of:" << std::endl
520 << deExcitationModelList << std::endl;
521 std::cerr << suggestHelpMsg;
526 #ifdef INCL_DEEXCITATION_FERMI_BREAKUP
528 if(variablesMap.count(
"max-mass-fermi-breakup")) {
529 if(config.maxMassFermiBreakUp<0 || config.maxMassFermiBreakUp>16) {
530 std::cerr <<
"The maximum mass for Fermi breakup must belong to the [0,16] interval. " << std::endl;
531 std::cerr << suggestHelpMsg;
535 if(variablesMap.count(
"max-charge-fermi-breakup")) {
536 if(config.maxChargeFermiBreakUp<0 || config.maxChargeFermiBreakUp>8) {
537 std::cerr <<
"The maximum charge for Fermi breakup must belong to the [0,8] interval. " << std::endl;
538 std::cerr << suggestHelpMsg;
545 if(variablesMap.count(
"cluster-algorithm")) {
546 std::string clusterAlgorithmNorm = config.clusterAlgorithmString;
547 std::transform(clusterAlgorithmNorm.begin(),
548 clusterAlgorithmNorm.end(),
549 clusterAlgorithmNorm.begin(), ::tolower);
550 if(clusterAlgorithmNorm==
"none")
551 config.clusterAlgorithmType = G4INCL::NoClusterAlgorithm;
552 else if(clusterAlgorithmNorm==
"intercomparison")
553 config.clusterAlgorithmType = G4INCL::IntercomparisonClusterAlgorithm;
555 std::cerr <<
"Unrecognized cluster algorithm. "
556 <<
"Must be one of:" << std::endl
557 <<
" intercomparison (default)" << std::endl
558 <<
" none" << std::endl;
559 std::cerr << suggestHelpMsg;
565 if(variablesMap.count(
"cluster-max-mass") && config.clusterMaxMass < 2 && config.clusterMaxMass > 12) {
566 std::cerr <<
"Maximum cluster mass outside the allowed range. Must be between 2 and 12 (included)"
573 if(variablesMap.count(
"separation-energies")) {
574 std::string separationEnergyNorm = config.separationEnergyString;
575 std::transform(separationEnergyNorm.begin(),
576 separationEnergyNorm.end(),
577 separationEnergyNorm.begin(), ::tolower);
578 if(separationEnergyNorm==
"incl")
579 config.separationEnergyType = G4INCL::INCLSeparationEnergy;
580 else if(separationEnergyNorm==
"real")
581 config.separationEnergyType = G4INCL::RealSeparationEnergy;
582 else if(separationEnergyNorm==
"real-light")
583 config.separationEnergyType = G4INCL::RealForLightSeparationEnergy;
585 std::cerr <<
"Unrecognized separation-energies option. "
586 <<
"Must be one of:" << std::endl
587 <<
" INCL (default)" << std::endl
588 <<
" real" << std::endl
589 <<
" real-light" << std::endl;
590 std::cerr << suggestHelpMsg;
594 config.separationEnergyType = G4INCL::INCLSeparationEnergy;
598 if(variablesMap.count(
"fermi-momentum")) {
599 std::string fermiMomentumNorm = config.fermiMomentumString;
600 std::transform(fermiMomentumNorm.begin(),
601 fermiMomentumNorm.end(),
602 fermiMomentumNorm.begin(), ::tolower);
603 if(fermiMomentumNorm==
"constant")
604 config.fermiMomentumType = G4INCL::ConstantFermiMomentum;
605 else if(fermiMomentumNorm==
"constant-light")
606 config.fermiMomentumType = G4INCL::ConstantLightFermiMomentum;
607 else if(fermiMomentumNorm==
"mass-dependent")
608 config.fermiMomentumType = G4INCL::MassDependentFermiMomentum;
613 config.fermiMomentum = strtod(fermiMomentumNorm.c_str(), &tail);
614 if(errno || *tail!=
'\0') {
615 std::cerr <<
"Unrecognized fermi-momentum option. "
616 <<
"Must be one of:" << std::endl
617 <<
" constant (default)" << std::endl
618 <<
" constant-light" << std::endl
619 <<
" mass-dependent" << std::endl
620 <<
" [a postiive value]" << std::endl;
621 std::cerr << suggestHelpMsg;
624 if(config.fermiMomentum<=0.) {
625 std::cerr <<
"Values passed to fermi-momentum must be positive." << std::endl;
626 std::cerr << suggestHelpMsg;
629 config.fermiMomentumType = G4INCL::ConstantFermiMomentum;
632 config.fermiMomentumType = G4INCL::ConstantFermiMomentum;
636 if(variablesMap.count(
"rp-correlation")) {
637 if(!variablesMap.count(
"rp-correlation-p") || variablesMap.find(
"rp-correlation-p")->second.defaulted())
638 config.rpCorrelationCoefficientProton = config.rpCorrelationCoefficient;
639 if(!variablesMap.count(
"rp-correlation-n") || variablesMap.find(
"rp-correlation-n")->second.defaulted())
640 config.rpCorrelationCoefficientNeutron = config.rpCorrelationCoefficient;
644 if(variablesMap.count(
"cross-sections")) {
645 std::string crossSectionsNorm = config.crossSectionsString;
646 std::transform(crossSectionsNorm.begin(), crossSectionsNorm.end(), crossSectionsNorm.begin(), ::tolower);
647 if(crossSectionsNorm==
"incl46")
648 config.crossSectionsType = G4INCL::INCL46CrossSections;
649 else if(crossSectionsNorm==
"multipions")
650 config.crossSectionsType = G4INCL::MultiPionsCrossSections;
651 else if(crossSectionsNorm==
"truncated-multipions")
652 config.crossSectionsType = G4INCL::TruncatedMultiPionsCrossSections;
654 std::cerr <<
"Unrecognized cross section parametrization. Must be one of:" << std::endl
655 <<
" multipions (default)" << std::endl
656 <<
" truncated-multipions" << std::endl
657 <<
" incl46" << std::endl;
658 std::cerr << suggestHelpMsg;
664 if(!variablesMap[
"max-number-multipions"].defaulted() && !variablesMap[
"cross-sections"].defaulted()) {
665 if(config.crossSectionsType!=G4INCL::TruncatedMultiPionsCrossSections) {
667 config.crossSectionsString =
"truncated-multipions";
668 config.crossSectionsType = G4INCL::TruncatedMultiPionsCrossSections;
673 if(variablesMap.count(
"phase-space-generator")) {
674 std::string phaseSpaceGeneratorNorm = config.phaseSpaceGenerator;
675 std::transform(phaseSpaceGeneratorNorm.begin(),
676 phaseSpaceGeneratorNorm.end(),
677 phaseSpaceGeneratorNorm.begin(), ::tolower);
678 if(phaseSpaceGeneratorNorm==
"raubold-lynch")
679 config.phaseSpaceGeneratorType = G4INCL::RauboldLynchType;
680 else if(phaseSpaceGeneratorNorm==
"kopylov")
681 config.phaseSpaceGeneratorType = G4INCL::KopylovType;
683 std::cerr <<
"Unrecognized phase-space-generator option. "
684 <<
"Must be one of:" << std::endl
685 <<
" Raubold-Lynch (default)" << std::endl
686 <<
" Kopylov" << std::endl;
687 std::cerr << suggestHelpMsg;
691 config.phaseSpaceGeneratorType = G4INCL::RauboldLynchType;
695 if(variablesMap.count(
"cascade-action")) {
696 std::string cascadeActionNorm = config.cascadeAction;
697 std::transform(cascadeActionNorm.begin(),
698 cascadeActionNorm.end(),
699 cascadeActionNorm.begin(), ::tolower);
700 if(cascadeActionNorm==
"default")
701 config.cascadeActionType = G4INCL::DefaultActionType;
702 else if(cascadeActionNorm==
"avatar-dump")
703 config.cascadeActionType = G4INCL::AvatarDumpActionType;
705 std::cerr <<
"Unrecognized cascade-action option. "
706 <<
"Must be one of:" << std::endl
707 <<
" default (default)" << std::endl
708 <<
" avatar-dump" << std::endl;
709 std::cerr << suggestHelpMsg;
713 config.cascadeActionType = G4INCL::DefaultActionType;
717 if(!variablesMap.count(
"suffix")) {
719 variablesMap.insert(std::make_pair(
"suffix", po::variable_value(boost::any(config.fileSuffix),
false)));
723 if(variablesMap.count(
"inclxx-datafile-path"))
724 config.INCLXXDataFilePath = G4INCL::String::expandPath(config.INCLXXDataFilePath);
725 #ifdef INCL_DEEXCITATION_ABLAXX
726 if(variablesMap.count(
"ablav3p-cxx-datafile-path"))
727 config.ablav3pCxxDataFilePath = G4INCL::String::expandPath(config.ablav3pCxxDataFilePath);
729 #ifdef INCL_DEEXCITATION_ABLA07
730 if(variablesMap.count(
"abla07-datafile-path"))
731 config.abla07DataFilePath = G4INCL::String::expandPath(config.abla07DataFilePath);
733 #ifdef INCL_DEEXCITATION_GEMINIXX
734 if(variablesMap.count(
"geminixx-datafile-path"))
735 config.geminixxDataFilePath = G4INCL::String::expandPath(config.geminixxDataFilePath);
739 if(variablesMap.count(
"output")) {
740 config.outputFileRoot = G4INCL::String::expandPath(config.outputFileRoot);
743 std::stringstream outputFileRootStream;
745 if(variablesMap.count(
"input-file"))
746 outputFileRootStream << config.inputFileName << config.fileSuffix;
748 outputFileRootStream.precision(0);
749 outputFileRootStream.setf(std::ios::fixed, std::ios::floatfield);
750 outputFileRootStream <<
751 G4INCL::ParticleTable::getShortName(config.projectileSpecies) <<
"_" <<
752 G4INCL::ParticleTable::getShortName(config.targetSpecies) <<
"_" <<
753 config.projectileKineticEnergy;
754 outputFileRootStream.precision(2);
757 typedef po::variables_map::const_iterator BPOVMIter;
758 for(BPOVMIter i=variablesMap.begin(),
e=variablesMap.end(); i!=
e; ++i) {
759 std::string
const &name = i->first;
761 if(name!=
"projectile"
764 && name!=
"number-shots"
765 && name!=
"random-seeds"
766 && name!=
"random-number-generator"
768 && name!=
"verbose-event"
771 && name!=
"root-selection"
772 && name!=
"concise-root-tree"
774 && name!=
"inverse-kinematics"
775 && name!=
"inclxx-datafile-path"
776 #ifdef INCL_DEEXCITATION_ABLA07
777 && name!=
"abla07-datafile-path"
779 #ifdef INCL_DEEXCITATION_ABLAXX
780 && name!=
"ablav3p-cxx-datafile-path"
782 #ifdef INCL_DEEXCITATION_GEMINIXX
783 && name!=
"geminixx-datafile-path"
786 po::variable_value v = i->second;
788 const std::type_info &type = v.value().type();
789 if(type==
typeid(std::string))
790 outputFileRootStream <<
"_" << name <<
"=" << v.as<std::string>();
791 else if(type==
typeid(
float))
792 outputFileRootStream <<
"_" << name <<
"=" << v.as<
float>();
793 else if(type==
typeid(
double))
794 outputFileRootStream <<
"_" << name <<
"=" << v.as<
double>();
795 else if(type==
typeid(
int))
796 outputFileRootStream <<
"_" << name <<
"=" << v.as<
int>();
797 else if(type==
typeid(
bool))
798 outputFileRootStream <<
"_" << name <<
"=" << v.as<
bool>();
803 outputFileRootStream << config.fileSuffix;
807 config.outputFileRoot = outputFileRootStream.str();
809 variablesMap.insert(std::make_pair(
"output", po::variable_value(boost::any(config.outputFileRoot),
false)));
813 if(!variablesMap.count(
"logfile")) {
815 config.logFileName = config.outputFileRoot +
".log";
817 variablesMap.insert(std::make_pair(
"logfile", po::variable_value(boost::any(config.logFileName),
false)));
820 config.logFileName = G4INCL::String::expandPath(config.logFileName);
824 if(variablesMap.count(
"random-number-generator")) {
825 std::string randomNumberGeneratorNorm = config.randomNumberGenerator;
826 std::transform(randomNumberGeneratorNorm.begin(),
827 randomNumberGeneratorNorm.end(),
828 randomNumberGeneratorNorm.begin(), ::tolower);
829 if(randomNumberGeneratorNorm==
"ranecu")
830 config.rngType = G4INCL::RanecuType;
831 else if(randomNumberGeneratorNorm==
"ranecu3")
832 config.rngType = G4INCL::Ranecu3Type;
834 std::cerr <<
"Unrecognized random-number-generator option. "
835 <<
"Must be one of:" << std::endl
836 <<
" Ranecu (2 seeds, default)" << std::endl
837 <<
" Ranecu3 (3 seeds)" << std::endl;
838 std::cerr << suggestHelpMsg;
842 config.rngType = G4INCL::RanecuType;
846 if(variablesMap.count(
"random-seeds")) {
847 config.randomSeedVector.clear();
849 std::vector<std::string> tokens = G4INCL::String::tokenize(config.randomSeeds,
", \t");
850 for(std::vector<std::string>::const_iterator i=tokens.begin(),
e=tokens.end(); i!=
e; ++i) {
851 if(!G4INCL::String::isInteger(*i)) {
852 std::cerr <<
"Invalid random seed, must be an integer. Parsed token: "
854 std::cerr << suggestHelpMsg;
858 std::stringstream ss(*i);
862 if(seed<randomSeedMin || seed>randomSeedMax) {
863 std::cerr <<
"Invalid value for random-seed-1. "
864 <<
"Allowed range: [" << randomSeedMin <<
", " << randomSeedMax <<
"]." << std::endl;
865 std::cerr << suggestHelpMsg;
869 config.randomSeedVector.push_back(seed);
874 catch(std::exception&
e)
876 std::cerr << e.what() <<
"\n";
877 std::cerr << suggestHelpMsg;
882 G4INCL::Config *aConfig =
new G4INCL::Config(config);
886 std::string ConfigParser::echo(G4INCL::Config
const *
const aConfig) {
888 std::stringstream ss;
889 ss <<
"###########################\n"
890 <<
"### Start of input echo ###\n"
891 <<
"###########################\n\n"
892 <<
"# You may re-use this snippet of the log file as an input file!\n"
893 <<
"# Options marked with a * are compulsory.\n"
894 <<
"\n### Run options\n" << echoOptionsDescription(runOptDesc)
895 <<
"\n### Physics options\n" << echoOptionsDescription(physicsOptDesc)
896 <<
"\n# the projectile nuclide was parsed as Z=" << config.projectileSpecies.theZ
897 <<
", A=" << config.projectileSpecies.theA
898 <<
"\n# the target nuclide was parsed as Z=" << config.targetSpecies.theZ;
899 if(config.targetSpecies.theA>0)
900 ss <<
", A=" << config.targetSpecies.theA;
902 ss <<
", natural target";
903 ss <<
"\n\n#########################\n"
904 <<
"### End of input echo ###\n"
905 <<
"#########################" << std::endl;
910 std::string ConfigParser::echoOptionsDescription(
const po::options_description &aDesc) {
911 typedef std::vector< boost::shared_ptr< po::option_description > > OptVector;
912 typedef std::vector< boost::shared_ptr< po::option_description > >::const_iterator OptIter;
914 std::stringstream ss;
915 ss << std::boolalpha;
916 OptVector
const &anOptVect = aDesc.options();
917 for(OptIter opt=anOptVect.begin(), e=anOptVect.end(); opt!=
e; ++opt) {
918 std::string optDescription = (*opt)->description();
919 G4INCL::String::wrap(optDescription);
920 G4INCL::String::replaceAll(optDescription,
"\n",
"\n# ");
921 ss <<
"\n# " << optDescription <<
'\n';
922 const std::string &name = (*opt)->long_name();
924 po::variable_value
const &value = variablesMap.find(name)->second;
925 std::type_info
const &type = value.value().type();
926 if(type ==
typeid(std::string)) {
927 const std::string
s = value.as<std::string>();
932 }
else if(type ==
typeid(
int))
933 ss << value.as<
int>();
934 else if(type ==
typeid(
unsigned int))
935 ss << value.as<
unsigned int>();
936 else if(type ==
typeid(
float))
937 ss << value.as<
float>();
938 else if(type ==
typeid(
double))
939 ss << value.as<
double>();
940 else if(type ==
typeid(
bool))
941 ss << value.as<
bool>();
948 #endif // __GENIE_INCL_ENABLED__
static constexpr double s