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