Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
42 #ifdef HAS_BOOST_PROGRAM_OPTIONS
43 #include <boost/program_options/options_description.hpp>
44 #include <boost/program_options/parsers.hpp>
45 #include <boost/program_options/variables_map.hpp>
46 #include <iostream>
47 #include <fstream>
48 #include <sstream>
49 #include <cstdlib>
50 #include "G4INCLCascade.hh"
51 #include "G4INCLLogger.hh"
52 #endif
53 
54 namespace G4INCL {
55 
57  {
58  init();
59  }
60 
61  Config::Config(G4int /*A*/, G4int /*Z*/, G4INCL::ParticleSpecies proj, G4double projectileE)
62  {
63  init();
64  projectileSpecies = proj;
65  projectileKineticEnergy = projectileE;
66  }
67 
68  // NOT used in Geant4 mode
69 #ifdef HAS_BOOST_PROGRAM_OPTIONS
70  Config::Config(G4int argc, char *argv[], G4bool isFullRun) : naturalTarget(false) {
71  const std::string suggestHelpMsg("You might want to run `INCLCascade -h' to get a help message.\n");
72 
73  try {
74 
75  // Hidden options
76  boost::program_options::options_description hiddenOptDesc("Hidden options");
77  hiddenOptDesc.add_options()
78  ("input-file", boost::program_options::value<std::string>(&inputFileName), "input file")
79  ("impact-parameter", boost::program_options::value<G4double>(&impactParameter)->default_value(-1.), "impact parameter")
80  ;
81 
82  // Generic options
83  std::stringstream verbosityDescription;
84  verbosityDescription << "set verbosity level:\n"
85  << " 0: \tquiet, suppress all output messages\n"
86  << " " << InfoMsg << ": \tminimal logging\n"
87  << " " << FatalMsg << ": \tlog fatal error messages as well\n"
88  << " " << ErrorMsg << ": \tlog error messages as well\n"
89  << " " << WarningMsg << ": \tlog warning messages as well\n"
90  << " " << DebugMsg << ": \tlog debug messages as well\n"
91  << " " << DataBlockMsg << ": \tlog data-block messages as well";
92 
93  boost::program_options::options_description genericOptDesc("Generic options");
94  genericOptDesc.add_options()
95  ("help,h", "produce this help message")
96  ("version", "print version string and exit")
97  ;
98 
99  // Run-specific options
100  boost::program_options::options_description runOptDesc("Run options");
101  runOptDesc.add_options()
102  ("title", boost::program_options::value<std::string>(&title)->default_value("INCL default run title"), "run title")
103  ("output,o", boost::program_options::value<std::string>(&outputFileRoot), "root for generating output file names. 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")
104  ("logfile,l", boost::program_options::value<std::string>(&logFileName), "log file name. Defaults to `<output_root>.log'. Use `-' if you want to redirect logging to stdout")
105  ("number-shots,N", boost::program_options::value<G4int>(&nShots), "* number of shots")
106  ("target,t", boost::program_options::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.")
107  ("projectile,p", boost::program_options::value<std::string>(&projectileString), "* projectile name:\n"
108  " \tproton, p\n"
109  " \tneutron, n\n"
110  " \tpi+, piplus, pion+, pionplus\n"
111  " \tpi0, pizero, pion0, pionzero\n"
112  " \tpi-, piminus, pion-, pionminus\n"
113  " \td, t, a, deuteron, triton, alpha\n"
114  " \tHe-4, He4, 4He (and so on)\n")
115  ("energy,E", boost::program_options::value<G4float>(&projectileKineticEnergy), "* total kinetic energy of the projectile, in MeV")
116  ("verbose-event", boost::program_options::value<G4int>(&verboseEvent)->default_value(-1), "request verbose logging for the specified event only")
117  ("random-seed-1", boost::program_options::value<G4int>(&randomSeed1)->default_value(666), "first seed for the random-number generator")
118  ("random-seed-2", boost::program_options::value<G4int>(&randomSeed2)->default_value(777), "second seed for the random-number generator")
119  ("inclxx-datafile-path", boost::program_options::value<std::string>(&INCLXXDataFilePath)->default_value("./data/"))
120 #ifdef INCL_DEEXCITATION_ABLAXX
121  ("ablav3p-cxx-datafile-path", boost::program_options::value<std::string>(&ablav3pCxxDataFilePath)->default_value("./de-excitation/ablaxx/data/G4ABLA3.0/"))
122 #endif
123 #ifdef INCL_DEEXCITATION_ABLA07
124  ("abla07-datafile-path", boost::program_options::value<std::string>(&abla07DataFilePath)->default_value("./de-excitation/abla07/upstream/tables/"))
125 #endif
126 #ifdef INCL_DEEXCITATION_GEMINIXX
127  ("geminixx-datafile-path", boost::program_options::value<std::string>(&geminixxDataFilePath)->default_value("./de-excitation/geminixx/upstream/"))
128 #endif
129  ("verbosity,v", boost::program_options::value<G4int>(&verbosity)->default_value(4), verbosityDescription.str().c_str())
130  ;
131 
132  // Physics options
133  boost::program_options::options_description physicsOptDesc("Physics options");
134  physicsOptDesc.add_options()
135  ("pauli", boost::program_options::value<std::string>(&pauliString)->default_value("strict-statistical"), "Pauli-blocking algorithm:\n"
136  " \tstrict-statistical (default)\n"
137  " \tstrict\n"
138  " \tstatistical\n"
139  " \tglobal\n"
140  " \tnone")
141  ("cdpp", boost::program_options::value<G4bool>(&CDPP)->default_value(true), "whether to apply CDPP after collisions:\n \ttrue, 1 (default)\n \tfalse, 0")
142  ("coulomb", boost::program_options::value<std::string>(&coulombString)->default_value("non-relativistic"), "Coulomb-distortion algorithm:\n \tnon-relativistic (default)\n \tnone")
143  ("potential", boost::program_options::value<std::string>(&potentialString)->default_value("isospin-energy"), "nucleon potential:\n \tisospin-energy-smooth\n \tisospin-energy (default)\n \tisospin\n \tconstant")
144  ("pion-potential", boost::program_options::value<G4bool>(&pionPotential)->default_value("true"), "whether to use a pion potential:\n \ttrue, 1 (default)\n \tfalse, 0")
145  ("local-energy-BB", boost::program_options::value<std::string>(&localEnergyBBString)->default_value("first-collision"), "local energy in baryon-baryon collisions:\n \talways\n \tfirst-collision (default)\n \tnever")
146  ("local-energy-pi", boost::program_options::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")
147  ("de-excitation", boost::program_options::value<std::string>(&deExcitationString)->default_value("none"), "which de-excitation model to use:"
148  "\n \tnone (default)"
149 #ifdef INCL_DEEXCITATION_ABLAXX
150  "\n \tABLAv3p"
151 #endif
152 #ifdef INCL_DEEXCITATION_ABLA07
153  "\n \tABLA07"
154 #endif
155 #ifdef INCL_DEEXCITATION_SMM
156  "\n \tSMM"
157 #endif
158 #ifdef INCL_DEEXCITATION_GEMINIXX
159  "\n \tGEMINIXX"
160 #endif
161  )
162  ("cluster-algorithm", boost::program_options::value<std::string>(&clusterAlgorithmString)->default_value("intercomparison"), "clustering algorithm for production of composites:\n \tintercomparison (default)\n \tnone")
163  ("cluster-max-mass", boost::program_options::value<G4int>(&clusterMaxMass)->default_value(8), "maximum mass of produced composites:\n \tminimum 2\n \tmaximum 12")
164  ("back-to-spectator", boost::program_options::value<G4bool>(&backToSpectator)->default_value("true"), "whether to use back-to-spectator:\n \ttrue, 1 (default)\n \tfalse, 0")
165  ("use-real-masses", boost::program_options::value<G4bool>(&useRealMasses)->default_value("true"), "whether to use real masses for the outgoing particle energies:\n \ttrue, 1 (default)\n \tfalse, 0")
166  ("separation-energies", boost::program_options::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")
167  ;
168 
169  // Select options allowed on the command line
170  boost::program_options::options_description cmdLineOptions;
171  cmdLineOptions.add(hiddenOptDesc).add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
172 
173  // Select options allowed in config files
174  boost::program_options::options_description configFileOptions;
175  configFileOptions.add(runOptDesc).add(physicsOptDesc);
176 
177  // Select visible options
178  boost::program_options::options_description visibleOptions;
179  visibleOptions.add(genericOptDesc).add(runOptDesc).add(physicsOptDesc);
180 
181  // Declare input-file as a positional option (if we just provide a file
182  // name on the command line, it should be interpreted as an input-file
183  // option).
184  boost::program_options::positional_options_description p;
185  p.add("input-file", 1);
186 
187  // Disable guessing of option names
188  G4int cmdstyle =
189  boost::program_options::command_line_style::default_style &
190  ~boost::program_options::command_line_style::allow_guessing;
191 
192  // Result of the option processing
193  boost::program_options::variables_map variablesMap;
194  boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
195  style(cmdstyle).
196  options(cmdLineOptions).positional(p).run(), variablesMap);
197  boost::program_options::notify(variablesMap);
198 
199  // If an input file was specified, merge the options with the command-line
200  // options.
201  if(variablesMap.count("input-file")) {
202  std::ifstream inputFileStream(inputFileName.c_str());
203  if(!inputFileStream) {
204  std::cerr << "Cannot open input file: " << inputFileName << std::endl;
205  std::exit(EXIT_FAILURE);
206  } else {
207  // Merge options from the input file
208  boost::program_options::parsed_options parsedOptions = boost::program_options::parse_config_file(inputFileStream, configFileOptions, true);
209 
210  // Make sure that the unhandled options are all "*-datafile-path"
211  std::vector<std::string> unhandledOptions =
212  boost::program_options::collect_unrecognized(parsedOptions.options, boost::program_options::exclude_positional);
213  G4bool ignoreNext = false;
214  const std::string match = "-datafile-path";
215  for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(); i!=unhandledOptions.end(); ++i) {
216  if(ignoreNext) {
217  ignoreNext=false;
218  continue;
219  }
220  if(i->rfind(match) == i->length()-match.length()) {
221  std::cerr << "Ignoring unrecognized option " << *i << std::endl;
222  ignoreNext = true;
223  } else {
224  std::cerr << "Error: unrecognized option " << *i << std::endl;
225  std::cerr << suggestHelpMsg;
226  std::exit(EXIT_FAILURE);
227  }
228  }
229 
230  // Store the option values in the variablesMap
231  boost::program_options::store(parsedOptions, variablesMap);
232  boost::program_options::notify(variablesMap);
233  }
234  inputFileStream.close();
235  }
236 
237  // Process the options from the user-specific config file ~/.inclxxrc
238  std::string configFileName;
239  const char * const configFileVar = getenv("INCLXXRC");
240  if(configFileVar)
241  configFileName = configFileVar;
242  else {
243  const char * const homeDirectoryPointer = getenv("HOME");
244  if(homeDirectoryPointer) { // Check if we can find the home directory
245  std::string homeDirectory(homeDirectoryPointer);
246  configFileName = homeDirectory + "/.inclxxrc";
247  } else {
248  std::cerr << "Could not determine the user's home directory. "
249  << "Are you running Linux, Unix or BSD?"<< std::endl;
250  std::exit(EXIT_FAILURE);
251  }
252  }
253 
254  std::ifstream configFileStream(configFileName.c_str());
255  std::cout << "Reading config file " << configFileName << std::endl;
256  if(!configFileStream) {
257  std::cerr << "INCL++ config file " << configFileName
258  << " not found. Continuing the run regardless."
259  << std::endl;
260  } else {
261  // Merge options from the input file
262  boost::program_options::parsed_options parsedOptions = boost::program_options::parse_config_file(configFileStream, configFileOptions, true);
263  boost::program_options::store(parsedOptions, variablesMap);
264 
265  // Make sure that the unhandled options are all "*-datafile-path"
266  std::vector<std::string> unhandledOptions =
267  boost::program_options::collect_unrecognized(parsedOptions.options, boost::program_options::exclude_positional);
268  G4bool ignoreNext = false;
269  const std::string match = "-datafile-path";
270  for(std::vector<std::string>::const_iterator i=unhandledOptions.begin(); i!=unhandledOptions.end(); ++i) {
271  if(ignoreNext) {
272  ignoreNext=false;
273  continue;
274  }
275  if(i->rfind(match) == i->length()-match.length()) {
276  std::cerr << "Ignoring unrecognized option " << *i << std::endl;
277  ignoreNext = true;
278  } else {
279  std::cerr << "Error: unrecognized option " << *i << std::endl;
280  std::cerr << suggestHelpMsg;
281  std::exit(EXIT_FAILURE);
282  }
283  }
284 
285  // Store the option values in the variablesMap
286  boost::program_options::store(parsedOptions, variablesMap);
287  boost::program_options::notify(variablesMap);
288  }
289  configFileStream.close();
290 
291  /* *******************
292  * Process the options
293  * *******************/
294 
295  // -h/--help: print the help message and exit successfully
296  if(variablesMap.count("help")) {
297  std::cout << "Usage: INCLCascade [options] <input_file>" << std::endl;
298  std::cout << 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;
299  std::cout << visibleOptions << std::endl;
300  std::exit(EXIT_SUCCESS);
301  }
302 
303  // --version: print the version string and exit successfully
304  if(variablesMap.count("version")) {
305  std::cout <<"INCL++ version " << getVersionID() << std::endl;
306  std::exit(EXIT_SUCCESS);
307  }
308 
309  // Check if the required options are present
310  if(isFullRun) {
311  std::string missingOption("");
312  if(!variablesMap.count("number-shots"))
313  missingOption = "number-shots";
314  else if(!variablesMap.count("target"))
315  missingOption = "target";
316  else if(!variablesMap.count("projectile"))
317  missingOption = "projectile";
318  else if(!variablesMap.count("energy"))
319  missingOption = "energy";
320  if(!missingOption.empty()) {
321  std::cerr << "Required option " << missingOption << " is missing." << std::endl;
322  std::cerr << suggestHelpMsg;
323  std::exit(EXIT_FAILURE);
324  }
325  } else {
326  std::cout <<"Not performing a full run. This had better be a test..." << std::endl;
327  }
328 
329  // -p/--projectile: projectile species
330  projectileSpecies = ParticleSpecies(projectileString);
331  if(projectileSpecies.theType == G4INCL::UnknownParticle && isFullRun) {
332  std::cerr << "Error: unrecognized particle type " << projectileString << std::endl;
333  std::cerr << suggestHelpMsg;
334  std::exit(EXIT_FAILURE);
335  }
336 
337  // -t/--target: target species
338  if(variablesMap.count("target")) {
339  targetSpecies = ParticleSpecies(targetString);
340  if(targetSpecies.theType!=Composite) {
341  std::cerr << "Unrecognized target. You specified: " << targetString << std::endl
342  << " The target nuclide must be specified in one of the following forms:" << std::endl
343  << " Fe56, 56Fe, Fe-56, 56-Fe, Fe_56, 56_Fe, Fe" << std::endl
344  << " You can also use IUPAC element names (such as Uuh)." << std::endl;
345  std::cerr << suggestHelpMsg;
346  std::exit(EXIT_FAILURE);
347  }
348  if(targetSpecies.theA==0)
349  naturalTarget = true;
350  }
351 
352  // --pauli
353  if(variablesMap.count("pauli")) {
354  std::string pauliNorm = pauliString;
355  std::transform(pauliNorm.begin(), pauliNorm.end(), pauliNorm.begin(), ::tolower);
356  if(pauliNorm=="statistical")
357  pauliType = StatisticalPauli;
358  else if(pauliNorm=="strict")
359  pauliType = StrictPauli;
360  else if(pauliNorm=="strict-statistical")
361  pauliType = StrictStatisticalPauli;
362  else if(pauliNorm=="global")
363  pauliType = GlobalPauli;
364  else if(pauliNorm=="none")
365  pauliType = NoPauli;
366  else {
367  std::cerr << "Unrecognized Pauli-blocking algorithm. Must be one of:" << std::endl
368  << " strict-statistical (default)" << std::endl
369  << " strict" << std::endl
370  << " statistical" << std::endl
371  << " global" << std::endl
372  << " none" << std::endl;
373  std::cerr << suggestHelpMsg;
374  std::exit(EXIT_FAILURE);
375  }
376  }
377 
378  // --coulomb
379  if(variablesMap.count("coulomb")) {
380  std::string coulombNorm = coulombString;
381  std::transform(coulombNorm.begin(), coulombNorm.end(), coulombNorm.begin(), ::tolower);
382  if(coulombNorm=="non-relativistic")
383  coulombType = NonRelativisticCoulomb;
384  else if(coulombNorm=="none")
385  coulombType = NoCoulomb;
386  else {
387  std::cerr << "Unrecognized Coulomb-distortion algorithm. Must be one of:" << std::endl
388  << " non-relativistic-heavy-ion (default)" << std::endl
389  << " non-relativistic" << std::endl
390  << " none" << std::endl;
391  std::cerr << suggestHelpMsg;
392  std::exit(EXIT_FAILURE);
393  }
394  }
395 
396  // --potential
397  if(variablesMap.count("potential")) {
398  std::string potentialNorm = potentialString;
399  std::transform(potentialNorm.begin(), potentialNorm.end(), potentialNorm.begin(), ::tolower);
400  if(potentialNorm=="isospin-energy-smooth") {
401  potentialType = IsospinEnergySmoothPotential;
402  } else if(potentialNorm=="isospin-energy") {
403  potentialType = IsospinEnergyPotential;
404  } else if(potentialNorm=="isospin")
405  potentialType = IsospinPotential;
406  else if(potentialNorm=="constant")
407  potentialType = ConstantPotential;
408  else {
409  std::cerr << "Unrecognized potential type. Must be one of:" << std::endl
410  << " isospin-energy-smooth" << std::endl
411  << " isospin-energy (default)" << std::endl
412  << " isospin" << std::endl
413  << " constant" << std::endl;
414  std::cerr << suggestHelpMsg;
415  std::exit(EXIT_FAILURE);
416  }
417  }
418 
419  // --local-energy-BB
420  if(variablesMap.count("local-energy-BB")) {
421  std::string localEnergyBBNorm = localEnergyBBString;
422  std::transform(localEnergyBBNorm.begin(), localEnergyBBNorm.end(), localEnergyBBNorm.begin(), ::tolower);
423  if(localEnergyBBNorm=="always") {
424  localEnergyBBType = AlwaysLocalEnergy;
425  } else if(localEnergyBBNorm=="first-collision")
426  localEnergyBBType = FirstCollisionLocalEnergy;
427  else if(localEnergyBBNorm=="never")
428  localEnergyBBType = NeverLocalEnergy;
429  else {
430  std::cerr << "Unrecognized local-energy-BB type. Must be one of:" << std::endl
431  << " always" << std::endl
432  << " first-collision (default)" << std::endl
433  << " never" << std::endl;
434  std::cerr << suggestHelpMsg;
435  std::exit(EXIT_FAILURE);
436  }
437  }
438 
439  // --local-energy-pi
440  if(variablesMap.count("local-energy-pi")) {
441  std::string localEnergyPiNorm = localEnergyPiString;
442  std::transform(localEnergyPiNorm.begin(), localEnergyPiNorm.end(), localEnergyPiNorm.begin(), ::tolower);
443  if(localEnergyPiNorm=="always") {
444  localEnergyPiType = AlwaysLocalEnergy;
445  } else if(localEnergyPiNorm=="first-collision")
446  localEnergyPiType = FirstCollisionLocalEnergy;
447  else if(localEnergyPiNorm=="never")
448  localEnergyPiType = NeverLocalEnergy;
449  else {
450  std::cerr << "Unrecognized local-energy-pi type. Must be one of:" << std::endl
451  << " always" << std::endl
452  << " first-collision" << std::endl
453  << " never (default)" << std::endl;
454  std::cerr << suggestHelpMsg;
455  std::exit(EXIT_FAILURE);
456  }
457  }
458 
459  // --de-excitation
460  if(variablesMap.count("de-excitation")) {
461  std::string deExcitationNorm = deExcitationString;
462  std::transform(deExcitationNorm.begin(),
463  deExcitationNorm.end(),
464  deExcitationNorm.begin(), ::tolower);
465  if(deExcitationNorm=="none")
466  deExcitationType = DeExcitationNone;
467 #ifdef INCL_DEEXCITATION_ABLAXX
468  else if(deExcitationNorm=="ablav3p")
469  deExcitationType = DeExcitationABLAv3p;
470 #endif
471 #ifdef INCL_DEEXCITATION_ABLA07
472  else if(deExcitationNorm=="abla07")
473  deExcitationType = DeExcitationABLA07;
474 #endif
475 #ifdef INCL_DEEXCITATION_SMM
476  else if(deExcitationNorm=="smm")
477  deExcitationType = DeExcitationSMM;
478 #endif
479 #ifdef INCL_DEEXCITATION_GEMINIXX
480  else if(deExcitationNorm=="geminixx")
481  deExcitationType = DeExcitationGEMINIXX;
482 #endif
483  else {
484  std::cerr << "Unrecognized de-excitation model. "
485  << "Must be one of:" << std::endl
486  << " none (default)" << std::endl
487 #ifdef INCL_DEEXCITATION_ABLAXX
488  << " ABLAv3p" << std::endl
489 #endif
490 #ifdef INCL_DEEXCITATION_ABLA07
491  << " ABLA07" << std::endl
492 #endif
493 #ifdef INCL_DEEXCITATION_SMM
494  << " SMM" << std::endl
495 #endif
496 #ifdef INCL_DEEXCITATION_GEMINIXX
497  << " GEMINIXX" << std::endl
498 #endif
499  ;
500  std::cerr << suggestHelpMsg;
501  std::exit(EXIT_FAILURE);
502  }
503  } else {
504  deExcitationType = DeExcitationNone;
505  }
506 
507  // --cluster-algorithm
508  if(variablesMap.count("cluster-algorithm")) {
509  std::string clusterAlgorithmNorm = clusterAlgorithmString;
510  std::transform(clusterAlgorithmNorm.begin(),
511  clusterAlgorithmNorm.end(),
512  clusterAlgorithmNorm.begin(), ::tolower);
513  if(clusterAlgorithmNorm=="none")
514  clusterAlgorithmType = NoClusterAlgorithm;
515  else if(clusterAlgorithmNorm=="intercomparison")
516  clusterAlgorithmType = IntercomparisonClusterAlgorithm;
517  else {
518  std::cerr << "Unrecognized cluster algorithm. "
519  << "Must be one of:" << std::endl
520  << " intercomparison (default)" << std::endl
521  << " none" << std::endl;
522  std::cerr << suggestHelpMsg;
523  std::exit(EXIT_FAILURE);
524  }
525  } else {
526  clusterAlgorithmType = IntercomparisonClusterAlgorithm;
527  }
528 
529  // --cluster-max-mass
530  if(variablesMap.count("cluster-max-mass") && clusterMaxMass < 2 && clusterMaxMass > 12) {
531  std::cerr << "Maximum cluster mass outside the allowed range. Must be between 2 and 12 (included)"
532  << std::endl
533  << suggestHelpMsg;
534  std::exit(EXIT_FAILURE);
535  }
536 
537  // --separation-energies
538  if(variablesMap.count("separation-energies")) {
539  std::string separationEnergyNorm = separationEnergyString;
540  std::transform(separationEnergyNorm.begin(),
541  separationEnergyNorm.end(),
542  separationEnergyNorm.begin(), ::tolower);
543  if(separationEnergyNorm=="incl")
544  separationEnergyType = INCLSeparationEnergy;
545  else if(separationEnergyNorm=="real")
546  separationEnergyType = RealSeparationEnergy;
547  else if(separationEnergyNorm=="real-light")
548  separationEnergyType = RealForLightSeparationEnergy;
549  else {
550  std::cerr << "Unrecognized separation-energies option. "
551  << "Must be one of:" << std::endl
552  << " INCL (default)" << std::endl
553  << " real" << std::endl
554  << " real-light" << std::endl;
555  std::cerr << suggestHelpMsg;
556  std::exit(EXIT_FAILURE);
557  }
558  } else {
559  separationEnergyType = INCLSeparationEnergy;
560  }
561 
562  // --output: construct a reasonable output file root if not specified
563  if(!variablesMap.count("output") && isFullRun) {
564  // If an input file was specified, use its name as the output file root
565  if(variablesMap.count("input-file"))
566  outputFileRoot = inputFileName;
567  else {
568  std::stringstream outputFileRootStream;
569  outputFileRootStream.precision(0);
570  outputFileRootStream.setf(std::ios::fixed, std::ios::floatfield);
571  outputFileRootStream <<
572  ParticleTable::getShortName(projectileSpecies) << "_" <<
573  ParticleTable::getShortName(targetSpecies) << "_" <<
574  projectileKineticEnergy;
575 
576  // Append suffixes to the output file root for each explicitly specified CLI option
577  typedef boost::program_options::variables_map::const_iterator BPOVMIter;
578  for(BPOVMIter i=variablesMap.begin(); i!=variablesMap.end(); ++i) {
579  std::string const &name = i->first;
580  // Only process CLI options
581  if(name!="projectile"
582  && name!="target"
583  && name!="energy"
584  && name!="number-shots"
585  && name!="random-seed-1"
586  && name!="random-seed-2"
587  && name!="inclxx-datafile-path"
588 #ifdef INCL_DEEXCITATION_ABLA07
589  && name!="abla07-datafile-path"
590 #endif
591 #ifdef INCL_DEEXCITATION_ABLAXX
592  && name!="ablav3p-cxx-datafile-path"
593 #endif
594 #ifdef INCL_DEEXCITATION_GEMINIXX
595  && name!="geminixx-datafile-path"
596 #endif
597  ) {
598  boost::program_options::variable_value v = i->second;
599  if(!v.defaulted()) {
600  const std::type_info &type = v.value().type();
601  if(type==typeid(std::string))
602  outputFileRootStream << "_" << name << "=" << v.as<std::string>();
603  else if(type==typeid(G4float))
604  outputFileRootStream << "_" << name << "=" << v.as<G4float>();
605  else if(type==typeid(G4int))
606  outputFileRootStream << "_" << name << "=" << v.as<G4int>();
607  else if(type==typeid(G4bool))
608  outputFileRootStream << "_" << name << "=" << v.as<G4bool>();
609  }
610  }
611  }
612 
613  outputFileRoot = outputFileRootStream.str();
614  }
615  }
616 
617  // -l/--logfile
618  if(!variablesMap.count("logfile"))
619  logFileName = outputFileRoot + ".log";
620 
621  }
622  catch(std::exception& e)
623  {
624  std::cerr << e.what() << "\n";
625  std::cerr << suggestHelpMsg;
626  std::exit(EXIT_FAILURE);
627  }
628 
629  }
630 #else
631  Config::Config(G4int /*argc*/, char * /*argv*/ [], G4bool /*isFullRun*/)
632  {
633  init();
634  }
635 #endif
636 
638  {}
639 
640  void Config::init() {
641  verbosity = 1;
642  inputFileName = "";
643  title = "INCL default run title";
644  nShots = 1000;
645  naturalTarget = false;
646  projectileString = "proton";
647  projectileSpecies = G4INCL::Proton;
648  projectileKineticEnergy = 1000.0;
649  verboseEvent = -1;
650  randomSeed1 = 666;
651  randomSeed2 = 777;
652  pauliString = "strict-statistical";
653  pauliType = StrictStatisticalPauli;
654  CDPP = true;
655  coulombString = "non-relativistic";
656  coulombType = NonRelativisticCoulomb;
657  potentialString = "isospin-energy";
658  potentialType = IsospinEnergyPotential;
659  pionPotential = true;
660  localEnergyBBString = "first-collision";
661  localEnergyBBType = FirstCollisionLocalEnergy;
662  localEnergyPiString = "first-collision";
663  localEnergyPiType = FirstCollisionLocalEnergy;
664  deExcitationString = "none";
665  deExcitationType = DeExcitationNone;
666  clusterAlgorithmString = "intercomparison";
667  clusterAlgorithmType = IntercomparisonClusterAlgorithm;
668  clusterMaxMass = 8;
669  backToSpectator = true;
670  useRealMasses = true;
671  impactParameter = -1.;
672  separationEnergyString = "INCL";
673  separationEnergyType = INCLSeparationEnergy;
674  }
675 
676  std::string Config::summary() {
677  std::stringstream message;
678  message << "INCL++ version " << getVersionID() << std::endl;
679  if(projectileSpecies.theType != Composite)
680  message << "Projectile: " << ParticleTable::getName(projectileSpecies) << std::endl;
681  else
682  message << "Projectile: composite, A=" << projectileSpecies.theA << ", Z=" << projectileSpecies.theZ << std::endl;
683  message << " energy = " << projectileKineticEnergy << std::endl;
684  if(targetSpecies.theA>0)
685  message << "Target: A = " << targetSpecies.theA << " Z = " << targetSpecies.theZ << std::endl;
686  else
687  message << "Target: natural isotopic composition, Z = " << targetSpecies.theZ << std::endl;
688  message << "Number of requested shots = " << nShots << std::endl;
689  return message.str();
690  }
691 
692  std::string const Config::echo() const {
693  std::stringstream ss;
694  ss << std::boolalpha;
695  ss << "###########################" << std::endl
696  << "### Start of input echo ###" << std::endl
697  << "###########################" << std::endl << std::endl
698  << " # You may re-use this snippet of the log file as an input file!" << std::endl
699  << " # Options marked with a * are compulsory." << std::endl
700  << std::endl
701  << "# Run options" << std::endl
702  << "title = " << title << "\t# run title" << std::endl
703  << "output = " << outputFileRoot << "\t# root for generating output file names. 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" << std::endl
704  << "logfile = " << logFileName << "\t# log file name. Defaults to `<output_root>.log'. Use `-' if you want to redirect logging to stdout" << std::endl
705  << "number-shots = " << nShots << "\t# * number of shots" << std::endl
706  << "inclxx-datafile-path = " << INCLXXDataFilePath << std::endl
707 #ifdef INCL_DEEXCITATION_ABLAXX
708  << "ablav3p-cxx-datafile-path = " << ablav3pCxxDataFilePath << std::endl
709 #endif
710 #ifdef INCL_DEEXCITATION_ABLA07
711  << "abla07-datafile-path = " << abla07DataFilePath << std::endl
712 #endif
713 #ifdef INCL_DEEXCITATION_GEMINIXX
714  << "geminixx-datafile-path = " << geminixxDataFilePath << std::endl
715 #endif
716  << std::endl << "# Projectile and target definitions" << std::endl
717  << "target = " << targetString << "\t# * 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." << std::endl
718  << " " << "# the target nuclide was parsed as Z=" << targetSpecies.theZ;
719  if(targetSpecies.theA>0)
720  ss << ", A=" << targetSpecies.theA;
721  else
722  ss << ", natural target";
723  ss << std::endl
724  << "projectile = " << projectileString << "\t# * projectile name (proton, neutron, pi+, pi0, pi-, d, t, a, He-4...)" << std::endl
725  << " " << "# the projectile nuclide was parsed as Z=" << projectileSpecies.theZ << ", A=" << projectileSpecies.theA << std::endl
726  << "energy = " << projectileKineticEnergy << "\t# * total kinetic energy of the projectile, in MeV" << std::endl
727  << std::endl << "# Physics options " << std::endl
728  << "pauli = " << pauliString << "\t# Pauli-blocking algorithm. Must be one of: strict-statistical (default), strict, statistical, global, none" << std::endl
729  << "cdpp = " << CDPP << "\t# whether to apply CDPP after collisions" << std::endl
730  << "coulomb = " << coulombString << "\t# Coulomb-distortion algorithm. Must be one of: non-relativistic (default), none" << std::endl
731  << "potential = " << potentialString << "\t# nucleon potential. Must be one of: isospin-energy-smooth, isospin-energy (default), isospin, constant" << std::endl
732  << "pion-potential = " << pionPotential << "\t# whether to use a pion potential" << std::endl
733  << "local-energy-BB = " << localEnergyBBString << "\t# local energy in baryon-baryon collisions. Must be one of: always, first-collision (default), never" << std::endl
734  << "local-energy-pi = " << localEnergyPiString << "\t# local energy in pi-N collisions and in delta decays. Must be one of: always, first-collision (default), never" << std::endl
735  << "de-excitation = " << deExcitationString << "\t # which de-excitation model to use. Must be one of:"
736  " none (default)"
737 #ifdef INCL_DEEXCITATION_ABLAXX
738  ", ABLAv3p"
739 #endif
740 #ifdef INCL_DEEXCITATION_ABLA07
741  ", ABLA07"
742 #endif
743 #ifdef INCL_DEEXCITATION_SMM
744  ", SMM"
745 #endif
746 #ifdef INCL_DEEXCITATION_GEMINIXX
747  ", GEMINIXX"
748 #endif
749  << std::endl
750  << "cluster-algorithm = " << clusterAlgorithmString << "\t# clustering algorithm for production of composites. Must be one of: intercomparison (default), none" << std::endl
751  << "cluster-max-mass = " << clusterMaxMass << "\t# maximum mass of produced composites. Must be between 2 and 12 (included)" << std::endl
752  << "back-to-spectator = " << backToSpectator << "\t# whether to use back-to-spectator" << std::endl
753  << "use-real-masses = " << useRealMasses << "\t# whether to use real masses for the outgoing particle energies" << std::endl
754  << "separation-energies = " << separationEnergyString << "\t# how to assign the separation energies of the INCL nucleus. Must be one of: INCL (default), real, real-light" << std::endl
755  << std::endl << "# Technical options " << std::endl
756  << "verbosity = " << verbosity << "\t# from 0 (quiet) to 10 (most verbose)" << std::endl
757  << "verbose-event = " << verboseEvent << "\t# request verbose logging for the specified event only" << std::endl
758  << "random-seed-1 = " << randomSeed1 << "\t# first seed for the random-number generator" << std::endl
759  << "random-seed-2 = " << randomSeed2 << "\t# second seed for the random-number generator" << std::endl
760  << std::endl << "#########################" << std::endl
761  << "### End of input echo ###" << std::endl
762  << "#########################" << std::endl;
763 
764  return ss.str();
765  }
766 
767 }