Geant4  10.00.p03
G4INCLConfig.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 #include "G4INCLParticleType.hh"
38 #include "G4INCLConfig.hh"
39 #include "G4INCLParticleSpecies.hh"
40 #include "G4INCLParticleTable.hh"
41 #include "G4INCLGlobals.hh"
42 #include <cerrno>
43 #include <cstdlib>
44 
45 namespace G4INCL {
46 
47  const G4int Config::randomSeedMin = 1;
48  const G4int Config::randomSeedMax = ((1<<30)-1)+(1<<30); // 2^31-1
49 
51  {
52  init();
53  }
54 
55  Config::Config(G4int /*A*/, G4int /*Z*/, G4INCL::ParticleSpecies proj, G4double projectileE)
56  {
57  init();
58  projectileSpecies = proj;
59  projectileKineticEnergy = projectileE;
60  }
61 
62  // NOT used in Geant4 mode
63 #if defined(HAS_BOOST_PROGRAM_OPTIONS) && !defined(INCLXX_IN_GEANT4_MODE)
64  Config::Config(G4int argc, char *argv[], G4bool isFullRun) :
65  runOptDesc("Run options"),
66  hiddenOptDesc("Hidden options"),
67  genericOptDesc("Generic options"),
68  physicsOptDesc("Physics options"),
69  naturalTarget(false)
70  {
71  init();
72 
73  const std::string suggestHelpMsg("You might want to run `INCLCascade --help' to get a help message.\n");
74 
75  // Define the names of the de-excitation models
76  const std::string theNoneName = "none";
77 #ifdef INCL_DEEXCITATION_SMM
78  const std::string theSMMName = "SMM";
79 #endif
80 #ifdef INCL_DEEXCITATION_GEMINIXX
81  const std::string theGEMINIXXName = "GEMINIXX";
82 #endif
83 #ifdef INCL_DEEXCITATION_ABLAXX
84  const std::string theABLAv3pName = "ABLAv3p";
85 #endif
86 #ifdef INCL_DEEXCITATION_ABLA07
87  const std::string theABLA07Name = "ABLA07";
88 #endif
89 
90  // Define the default de-excitation model, in decreasing order of priority
91  std::string defaultDeExcitationModel = theNoneName;
92 #ifdef INCL_DEEXCITATION_SMM
93  defaultDeExcitationModel = theSMMName;
94 #endif
95 #ifdef INCL_DEEXCITATION_GEMINIXX
96  defaultDeExcitationModel = theGEMINIXXName;
97 #endif
98 #ifdef INCL_DEEXCITATION_ABLAXX
99  defaultDeExcitationModel = theABLAv3pName;
100 #endif
101 #ifdef INCL_DEEXCITATION_ABLA07
102  defaultDeExcitationModel = theABLA07Name;
103 #endif
104 
105  const std::string listSeparator = "\n \t";
107  listSeparator + theNoneName
108 #ifdef INCL_DEEXCITATION_ABLA07
109  + listSeparator + theABLA07Name
110 #endif
111 #ifdef INCL_DEEXCITATION_ABLAXX
112  + listSeparator + theABLAv3pName
113 #endif
114 #ifdef INCL_DEEXCITATION_GEMINIXX
115  + listSeparator + theGEMINIXXName
116 #endif
117 #ifdef INCL_DEEXCITATION_SMM
118  + listSeparator + theSMMName
119 #endif
120  ;
121 
122  // Append " (default)" to the name of the default model
123  size_t defaultModelIndex = deExcitationModelList.find(defaultDeExcitationModel);
124  if(defaultModelIndex!=std::string::npos) {
125  deExcitationModelList = deExcitationModelList.substr(0, defaultModelIndex+defaultDeExcitationModel.size())
126  + " (default)"
127  + deExcitationModelList.substr(defaultModelIndex+defaultDeExcitationModel.size(), std::string::npos);
128  }
129 
130  // Spell out the G4bool values
131  std::cout << std::boolalpha;
132 
133  try {
134 
135  // Hidden options
136  hiddenOptDesc.add_options()
137  ("input-file", po::value<std::string>(&inputFileName), "input file")
138  ("impact-parameter", po::value<G4double>(&impactParameter)->default_value(-1.), "impact parameter")
139  ;
140 
141  // Generic options
142  std::stringstream verbosityDescription;
143  verbosityDescription << "set verbosity level:\n"
144  << " 0: \tquiet, suppress all output messages\n"
145  << " " << InfoMsg << ": \tminimal logging\n"
146  << " " << FatalMsg << ": \tlog fatal error messages as well\n"
147  << " " << ErrorMsg << ": \tlog error messages as well\n"
148  << " " << WarningMsg << ": \tlog warning messages as well\n"
149  << " " << DebugMsg << ": \tlog debug messages as well\n"
150  << " " << DataBlockMsg << ": \tlog data-block messages as well";
151 
152  genericOptDesc.add_options()
153  ("help,h", "produce this help message")
154  ("version", "print version string and exit")
155  ;
156 
157  // Run-specific options
158  std::stringstream randomSeed1Description, randomSeed2Description;
159  randomSeed1Description << "first seed for the random-number generator (between "
160  << randomSeedMin << "and " << randomSeedMax << ")";
161  randomSeed2Description << "second seed for the random-number generator (between "
162  << randomSeedMin << "and " << randomSeedMax << ")";
163 
164  runOptDesc.add_options()
165  ("title", po::value<std::string>(&title)->default_value("INCL default run title"), "run title")
166  ("output,o", po::value<std::string>(&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")
167  ("suffix,s", po::value<std::string>(&fileSuffix), "suffix to be appended to generated output file names")
168  ("logfile,l", po::value<std::string>(&logFileName), "log file name. Defaults to `<output_root>.log'. Use `-' if you want to redirect logging to stdout")
169  ("number-shots,N", po::value<G4int>(&nShots), "* number of shots")
170  ("target,t", po::value<std::string>(&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.")
171  ("projectile,p", po::value<std::string>(&projectileString), "* projectile name:\n"
172  " \tproton, p\n"
173  " \tneutron, n\n"
174  " \tpi+, piplus, pion+, pionplus\n"
175  " \tpi0, pizero, pion0, pionzero\n"
176  " \tpi-, piminus, pion-, pionminus\n"
177  " \td, t, a, deuteron, triton, alpha\n"
178  " \tHe-4, He4, 4He (and so on)")
179  ("energy,E", po::value<G4double>(&projectileKineticEnergy), "* total kinetic energy of the projectile, in MeV")
180  ("verbose-event", po::value<G4int>(&verboseEvent)->default_value(-1), "request verbose logging for the specified event only")
181  ("random-seed-1", po::value<G4int>(&randomSeed1)->default_value(666), randomSeed1Description.str().c_str())
182  ("random-seed-2", po::value<G4int>(&randomSeed2)->default_value(777), randomSeed2Description.str().c_str())
183 #ifdef INCL_ROOT_USE
184  ("root-selection", po::value<std::string>(&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.")
185 #endif
186  ("inclxx-datafile-path", po::value<std::string>(&INCLXXDataFilePath)->default_value("../data/"),
187  "path to the INCL++ data files")
188 #ifdef INCL_DEEXCITATION_ABLA07
189  ("abla07-datafile-path", po::value<std::string>(&abla07DataFilePath)->default_value("../de-excitation/abla07/upstream/tables/"),
190  "path to the ABLA07 data files")
191 #endif
192 #ifdef INCL_DEEXCITATION_ABLAXX
193  ("ablav3p-cxx-datafile-path", po::value<std::string>(&ablav3pCxxDataFilePath)->default_value("../de-excitation/ablaxx/data/G4ABLA3.0/"),
194  "path to the ABLAv3p data files")
195 #endif
196 #ifdef INCL_DEEXCITATION_GEMINIXX
197  ("geminixx-datafile-path", po::value<std::string>(&geminixxDataFilePath)->default_value("../de-excitation/geminixx/upstream/"),
198  "path to the GEMINI++ data files")
199 #endif
200  ("verbosity,v", po::value<G4int>(&verbosity)->default_value(4), verbosityDescription.str().c_str())
201  ;
202 
203  // Physics options
204  physicsOptDesc.add_options()
205  ("de-excitation,d", po::value<std::string>(&deExcitationString)->default_value(defaultDeExcitationModel.c_str()), ("which de-excitation model to use:" + deExcitationModelList).c_str())
206 #ifdef INCL_DEEXCITATION_FERMI_BREAKUP
207  ("max-mass-fermi-breakup", po::value<G4int>(&maxMassFermiBreakUp)->default_value(18), "Maximum remnant mass for Fermi break-up. Default: 18.")
208 #endif
209  ("pauli", po::value<std::string>(&pauliString)->default_value("strict-statistical"), "Pauli-blocking algorithm:\n"
210  " \tstrict-statistical (default)\n"
211  " \tstrict\n"
212  " \tstatistical\n"
213  " \tglobal\n"
214  " \tnone")
215  ("cdpp", po::value<G4bool>(&CDPP)->default_value(true), "whether to apply CDPP after collisions:\n \ttrue, 1 (default)\n \tfalse, 0")
216  ("coulomb", po::value<std::string>(&coulombString)->default_value("non-relativistic"), "Coulomb-distortion algorithm:\n \tnon-relativistic (default)\n \tnone")
217  ("potential", po::value<std::string>(&potentialString)->default_value("isospin-energy"), "nucleon potential:\n \tisospin-energy-smooth\n \tisospin-energy (default)\n \tisospin\n \tconstant")
218  ("pion-potential", po::value<G4bool>(&pionPotential)->default_value("true"), "whether to use a pion potential:\n \ttrue, 1 (default)\n \tfalse, 0")
219  ("local-energy-BB", po::value<std::string>(&localEnergyBBString)->default_value("first-collision"), "local energy in baryon-baryon collisions:\n \talways\n \tfirst-collision (default)\n \tnever")
220  ("local-energy-pi", po::value<std::string>(&localEnergyPiString)->default_value("first-collision"), "local energy in pi-N collisions and in delta decays:\n \talways\n \tfirst-collision (default)\n \tnever")
221  ("cluster-algorithm", po::value<std::string>(&clusterAlgorithmString)->default_value("intercomparison"), "clustering algorithm for production of composites:\n \tintercomparison (default)\n \tnone")
222  ("cluster-max-mass", po::value<G4int>(&clusterMaxMass)->default_value(8), "maximum mass of produced composites:\n \tminimum 2\n \tmaximum 12")
223  ("back-to-spectator", po::value<G4bool>(&backToSpectator)->default_value("true"), "whether to use back-to-spectator:\n \ttrue, 1 (default)\n \tfalse, 0")
224  ("use-real-masses", po::value<G4bool>(&useRealMasses)->default_value("true"), "whether to use real masses for the outgoing particle energies:\n \ttrue, 1 (default)\n \tfalse, 0")
225  ("separation-energies", po::value<std::string>(&separationEnergyString)->default_value("INCL"), "how to assign the separation energies of the INCL nucleus:\n \tINCL (default)\n \treal\n \treal-light")
226  ("fermi-momentum", po::value<std::string>(&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]")
227  ("cutNN", po::value<G4double>(&cutNN)->default_value(1910.), "minimum CM energy for nucleon-nucleon collisions, in MeV. Default: 1910.")
228  ("rp-correlation", po::value<G4double>(&rpCorrelationCoefficient)->default_value(1.), "correlation coefficient for the r-p correlation. Default: 1 (full correlation).")
229  ("rp-correlation-p", po::value<G4double>(&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).")
230  ("rp-correlation-n", po::value<G4double>(&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).")
231  ("neutron-skin-thickness", po::value<G4double>(&neutronSkinThickness)->default_value(0.), "thickness of the neutron skin, in fm. Default: 0.")
232  ("neutron-skin-additional-diffuseness", po::value<G4double>(&neutronSkinAdditionalDiffuseness)->default_value(0.), "additional diffuseness of the neutron density distribution (with respect to the proton diffuseness), in fm. Default: 0.")
233  ("refraction", po::value<G4bool>(&refraction)->default_value(false), "whether to use refraction when particles are transmitted. Default: false.")
234  ;
235 
236  // Select options allowed on the command line
237  po::options_description cmdLineOptions;
238  cmdLineOptions.add(hiddenOptDesc).add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
239 
240  // Select options allowed in config files
241  po::options_description configFileOptions;
242  configFileOptions.add(runOptDesc).add(physicsOptDesc);
243 
244  // Select visible options
245  po::options_description visibleOptions;
246  visibleOptions.add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
247 
248  // Declare input-file as a positional option (if we just provide a file
249  // name on the command line, it should be interpreted as an input-file
250  // option).
251  po::positional_options_description p;
252  p.add("input-file", 1);
253 
254  // Disable guessing of option names
255  G4int cmdstyle =
256  po::command_line_style::default_style &
257  ~po::command_line_style::allow_guessing;
258 
259  // Result of the option processing
260  po::store(po::command_line_parser(argc, argv).
261  style(cmdstyle).
262  options(cmdLineOptions).positional(p).run(), variablesMap);
263  po::notify(variablesMap);
264 
265  // If an input file was specified, merge the options with the command-line
266  // options.
267  if(variablesMap.count("input-file")) {
268  std::ifstream inputFileStream(inputFileName.c_str());
269  if(!inputFileStream) {
270  std::cerr << "Cannot open input file: " << inputFileName << std::endl;
271  std::exit(EXIT_FAILURE);
272  } else {
273  // Merge options from the input file
274  po::parsed_options parsedOptions = po::parse_config_file(inputFileStream, configFileOptions, true);
275 
276  // Make sure that the unhandled options are all "*-datafile-path"
277  std::vector<std::string> unhandledOptions =
278  po::collect_unrecognized(parsedOptions.options, po::exclude_positional);
279  G4bool ignoreNext = false;
280  const std::string match = "-datafile-path";
281  for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(), e=unhandledOptions.end(); i!=e; ++i) {
282  if(ignoreNext) {
283  ignoreNext=false;
284  continue;
285  }
286  if(i->rfind(match) == i->length()-match.length()) {
287  std::cout << "Ignoring unrecognized option " << *i << std::endl;
288  ignoreNext = true;
289  } else {
290  std::cerr << "Error: unrecognized option " << *i << std::endl;
291  std::cerr << suggestHelpMsg;
292  std::exit(EXIT_FAILURE);
293  }
294  }
295 
296  // Store the option values in the variablesMap
297  po::store(parsedOptions, variablesMap);
298  po::notify(variablesMap);
299  }
300  inputFileStream.close();
301  }
302 
303  // Process the options from the user-specific config file ~/.inclxxrc
304  std::string configFileName;
305  const char * const configFileVar = getenv("INCLXXRC");
306  if(configFileVar)
307  configFileName = configFileVar;
308  else {
309  const char * const homeDirectoryPointer = getenv("HOME");
310  if(homeDirectoryPointer) { // Check if we can find the home directory
311  std::string homeDirectory(homeDirectoryPointer);
312  configFileName = homeDirectory + "/.inclxxrc";
313  } else {
314  std::cerr << "Could not determine the user's home directory. "
315  << "Are you running Linux, Unix or BSD?"<< std::endl;
316  std::exit(EXIT_FAILURE);
317  }
318  }
319 
320  std::ifstream configFileStream(configFileName.c_str());
321  std::cout << "Reading config file " << configFileName << std::endl;
322  if(!configFileStream) {
323  std::cout << "INCL++ config file " << configFileName
324  << " not found. Continuing the run regardless."
325  << std::endl;
326  } else {
327  // Merge options from the input file
328  po::parsed_options parsedOptions = po::parse_config_file(configFileStream, configFileOptions, true);
329  po::store(parsedOptions, variablesMap);
330 
331  // Make sure that the unhandled options are all "*-datafile-path"
332  std::vector<std::string> unhandledOptions =
333  po::collect_unrecognized(parsedOptions.options, po::exclude_positional);
334  G4bool ignoreNext = false;
335  const std::string match = "-datafile-path";
336  for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(), e=unhandledOptions.end(); i!=e; ++i) {
337  if(ignoreNext) {
338  ignoreNext=false;
339  continue;
340  }
341  if(i->rfind(match) == i->length()-match.length()) {
342  std::cout << "Ignoring unrecognized option " << *i << std::endl;
343  ignoreNext = true;
344  } else {
345  std::cerr << "Error: unrecognized option " << *i << std::endl;
346  std::cerr << suggestHelpMsg;
347  std::exit(EXIT_FAILURE);
348  }
349  }
350 
351  // Store the option values in the variablesMap
352  po::store(parsedOptions, variablesMap);
353  po::notify(variablesMap);
354  }
355  configFileStream.close();
356 
357  /* *******************
358  * Process the options
359  * *******************/
360 
361  // -h/--help: print the help message and exit successfully
362  if(variablesMap.count("help")) {
363  std::cout
364  << "Usage: INCLCascade [options] <input_file>" << std::endl
365  << 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
366  << visibleOptions << std::endl;
367  std::exit(EXIT_SUCCESS);
368  }
369 
370  // --version: print the version string and exit successfully
371  if(variablesMap.count("version")) {
372  std::cout <<"INCL++ version " << getVersionString() << std::endl;
373  std::exit(EXIT_SUCCESS);
374  }
375 
376  // Check if the required options are present
377  if(isFullRun) {
378  std::string missingOption("");
379  if(!variablesMap.count("number-shots"))
380  missingOption = "number-shots";
381  else if(!variablesMap.count("target"))
382  missingOption = "target";
383  else if(!variablesMap.count("projectile"))
384  missingOption = "projectile";
385  else if(!variablesMap.count("energy"))
386  missingOption = "energy";
387  if(!missingOption.empty()) {
388  std::cerr << "Required option " << missingOption << " is missing." << std::endl;
389  std::cerr << suggestHelpMsg;
390  std::exit(EXIT_FAILURE);
391  }
392  } else {
393  std::cout <<"Not performing a full run. This had better be a test..." << std::endl;
394  }
395 
396  // -p/--projectile: projectile species
397  projectileSpecies = ParticleSpecies(projectileString);
399  std::cerr << "Error: unrecognized particle type " << projectileString << std::endl;
400  std::cerr << suggestHelpMsg;
401  std::exit(EXIT_FAILURE);
402  }
403 
404  // -t/--target: target species
405  if(variablesMap.count("target")) {
406  targetSpecies = ParticleSpecies(targetString);
408  std::cerr << "Unrecognized target. You specified: " << targetString << std::endl
409  << " The target nuclide must be specified in one of the following forms:" << std::endl
410  << " Fe56, 56Fe, Fe-56, 56-Fe, Fe_56, 56_Fe, Fe" << std::endl
411  << " You can also use IUPAC element names (such as Uuh)." << std::endl;
412  std::cerr << suggestHelpMsg;
413  std::exit(EXIT_FAILURE);
414  }
415  if(targetSpecies.theA==0)
416  naturalTarget = true;
417  }
418 
419  // --pauli
420  if(variablesMap.count("pauli")) {
421  std::string pauliNorm = pauliString;
422  std::transform(pauliNorm.begin(), pauliNorm.end(), pauliNorm.begin(), ::tolower);
423  if(pauliNorm=="statistical")
425  else if(pauliNorm=="strict")
427  else if(pauliNorm=="strict-statistical")
429  else if(pauliNorm=="global")
431  else if(pauliNorm=="none")
432  pauliType = NoPauli;
433  else {
434  std::cerr << "Unrecognized Pauli-blocking algorithm. Must be one of:" << std::endl
435  << " strict-statistical (default)" << std::endl
436  << " strict" << std::endl
437  << " statistical" << std::endl
438  << " global" << std::endl
439  << " none" << std::endl;
440  std::cerr << suggestHelpMsg;
441  std::exit(EXIT_FAILURE);
442  }
443  }
444 
445  // --coulomb
446  if(variablesMap.count("coulomb")) {
447  std::string coulombNorm = coulombString;
448  std::transform(coulombNorm.begin(), coulombNorm.end(), coulombNorm.begin(), ::tolower);
449  if(coulombNorm=="non-relativistic")
451  else if(coulombNorm=="none")
453  else {
454  std::cerr << "Unrecognized Coulomb-distortion algorithm. Must be one of:" << std::endl
455  << " non-relativistic (default)" << std::endl
456  << " none" << std::endl;
457  std::cerr << suggestHelpMsg;
458  std::exit(EXIT_FAILURE);
459  }
460  }
461 
462  // --potential
463  if(variablesMap.count("potential")) {
464  std::string potentialNorm = potentialString;
465  std::transform(potentialNorm.begin(), potentialNorm.end(), potentialNorm.begin(), ::tolower);
466  if(potentialNorm=="isospin-energy-smooth") {
468  } else if(potentialNorm=="isospin-energy") {
470  } else if(potentialNorm=="isospin")
472  else if(potentialNorm=="constant")
474  else {
475  std::cerr << "Unrecognized potential type. Must be one of:" << std::endl
476  << " isospin-energy-smooth" << std::endl
477  << " isospin-energy (default)" << std::endl
478  << " isospin" << std::endl
479  << " constant" << std::endl;
480  std::cerr << suggestHelpMsg;
481  std::exit(EXIT_FAILURE);
482  }
483  }
484 
485  // --local-energy-BB
486  if(variablesMap.count("local-energy-BB")) {
487  std::string localEnergyBBNorm = localEnergyBBString;
488  std::transform(localEnergyBBNorm.begin(), localEnergyBBNorm.end(), localEnergyBBNorm.begin(), ::tolower);
489  if(localEnergyBBNorm=="always") {
491  } else if(localEnergyBBNorm=="first-collision")
493  else if(localEnergyBBNorm=="never")
495  else {
496  std::cerr << "Unrecognized local-energy-BB type. Must be one of:" << std::endl
497  << " always" << std::endl
498  << " first-collision (default)" << std::endl
499  << " never" << std::endl;
500  std::cerr << suggestHelpMsg;
501  std::exit(EXIT_FAILURE);
502  }
503  }
504 
505  // --local-energy-pi
506  if(variablesMap.count("local-energy-pi")) {
507  std::string localEnergyPiNorm = localEnergyPiString;
508  std::transform(localEnergyPiNorm.begin(), localEnergyPiNorm.end(), localEnergyPiNorm.begin(), ::tolower);
509  if(localEnergyPiNorm=="always") {
511  } else if(localEnergyPiNorm=="first-collision")
513  else if(localEnergyPiNorm=="never")
515  else {
516  std::cerr << "Unrecognized local-energy-pi type. Must be one of:" << std::endl
517  << " always" << std::endl
518  << " first-collision" << std::endl
519  << " never (default)" << std::endl;
520  std::cerr << suggestHelpMsg;
521  std::exit(EXIT_FAILURE);
522  }
523  }
524 
525  // -d/--de-excitation
526  if(variablesMap.count("de-excitation")) {
527  std::string deExcitationNorm = deExcitationString;
528  std::transform(deExcitationNorm.begin(),
529  deExcitationNorm.end(),
530  deExcitationNorm.begin(), ::tolower);
531  if(deExcitationNorm=="none")
533 #ifdef INCL_DEEXCITATION_ABLAXX
534  else if(deExcitationNorm=="ablav3p")
535  deExcitationType = DeExcitationABLAv3p;
536 #endif
537 #ifdef INCL_DEEXCITATION_ABLA07
538  else if(deExcitationNorm=="abla07")
539  deExcitationType = DeExcitationABLA07;
540 #endif
541 #ifdef INCL_DEEXCITATION_SMM
542  else if(deExcitationNorm=="smm")
543  deExcitationType = DeExcitationSMM;
544 #endif
545 #ifdef INCL_DEEXCITATION_GEMINIXX
546  else if(deExcitationNorm=="geminixx")
547  deExcitationType = DeExcitationGEMINIXX;
548 #endif
549  else {
550  std::cerr << "Unrecognized de-excitation model. "
551  << "Must be one of:" << std::endl
552  << deExcitationModelList << std::endl;
553  std::cerr << suggestHelpMsg;
554  std::exit(EXIT_FAILURE);
555  }
556  } else {
558  }
559 
560  // --cluster-algorithm
561  if(variablesMap.count("cluster-algorithm")) {
562  std::string clusterAlgorithmNorm = clusterAlgorithmString;
563  std::transform(clusterAlgorithmNorm.begin(),
564  clusterAlgorithmNorm.end(),
565  clusterAlgorithmNorm.begin(), ::tolower);
566  if(clusterAlgorithmNorm=="none")
568  else if(clusterAlgorithmNorm=="intercomparison")
570  else {
571  std::cerr << "Unrecognized cluster algorithm. "
572  << "Must be one of:" << std::endl
573  << " intercomparison (default)" << std::endl
574  << " none" << std::endl;
575  std::cerr << suggestHelpMsg;
576  std::exit(EXIT_FAILURE);
577  }
578  } else {
580  }
581 
582  // --cluster-max-mass
583  if(variablesMap.count("cluster-max-mass") && clusterMaxMass < 2 && clusterMaxMass > 12) {
584  std::cerr << "Maximum cluster mass outside the allowed range. Must be between 2 and 12 (included)"
585  << std::endl
586  << suggestHelpMsg;
587  std::exit(EXIT_FAILURE);
588  }
589 
590  // --separation-energies
591  if(variablesMap.count("separation-energies")) {
592  std::string separationEnergyNorm = separationEnergyString;
593  std::transform(separationEnergyNorm.begin(),
594  separationEnergyNorm.end(),
595  separationEnergyNorm.begin(), ::tolower);
596  if(separationEnergyNorm=="incl")
598  else if(separationEnergyNorm=="real")
600  else if(separationEnergyNorm=="real-light")
602  else {
603  std::cerr << "Unrecognized separation-energies option. "
604  << "Must be one of:" << std::endl
605  << " INCL (default)" << std::endl
606  << " real" << std::endl
607  << " real-light" << std::endl;
608  std::cerr << suggestHelpMsg;
609  std::exit(EXIT_FAILURE);
610  }
611  } else {
613  }
614 
615  // --fermi-momentum
616  if(variablesMap.count("fermi-momentum")) {
617  std::string fermiMomentumNorm = fermiMomentumString;
618  std::transform(fermiMomentumNorm.begin(),
619  fermiMomentumNorm.end(),
620  fermiMomentumNorm.begin(), ::tolower);
621  if(fermiMomentumNorm=="constant")
623  else if(fermiMomentumNorm=="constant-light")
625  else if(fermiMomentumNorm=="mass-dependent")
627  else {
628  // Try to convert the option value to a G4float, and bomb out on failure
629  errno = 0;
630  char *tail;
631  fermiMomentum = strtod(fermiMomentumNorm.c_str(), &tail);
632  if(errno || *tail!='\0') {
633  std::cerr << "Unrecognized fermi-momentum option. "
634  << "Must be one of:" << std::endl
635  << " constant (default)" << std::endl
636  << " constant-light" << std::endl
637  << " mass-dependent" << std::endl
638  << " [a postiive value]" << std::endl;
639  std::cerr << suggestHelpMsg;
640  std::exit(EXIT_FAILURE);
641  }
642  if(fermiMomentum<=0.) {
643  std::cerr << "Values passed to fermi-momentum must be positive." << std::endl;
644  std::cerr << suggestHelpMsg;
645  std::exit(EXIT_FAILURE);
646  }
648  }
649  } else {
651  }
652 
653  // --rp-correlation / --rp-correlation-p / --rp-correlation-n
654  if(variablesMap.count("rp-correlation")) {
655  if(!variablesMap.count("rp-correlation-p") || variablesMap.find("rp-correlation-p")->second.defaulted())
657  if(!variablesMap.count("rp-correlation-n") || variablesMap.find("rp-correlation-n")->second.defaulted())
659  }
660 
661  // -s/--suffix
662  if(!variablesMap.count("suffix")) {
663  // update the value in the variables_map
664  variablesMap.insert(std::make_pair("suffix", po::variable_value(boost::any(fileSuffix), false)));
665  }
666 
667  // --output: construct a reasonable output file root if not specified
668  if(!variablesMap.count("output") && isFullRun) {
669  std::stringstream outputFileRootStream;
670  // If an input file was specified, use its name as the output file root
671  if(variablesMap.count("input-file"))
672  outputFileRootStream << inputFileName << fileSuffix;
673  else {
674  outputFileRootStream.precision(0);
675  outputFileRootStream.setf(std::ios::fixed, std::ios::floatfield);
676  outputFileRootStream <<
680  outputFileRootStream.precision(2);
681 
682  // Append suffixes to the output file root for each explicitly specified CLI option
683  typedef po::variables_map::const_iterator BPOVMIter;
684  for(BPOVMIter i=variablesMap.begin(), e=variablesMap.end(); i!=e; ++i) {
685  std::string const &name = i->first;
686  // Only process CLI options
687  if(name!="projectile"
688  && name!="target"
689  && name!="energy"
690  && name!="number-shots"
691  && name!="random-seed-1"
692  && name!="random-seed-2"
693  && name!="verbosity"
694  && name!="verbose-event"
695  && name!="suffix"
696 #ifdef INCL_ROOT_USE
697  && name!="root-selection"
698 #endif
699  && name!="inclxx-datafile-path"
700 #ifdef INCL_DEEXCITATION_ABLA07
701  && name!="abla07-datafile-path"
702 #endif
703 #ifdef INCL_DEEXCITATION_ABLAXX
704  && name!="ablav3p-cxx-datafile-path"
705 #endif
706 #ifdef INCL_DEEXCITATION_GEMINIXX
707  && name!="geminixx-datafile-path"
708 #endif
709  ) {
710  po::variable_value v = i->second;
711  if(!v.defaulted()) {
712  const std::type_info &type = v.value().type();
713  if(type==typeid(std::string))
714  outputFileRootStream << "_" << name << "=" << v.as<std::string>();
715  else if(type==typeid(G4float))
716  outputFileRootStream << "_" << name << "=" << v.as<G4float>();
717  else if(type==typeid(G4double))
718  outputFileRootStream << "_" << name << "=" << v.as<G4double>();
719  else if(type==typeid(G4int))
720  outputFileRootStream << "_" << name << "=" << v.as<G4int>();
721  else if(type==typeid(G4bool))
722  outputFileRootStream << "_" << name << "=" << v.as<G4bool>();
723  }
724  }
725  }
726 
727  outputFileRootStream << fileSuffix;
728  }
729 
730  // update the variable
731  outputFileRoot = outputFileRootStream.str();
732  // update the value in the variables_map
733  variablesMap.insert(std::make_pair("output", po::variable_value(boost::any(outputFileRoot), false)));
734  }
735 
736  // -l/--logfile
737  if(!variablesMap.count("logfile")) {
738  // update the variable
739  logFileName = outputFileRoot + ".log";
740  // update the value in the variables_map
741  variablesMap.insert(std::make_pair("logfile", po::variable_value(boost::any(logFileName), false)));
742  }
743 
744  // --random-seed-1 and 2
745  if(!variablesMap.count("random-seed-1")) {
746  if(randomSeed1<randomSeedMin || randomSeed1>randomSeedMax) {
747  std::cerr << "Invalid value for random-seed-1. "
748  << "Allowed range: [" << randomSeedMin << ", " << randomSeedMax << "]." << std::endl;
749  std::cerr << suggestHelpMsg;
750  std::exit(EXIT_FAILURE);
751  }
752  }
753  if(!variablesMap.count("random-seed-2")) {
754  if(randomSeed2<randomSeedMin || randomSeed2>randomSeedMax) {
755  std::cerr << "Invalid value for random-seed-2. "
756  << "Allowed range: [" << randomSeedMin << ", " << randomSeedMax << "]." << std::endl;
757  std::cerr << suggestHelpMsg;
758  std::exit(EXIT_FAILURE);
759  }
760  }
761 
762  }
763  catch(std::exception& e)
764  {
765  std::cerr << e.what() << "\n";
766  std::cerr << suggestHelpMsg;
767  std::exit(EXIT_FAILURE);
768  }
769 
770  }
771 #else
772  Config::Config(G4int /*argc*/, char * /*argv*/ [], G4bool /*isFullRun*/)
773  {
774  init();
775  }
776 #endif
777 
779  {}
780 
781  void Config::init() {
782  verbosity = 1;
783  inputFileName = "";
784  title = "INCL default run title";
785  nShots = 1000;
786  naturalTarget = false;
787  projectileString = "proton";
789  projectileKineticEnergy = 1000.0;
790  verboseEvent = -1;
791  randomSeed1 = 666;
792  randomSeed2 = 777;
793  pauliString = "strict-statistical";
795  CDPP = true;
796  coulombString = "non-relativistic";
798  potentialString = "isospin-energy";
800  pionPotential = true;
801  localEnergyBBString = "first-collision";
803  localEnergyPiString = "first-collision";
805  deExcitationString = "none";
807  clusterAlgorithmString = "intercomparison";
809  clusterMaxMass = 8;
810  backToSpectator = true;
811  useRealMasses = true;
812  impactParameter = -1.;
813  separationEnergyString = "INCL";
815  fermiMomentumString = "constant";
817  fermiMomentum = -1.;
818  cutNN = 1910.;
819 #ifdef INCL_DEEXCITATION_FERMI_BREAKUP
820  maxMassFermiBreakUp = 18;
821 #endif
827  refraction=false;
828  }
829 
830  std::string Config::summary() {
831  std::stringstream message;
832  message << "INCL++ version " << getVersionString() << std::endl;
834  message << "Projectile: " << ParticleTable::getName(projectileSpecies) << std::endl;
835  else
836  message << "Projectile: composite, A=" << projectileSpecies.theA << ", Z=" << projectileSpecies.theZ << std::endl;
837  message << " energy = " << projectileKineticEnergy << std::endl;
838  if(targetSpecies.theA>0)
839  message << "Target: A = " << targetSpecies.theA << " Z = " << targetSpecies.theZ << std::endl;
840  else
841  message << "Target: natural isotopic composition, Z = " << targetSpecies.theZ << std::endl;
842  message << "Number of requested shots = " << nShots << std::endl;
843  return message.str();
844  }
845 
846 #if defined(HAS_BOOST_PROGRAM_OPTIONS) && !defined(INCLXX_IN_GEANT4_MODE)
847  std::string const Config::echo() const {
848  std::stringstream ss;
849  ss << "###########################\n"
850  << "### Start of input echo ###\n"
851  << "###########################\n\n"
852  << "# You may re-use this snippet of the log file as an input file!\n"
853  << "# Options marked with a * are compulsory.\n"
854  << "\n### Run options\n" << echoOptionsDescription(runOptDesc)
855  << "\n### Physics options\n" << echoOptionsDescription(physicsOptDesc)
856  << "\n# the projectile nuclide was parsed as Z=" << projectileSpecies.theZ
857  << ", A=" << projectileSpecies.theA
858  << "\n# the target nuclide was parsed as Z=" << targetSpecies.theZ;
859  if(targetSpecies.theA>0)
860  ss << ", A=" << targetSpecies.theA;
861  else
862  ss << ", natural target";
863  ss << "\n\n#########################\n"
864  << "### End of input echo ###\n"
865  << "#########################" << std::endl;
866 
867  return ss.str();
868  }
869 
870  std::string Config::echoOptionsDescription(const po::options_description &aDesc) const {
871  typedef std::vector< boost::shared_ptr< po::option_description > > OptVector;
872  typedef std::vector< boost::shared_ptr< po::option_description > >::const_iterator OptIter;
873 
874  std::stringstream ss;
875  ss << std::boolalpha;
876  OptVector const &anOptVect = aDesc.options();
877  for(OptIter opt=anOptVect.begin(), e=anOptVect.end(); opt!=e; ++opt) {
878  std::string description = (*opt)->description();
879  String::wrap(description);
880  String::replaceAll(description, "\n", "\n# ");
881  ss << "\n# " << description << std::endl;
882  const std::string &name = (*opt)->long_name();
883  ss << name << " = ";
884  po::variable_value const &value = variablesMap.find(name)->second;
885  std::type_info const &type = value.value().type();
886  if(type == typeid(std::string)) {
887  const std::string svalue = value.as<std::string>();
888  if(svalue.empty())
889  ss << "\"\"";
890  else
891  ss << svalue;
892  } else if(type == typeid(G4int))
893  ss << value.as<G4int>();
894  else if(type == typeid(G4float))
895  ss << value.as<G4float>();
896  else if(type == typeid(G4double))
897  ss << value.as<G4double>();
898  else if(type == typeid(G4bool))
899  ss << value.as<G4bool>();
900  ss << '\n';
901  }
902  return ss.str();
903  }
904 #endif
905 
906 }
std::string fermiMomentumString
LocalEnergyType localEnergyPiType
PauliType pauliType
std::string separationEnergyString
std::string targetString
ClusterAlgorithmType clusterAlgorithmType
std::string potentialString
std::string localEnergyBBString
PotentialType potentialType
FermiMomentumType fermiMomentumType
std::string pauliString
G4int first(char) const
G4String name
Definition: TRTMaterials.hh:40
G4double fermiMomentum
float G4float
Definition: G4Types.hh:77
std::string localEnergyPiString
~Config()
Default destructor.
std::string clusterAlgorithmString
std::string outputFileRoot
G4bool backToSpectator
static const G4int randomSeedMin
int G4int
Definition: G4Types.hh:78
CoulombType coulombType
std::string coulombString
static std::string const getVersionString()
Get the INCL version string.
LocalEnergyType localEnergyBBType
G4double rpCorrelationCoefficientProton
std::string deExcitationModelList
bool G4bool
Definition: G4Types.hh:79
G4double neutronSkinAdditionalDiffuseness
G4double impactParameter
G4double rpCorrelationCoefficient
ParticleSpecies targetSpecies
G4bool useRealMasses
G4double neutronSkinThickness
G4double projectileKineticEnergy
Config()
Default constructor.
Definition: G4INCLConfig.cc:50
std::string deExcitationString
G4bool naturalTarget
std::string title
void init()
Initialise the members.
static const G4int randomSeedMax
void replaceAll(std::string &str, const std::string &from, const std::string &to, const size_t maxPosition=std::string::npos)
G4bool pionPotential
std::string fileSuffix
std::string summary()
Return a summary of the run configuration.
std::string projectileString
G4double rpCorrelationCoefficientNeutron
std::string INCLXXDataFilePath
std::string inputFileName
double G4double
Definition: G4Types.hh:76
DeExcitationType deExcitationType
SeparationEnergyType separationEnergyType
std::string getShortName(const ParticleType t)
Get the short INCL name of the particle.
std::string logFileName
std::string getName(const ParticleType t)
Get the native INCL name of the particle.
void wrap(std::string &str, const size_t lineLength=78, const std::string &separators=" \t")
ParticleSpecies projectileSpecies