Nemo  2.4.2
Simulate forward-in-time genetic evolution in a spatially explicit, individual-based stochastic simulator
ParamManager Class Reference

Class to manage the sets of parameters of the simulation components. More...

#include <basicsimulation.h>

+ Inheritance diagram for ParamManager:
+ Collaboration diagram for ParamManager:

Public Member Functions

 ParamManager ()
 Cstor. More...
 
 ~ParamManager ()
 
void add_paramset (ParamSet *paramset)
 Adds a ParamSet to the list of the parameter sets of the simulation. More...
 
ParamSetget_paramset (string &name)
 Looks for paramset with "name" in the list of parameter sets. More...
 
void build_allParams ()
 Clears and fills the _allParams list with the ParamSet's of the simulation components. More...
 
list< ParamSet * > & get_allParams ()
 Accessor of the whole list of the parameter sets. More...
 
bool set_parameters (map< string, string > &simparams, bool silent)
 Sets the parameters of the simulation with the argument strings given in input. More...
 
bool param_consistency_check ()
 Checks if all the mandatory parameters are set so that the simulation can be launched. More...
 
void build_records (map< string, vector< string > > &initParams)
 Builds the list of simulation parameters from the parsed input file(s). More...
 
list< map< string, string > > & get_simRecords ()
 Accessor to the simulations parameter list. More...
 
map< string, string > & get_firstRecord ()
 Accessor to the first element in the simulations parameter list. More...
 
int get_nbSims ()
 Accessor to the size of the simulations parameter list, i.e. More...
 
- Public Member Functions inherited from ComponentManager
 ComponentManager ()
 
 ~ComponentManager ()
 
void build_component_list ()
 Clears and builds the list of all components from the lists of trait prototype templates and life cycle event templates. More...
 
void add_component (SimComponent *cmpt)
 Push a component at the back of the component list. More...
 
void add_trait (TraitPrototype *trait)
 Add a trait prototype to the template and component lists. More...
 
void add_LCE (LifeCycleEvent *event)
 Add a life cycle event to the template and component lists. More...
 
TraitPrototypeget_trait (string name)
 Search for component with "name" in the trait prototype list. More...
 
LifeCycleEventget_LCE (string name)
 Search for component with "name" in the life cycle events list. More...
 

Protected Attributes

list< ParamSet * > _allParams
 A list of all the parameter sets of all the simulation components loaded in the _component list of the ComponentManager. More...
 
map< string, string > _inputParams
 A map of the parameters and their arguments of the current (running) simulation. More...
 
map< unsigned int, list< pair< string, string > > > _temporalParams
 Lists of parameters to be updated during a simulation indexed by generation update time. More...
 
list< map< string, string > > _simRecords
 Sets of parameters of all the simulations to perform. More...
 
ParamSet _paramSet
 The ParamSet param set of the simulation. More...
 
- Protected Attributes inherited from ComponentManager
list< SimComponent * > _components
 List of all the simulation components. More...
 
list< TraitPrototype * > _TTrait_Templates
 List of all trait prototypes of the simulation, a subset of _components list. More...
 
list< LifeCycleEvent * > _LCE_Templates
 List of all the life-cycle events of the simulation, a subset of _components list. More...
 

Private Member Functions

string setFilename (string &fstring, unsigned int sim, vector< string > &args, vector< unsigned int > &arg_no, vector< bool > &is_linked, vector< string > &names, bool check_arg_no)
 
string stripFormatString (string &str, unsigned int &index)
 
string setArgString (string &fmt, string &arg, unsigned int arg_pos)
 
string lowercase (string &input)
 

Detailed Description

Class to manage the sets of parameters of the simulation components.

This class performs parameters setting and checking for the whole set of the simulation components. Provides access to derived classes to the complete list of parameter sets. Also sets the list of simulations parameters in case of sequential parameters found in input. It stores and builds the simulation parameters set.

See also
ParamsParser and derived classes. These are the input parameters providers.

Constructor & Destructor Documentation

◆ ParamManager()

ParamManager::ParamManager ( )

Cstor.

Builds the simulation PramaSet.

98 {
99  _paramSet.setName("simulation");
100  _paramSet.setIsRequired(true);
101  _paramSet.setOwner(NULL);
102  _paramSet.add_param("filename",STR,true,false,0,0);
103  _paramSet.add_param("root_dir",STR,false,false,0,0);
104  _paramSet.add_param("logfile",STR,false,false,0,0);
105  _paramSet.add_param("postexec_script",STR,false,false,0,0);
106  _paramSet.add_param("postexec_args",STR,false,false,0,0);
107  _paramSet.add_param("postexec_replicate_wise", BOOL, 0,0,0,0);
108  _paramSet.add_param("random_seed",INT,false,false,0,0);
109  _paramSet.add_param("replicates",INT,true,false,0,0);
110  _paramSet.add_param("generations",INT,true,false,0,0);
111  _paramSet.add_param("run_mode",STR,false,false,0,0);
112 }
ParamSet _paramSet
The ParamSet param set of the simulation.
Definition: basicsimulation.h:149
void add_param(Param *param)
Adds the param argument to the list.
Definition: param.h:251
void setName(string value)
Sets the container's name.
Definition: param.h:290
void setOwner(SimComponent *owner)
Sets the pointer to the SimComponents that owns this set.
Definition: param.h:294
void setIsRequired(bool value)
Sets the _isRequired flag meaning this container is mandatory and must be set in order to run a simul...
Definition: param.h:292
@ BOOL
Definition: types.h:76
@ STR
Definition: types.h:76
@ INT
Definition: types.h:76

References _paramSet, ParamSet::add_param(), BOOL, INT, ParamSet::setIsRequired(), ParamSet::setName(), ParamSet::setOwner(), and STR.

◆ ~ParamManager()

ParamManager::~ParamManager ( )
inline
91 {/*message("ParamManager::~ParamManager\n");*/}

Member Function Documentation

◆ add_paramset()

void ParamManager::add_paramset ( ParamSet paramset)
inline

Adds a ParamSet to the list of the parameter sets of the simulation.

94  {
95  _allParams.push_back(paramset);
96  }
list< ParamSet * > _allParams
A list of all the parameter sets of all the simulation components loaded in the _component list of th...
Definition: basicsimulation.h:141

Referenced by BinaryDataLoader::extractPop().

+ Here is the caller graph for this function:

◆ build_allParams()

void ParamManager::build_allParams ( )

Clears and fills the _allParams list with the ParamSet's of the simulation components.

117 {
118  list< SimComponent* >::iterator cmpt = _components.begin();
119 
120  _allParams.clear();
121 
122  _allParams.push_back(&_paramSet);
123 
124  while(cmpt != _components.end()) {
125  _allParams.push_back( (*cmpt)->get_paramset() );
126  cmpt++;
127  }
128 }
list< SimComponent * > _components
List of all the simulation components.
Definition: basicsimulation.h:69

References _allParams, ComponentManager::_components, and _paramSet.

Referenced by SIMenv::loadDefaultComponents(), SimRunner::run(), and SimBuilder::SimBuilder().

+ Here is the caller graph for this function:

◆ build_records()

void ParamManager::build_records ( map< string, vector< string > > &  initParams)

Builds the list of simulation parameters from the parsed input file(s).

251 {
252  map< string, string > params;
253  map< string, string > paramsToExpand;
254  map< string, string >::iterator param_iter;
255  map< string, vector<string> >::iterator Pit;
256  unsigned int RecNb = 1, ArgNb, SeqParam = 0, BlockSize, seq_pos, num_seq_arg = 0;
257  vector<unsigned int> sequence; //stores the number of args of each sequence parameters
258  vector<string> currSeqArg;
259  vector<unsigned int> currSeqPos;
260  vector<bool> currSeqIsLinked;
261  vector<string> currSeqNames;
262  vector<string> currCombinArg;
263  vector<unsigned int> currCombinPos;
264  string NAME;
265  string ARG;
266  bool SEQUENCE = 0;
267 
268  //pre-pass: detect and unwrap linked-sequential parameters written as 'name [v1 v2 v3]'.
269  //All such parameters share a single sequence dimension and must declare the same number of values.
270  set<string> linked_names;
271  unsigned int linked_N = 0;
272  string linked_first_name;
273 
274  for(Pit = initParams.begin(); Pit != initParams.end(); ++Pit) {
275 
276  if(Pit->second.size() != 1) continue;
277  if(Pit->second[0].empty() || Pit->second[0][0] != '[') continue;
278 
279  string val = Pit->second[0];
280  size_t close = val.find_last_of(']');
281  if(close == string::npos) {
282  fatal("linked-sequential parameter \"%s\" has unterminated '[' (closing ']' not found)\n",
283  Pit->first.c_str());
284  }
285  string body = val.substr(1, close - 1);
286  body = tstring::replaceChar(body, '\t', ' ');
287  body = tstring::replaceChar(body, '\n', ' ');
288 
289  vector<string> tokens = tstring::splitExcludeEnclosedDelimiters(body, ' ');
290  vector<string> vals;
291  for(unsigned int k = 0; k < tokens.size(); ++k)
292  if(!tokens[k].empty()) vals.push_back(tokens[k]);
293 
294  if(vals.empty()) {
295  fatal("linked-sequential parameter \"%s\" has no values inside '[ ]'\n", Pit->first.c_str());
296  }
297 
298  if(linked_names.empty()) {
299  linked_N = vals.size();
300  linked_first_name = Pit->first;
301  } else if(vals.size() != linked_N) {
302  fatal("linked-sequential parameter \"%s\" has %u values, but \"%s\" set the group size to %u; "
303  "all linked-sequential parameters must share the same number of values\n",
304  Pit->first.c_str(), (unsigned)vals.size(), linked_first_name.c_str(), linked_N);
305  }
306 
307  if(vals.size() == 1) {
308  warning("linked-sequential parameter \"%s\" has only one value; brackets have no effect\n",
309  Pit->first.c_str());
310  }
311 
312  Pit->second = vals;
313  linked_names.insert(Pit->first);
314  }
315 
316  //the linked group, if any, claims sequence[0] as the outer dimension.
317  if(!linked_names.empty()) {
318  sequence.push_back(linked_N);
319  num_seq_arg++;
320  RecNb *= linked_N;
321  }
322 
323  //find combinatorial sequential parameters (every multi-value param not part of the linked group):
324  for(Pit = initParams.begin(); Pit != initParams.end(); ++Pit) {
325 
326  if(linked_names.count(Pit->first)) continue; //already counted as part of the linked group
327 
328  if(Pit->second.size() > 1) {
329  sequence.push_back(Pit->second.size());
330  num_seq_arg++;
331  RecNb *= Pit->second.size();
332  }
333  }
334 
335  if(RecNb > 1)
336  //we have a sequence of simulations:
337  SEQUENCE = true;
338 
339  for(unsigned int i = 0; i < RecNb; ++i) {
340  //now build the simulation records with the right params!
341  //the map 'param' will get all the params used for one simulation
342  //it is then added to the list of simulations' parameters map
343 
344  //all linked-sequential params share this position (they advance in lockstep as the outer dim)
345  unsigned int linked_pos = 0;
346  if(!linked_names.empty()) {
347  BlockSize = RecNb / sequence[0];
348  linked_pos = (i / BlockSize) % linked_N;
349  }
350 
351  //SeqParam indexes the 'sequence' vector; start past the linked slot if any
352  SeqParam = (linked_names.empty() ? 0 : 1);
353 
354  for(Pit = initParams.begin(); Pit != initParams.end(); ++Pit) {
355 
356  //linked-sequential params: pick the value at the shared position and apply name expansion
357  if(linked_names.count(Pit->first)) {
358  ARG = Pit->second[linked_pos];
359  currSeqPos.push_back(linked_pos);
360  currSeqArg.push_back(ARG);
361  currSeqIsLinked.push_back(true);
362  currSeqNames.push_back(Pit->first);
363 
364  if(ARG.find_first_of('%') != string::npos) {
365  if(!SEQUENCE) fatal("found name expansion string '%%' without multi-value parameters in the input file.\n");
366  paramsToExpand[Pit->first] = ARG;
367  } else
368  params[Pit->first] = ARG;
369 
370  continue;
371  }
372 
373  if(!(Pit->first.compare("filename")==0) &&
374  !(Pit->first.compare("stat")==0) &&
375  !(Pit->first.compare("postexec_args")==0)) {
376 
377  //get the number of arguments for the current parameter:
378  ArgNb = Pit->second.size();
379 
380  if(ArgNb > 1) {
381  //the current param is a sequence param
382  //increase the index of the sequence parameter
383  SeqParam++;
384  //then compute the right argument to give to the current simulation record:
385  BlockSize = RecNb;
386 
387  for(unsigned int j = 0; j < SeqParam; ++j)
388  BlockSize /= sequence[j];
389 
390  seq_pos = (i/BlockSize) % ArgNb;
391  //we store the argument position in its sequence and the actual argument string to build the filename:
392  currSeqPos.push_back( seq_pos );
393  currSeqArg.push_back(Pit->second[ seq_pos ]);
394  currSeqIsLinked.push_back(false);
395  currSeqNames.push_back(Pit->first);
396 
397  //assign the right argument to the parameter:
398  //params[Pit->first] = Pit->second[ seq_pos ];
399 
400  ARG = Pit->second[ seq_pos ];
401  //we can expand a string argument of a sequential parameter as well
402  if(ARG.find_first_of('%') != string::npos) {
403 
404  if(!SEQUENCE) fatal("found name expansion string '%%' without multi-value parameters in the input file.\n");
405 
406  paramsToExpand[Pit->first] = ARG;
407 
408  } else
409  params[Pit->first] = ARG;
410 
411  } else if (ArgNb == 1) {
412  //the current param isn't a sequence param but gets an argument
413  //we might have to do some name expansion:
414  ARG = Pit->second[0];
415 
416  if(ARG.find_first_of('%') != string::npos) {
417 
418  if(!SEQUENCE) fatal("found name expansion string '%%' without multi-value parameters in the input file.\n");
419 
420  paramsToExpand[Pit->first] = ARG;
421 
422  } else
423  params[Pit->first] = ARG;
424 
425  } else
426  //current param has no argument (bool type param) we give it value 1 (true)
427  params[Pit->first] = "1";
428 
429  } else if (Pit->first.compare("stat") == 0){
430 
431  params["stat"].assign("");
432  //build a string with all the stats arguments
433  for(unsigned int k = 0; k < Pit->second.size(); ++k)
434  params["stat"] += Pit->second[k] + " ";
435 
436  } else if (Pit->first.compare("filename")==0) {
437 
438  if(SEQUENCE)
439  NAME = Pit->second[0];
440  else
441  params["filename"] = Pit->second[0];
442 
443  } else if (Pit->first.compare("postexec_args") == 0){
444 
445  ARG = "";
446 
447  //build a string with all the postexec arguments
448  for(unsigned int k = 0; k < Pit->second.size(); ++k)
449  ARG += Pit->second[k] + " ";
450 
451  params["postexec_args"] = ARG;
452 
453  if(ARG.find_first_of('%') != string::npos)
454  paramsToExpand["postexec_args"] = ARG;
455  }
456  }
457 
458  if(SEQUENCE) { //perform expansion of param arguments containing the '%' marker
459 
460  params["filename"] = setFilename(NAME, i+1, currSeqArg, currSeqPos, currSeqIsLinked, currSeqNames, true);
461 
462  for(param_iter = paramsToExpand.begin(); param_iter != paramsToExpand.end(); param_iter++)
463  params[param_iter->first] = setFilename(param_iter->second, i+1, currSeqArg, currSeqPos, currSeqIsLinked, currSeqNames, false);
464  }
465 
466  //add all the params previously computed to the main simulation recorder list (of maps)
467  _simRecords.push_back(params);
468 
469  currSeqArg.clear();
470  currSeqPos.clear();
471  currSeqIsLinked.clear();
472  currSeqNames.clear();
473  }
474  /*
475  RecNb = 1;
476  for(RecIt = SimRecorder.begin();RecIt != SimRecorder.end();++RecIt){
477  message("\nSimulation "<<RecNb++;
478  for(P2 = RecIt->begin();P2 != RecIt->end();++P2)
479  message("\n "<<P2->first<<"\t"<<P2->second;
480  }
481 */
482 }
string setFilename(string &fstring, unsigned int sim, vector< string > &args, vector< unsigned int > &arg_no, vector< bool > &is_linked, vector< string > &names, bool check_arg_no)
Definition: basicsimulation.cc:486
list< map< string, string > > _simRecords
Sets of parameters of all the simulations to perform.
Definition: basicsimulation.h:147
static vector< string > splitExcludeEnclosedDelimiters(const string &str, const char delim=',', const string &encloser="([{\"")
Splits a string into substrings (tokens) delimited by a single character.
Definition: tstring.h:153
static string replaceChar(const string &str, const char target, const char replacement)
Definition: tstring.h:392
void fatal(const char *str,...)
Definition: output.cc:98
void warning(const char *str,...)
Definition: output.cc:56

References _simRecords, fatal(), tstring::replaceChar(), setFilename(), tstring::splitExcludeEnclosedDelimiters(), and warning().

Referenced by SimRunner::run().

+ Here is the caller graph for this function:

◆ get_allParams()

list<ParamSet*>& ParamManager::get_allParams ( )
inline

Accessor of the whole list of the parameter sets.

Returns
the reference to the list of ParamSet
107  {
108  return _allParams;
109  }

◆ get_firstRecord()

map< string,string >& ParamManager::get_firstRecord ( )
inline

Accessor to the first element in the simulations parameter list.

135 {return (*_simRecords.begin());}

◆ get_nbSims()

int ParamManager::get_nbSims ( )
inline

Accessor to the size of the simulations parameter list, i.e.

the number of simulations to perform.

137 {return _simRecords.size();}

◆ get_paramset()

ParamSet * ParamManager::get_paramset ( string &  name)

Looks for paramset with "name" in the list of parameter sets.

Returns
NULL if parameter set "name" not found
233 {
234  list<ParamSet*>::iterator pset = _allParams.begin();
235 
236  while(pset != _allParams.end()) {
237 
238  if( (*pset)->getName().compare(name) == 0)
239  return (*pset);
240 
241  pset++;
242  }
243 
244  return NULL;
245 }

References _allParams.

Referenced by SimRunner::Replicate_LOOP().

+ Here is the caller graph for this function:

◆ get_simRecords()

list< map< string,string > >& ParamManager::get_simRecords ( )
inline

Accessor to the simulations parameter list.

133 {return _simRecords;}

◆ lowercase()

string ParamManager::lowercase ( string &  input)
private
771 {
772  for(unsigned int i=0;i<input.size();++i)
773  input[i] = tolower(input[i]);
774  return input;
775 }

◆ param_consistency_check()

bool ParamManager::param_consistency_check ( )

Checks if all the mandatory parameters are set so that the simulation can be launched.

Returns
TRUE if all ParamSet::check_consistency() returned true
133 {
134  list<ParamSet*>::iterator current_paramset = _allParams.begin();
135 
136  bool check = true;
137 
138  while(current_paramset != _allParams.end()){
139  if(!(*current_paramset)->check_consistency()){
140  error("ParamManager::param_consistency_check::consistency not satisfied for \"%s\"\n",
141  (*current_paramset)->getName().c_str());
142  check = false;
143  }
144  current_paramset++;
145  }
146  return check;
147 }
int error(const char *str,...)
Definition: output.cc:77

References _allParams, and error().

Referenced by set_parameters().

+ Here is the caller graph for this function:

◆ set_parameters()

bool ParamManager::set_parameters ( map< string, string > &  simparams,
bool  silent 
)

Sets the parameters of the simulation with the argument strings given in input.

Scans the _allParams list to set the parameters present in the input map simparams. Each ParamSet checks internally for the presence of a Param with the given name string and sets its value with the given argument, if present.

Note: all ParamSet owning a Param with the same name will use the same argument string. The input map is not a multimap, each param name is present only once.

Parameters
simparamsa map containing the parameter names and their argument string
silentwill be silent about parameters that could not be set.
Returns
the status of the param_consistency_check() function
152 {
153  _inputParams = simparams;
154  list<ParamSet*>::iterator current_paramset = _allParams.begin();
155  map< string,string >::iterator IT = _inputParams.begin();
156  bool set = false;
157  bool found = false;
158 
159  vector< string > unset;
160  vector< string > notfound;
161 
162  // we try and assign recorded parameters to a paramset
163  while(IT != _inputParams.end()) {
164 
165  current_paramset = _allParams.begin();
166 
167  // go through the list of all paramsets to assign the param to at least one paramset
168  // one parameter can be in multiple paramsets because of inheritance between components
169  while(current_paramset != _allParams.end()){
170 
171  found |= ( (*current_paramset)->find_param((string&)IT->first) != NULL );
172 
173  if(found)
174  set |= (*current_paramset)->set_param((string&)IT->first, IT->second);
175 
176  current_paramset++;
177  }
178 
179  // if not found, add param to list for warnings
180  if(!found){
181 
182  notfound.push_back(IT->first);
183 
184  }
185 
186  // if found but set failed, add param to list for warnings
187  if(found && !set){
188 
189  unset.push_back(IT->first);
190 
191  }
192 
193  // reset the flags
194  found = false;
195  set = false;
196 
197  // move to next input parameter
198  IT++;
199  }
200 
201 
202  if(!silent && _myenv->isMaster()) {
203 
204  if(notfound.size() > 0) {
205 
206  warning(" Orphan parameters!\n>>>> The following parameters do not belong to any simulation component:\n");
207 
208  for(unsigned i = 0; i < notfound.size(); ++i)
209  message(">>>> \"%s\" \n",notfound[i].c_str());
210 
211  message("\n");
212  }
213 
214  if(unset.size() > 0) {
215 
216  error(" Unset parameters!\n>>>> The following parameters could not be set (wrong value):\n");
217 
218  for(unsigned i = 0; i < unset.size(); ++i)
219  message(">>>> \"%s\" \n",unset[i].c_str());
220 
221  fatal("Please check the input parameter file and correct the error.\n");
222  }
223 
224  }
225 
226 
227  return param_consistency_check();
228 }
MPIenv * _myenv
Definition: MPImanager.cc:34
bool isMaster() const
Definition: MPImanager.h:126
map< string, string > _inputParams
A map of the parameters and their arguments of the current (running) simulation.
Definition: basicsimulation.h:143
bool param_consistency_check()
Checks if all the mandatory parameters are set so that the simulation can be launched.
Definition: basicsimulation.cc:132
void message(const char *message,...)
Definition: output.cc:38

References _allParams, _inputParams, _myenv, error(), fatal(), MPIenv::isMaster(), message(), param_consistency_check(), and warning().

Referenced by SimBuilder::build_currentParams().

+ Here is the caller graph for this function:

◆ setArgString()

string ParamManager::setArgString ( string &  fmt,
string &  arg,
unsigned int  arg_pos 
)
private
645 {
646  unsigned int width, digits;
647  double value;
648  bool is_dotless = 0;
649  string out, arg_str;
650  size_t pos = 0;
651 
652  if(fmt.size() != 0) {
653 
654  if(fmt[0] == '[') {
655  // comma-separated form: '[s1,s2,...]' -- no width, variable-length pieces
656  size_t close = fmt.find(']');
657  if(close == string::npos) {
658  error("syntax error in format string for filename parameter:\n");
659  fatal("enclosing ']' was not found\n");
660  }
661  string content = fmt.substr(1, close - 1);
662 
663  // [+] keeps its meaning (position number) but unpadded since no width is given
664  if(content.compare("+") == 0) {
665  ostringstream ostr;
666  ostr << arg_pos + 1;
667  return ostr.str();
668  }
669 
670  vector<string> pieces;
671  size_t start = 0, comma;
672  while((comma = content.find(',', start)) != string::npos) {
673  pieces.push_back(content.substr(start, comma - start));
674  start = comma + 1;
675  }
676  pieces.push_back(content.substr(start));
677 
678  if(arg_pos >= pieces.size()) {
679  fatal("not enough comma-separated substrings in substitution string \"[%s]\": "
680  "got %u, need at least %u for sequential parameter values\n",
681  content.c_str(), (unsigned)pieces.size(), arg_pos + 1);
682  }
683 
684  return pieces[arg_pos];
685  }
686 
687  if(fmt[0] == '.') {
688  is_dotless = true;
689  fmt = fmt.substr(1, string::npos);
690  }
691 
692  if( !isdigit(fmt[0]) ) {
693  error("syntax error in format string for parameter substitution:\n");
694  fatal("first character within \' \' must be a number\n");
695  }
696 
697  width = (unsigned int) strtol(fmt.c_str(), NULL, 10);
698 
699  digits = (unsigned int) log10((double)width) +1;
700 
701  fmt = fmt.substr(digits, string::npos);
702 
703  if(fmt[0] == '[') {
704 
705  if( (pos = fmt.find(']')) == string::npos){
706  error("syntax error in format string for parameter substitution:\n");
707  fatal("enclosing ']' was not found\n");
708  }
709 
710  arg_str = fmt.substr(1, pos-1);
711 
712  // reject mixing the two forms: width digit + comma-separated list
713  if(arg_str.find(',') != string::npos) {
714  error("syntax error in format string for parameter substitution:\n");
715  fatal("comma-separated replacement list \"[%s]\" cannot be combined with a size specifier; "
716  "drop the leading width digit and use \"[%s]\" alone for variable-length pieces.\n",
717  arg_str.c_str(), arg_str.c_str());
718  }
719 
720  if(arg_str[0] == '+') {
721 
722  ostringstream ostr;
723  ostr.width(width);
724  ostr.fill('0');
725  ostr << arg_pos+1;
726 
727  out = ostr.str();
728 
729  } else {
730 
731  if (arg_str.size() < (arg_pos+1)*width) {
732  error("syntax error in format string for parameter substitution:\n");
733  fatal("the number of characters in \"[%s]\" is not sufficient.\n", arg_str.c_str());
734  }
735 
736  for(unsigned int i = 0, start = arg_pos*width; i < width; i++)
737  out += arg_str[start + i];
738  }
739 
740  } else {
741 
742  value = strtod(arg.c_str(), 0);
743 
744  if(is_dotless) {
745  //take the decimal part:
746  double dummy;
747  value = modf(value, &dummy);
748  value *= pow(10.0, (double)width);
749  }
750 
751  ostringstream ostr;
752  ostr.width(width);
753  ostr.fill('0');
754  ostr << value;
755 
756  out = ostr.str();
757  }
758 
759  } else {
760 
761  out = arg;
762 
763  }
764 
765  return out;
766 }

References error(), and fatal().

Referenced by setFilename().

+ Here is the caller graph for this function:

◆ setFilename()

string ParamManager::setFilename ( string &  fstring,
unsigned int  sim,
vector< string > &  args,
vector< unsigned int > &  arg_no,
vector< bool > &  is_linked,
vector< string > &  names,
bool  check_arg_no 
)
private
492 {
493  string out, tail, fmt;
494  string::size_type pos = fstring.find_first_of('%');
495  string::size_type next;
496  unsigned int index, nstr_args = (pos != string::npos ? 1 : 0);
497  bool add_sim_no = false;
498  static bool has_warned = false;
499  static bool has_warned_linked_skip = false;
500 
501  while(pos != string::npos)
502  nstr_args += ( (pos = fstring.find('%', pos+1)) != string::npos);
503 
504  if(check_arg_no && nstr_args < args.size()) {
505 
506  //pre-scan the filename to find which 1-based %N indices are referenced
507  set<unsigned int> referenced;
508  string::size_type scan_pos = fstring.find_first_of('%');
509  while(scan_pos != string::npos) {
510  string scan_tail = fstring.substr(scan_pos + 1, string::npos);
511  unsigned int scan_index = 0;
512  stripFormatString(scan_tail, scan_index);
513  if(scan_index >= 1 && scan_index <= args.size())
514  referenced.insert(scan_index);
515  scan_pos = fstring.find('%', scan_pos + 1);
516  }
517 
518  //count linked vs combinatorial slots, and how many of each are referenced
519  unsigned int n_linked = 0, n_combin = 0;
520  unsigned int referenced_linked = 0, referenced_combin = 0;
521  for(unsigned int k = 0; k < is_linked.size(); ++k) {
522  if(is_linked[k]) {
523  n_linked++;
524  if(referenced.count(k + 1)) referenced_linked++;
525  } else {
526  n_combin++;
527  if(referenced.count(k + 1)) referenced_combin++;
528  }
529  }
530 
531  bool all_combin_covered = (referenced_combin == n_combin);
532  bool any_linked_covered = (referenced_linked >= 1);
533 
534  if(n_linked > 0 && all_combin_covered && any_linked_covered) {
535  //only linked-sequential params are missing from the filename; skip auto-numbering
536  string omitted;
537  for(unsigned int k = 0; k < is_linked.size(); ++k) {
538  if(is_linked[k] && referenced.count(k + 1) == 0) {
539  if(!omitted.empty()) omitted += ", ";
540  omitted += names[k];
541  }
542  }
543  if(!has_warned_linked_skip)
544  warning("linked-sequential param(s) '%s' omitted in filename; filename will not be numbered.\n",
545  omitted.c_str());
546  has_warned_linked_skip = true;
547  } else {
548  if(!has_warned) warning("missing sequential arguments in filename parameter, adding simulation number to filename.\n");
549  has_warned = true;
550  add_sim_no = true;
551  }
552  }
553 
554  pos = fstring.find_first_of('%');
555 
556  if(pos != string::npos) {
557 
558  if(pos > 0) out = fstring.substr(0, pos);
559 
560  tail = fstring.substr(pos+1, string::npos);
561 
562  fmt = stripFormatString(tail, index);
563 
564  if(index > args.size()) fatal("too many sequential arguments in \"%s\"\n",fstring.c_str());
565 
566  out += setArgString(fmt, args[index-1], arg_no[index-1]);
567 
568  next = tail.find_first_of('%');
569 
570  while(next != string::npos){
571 
572  out += tail.substr(0, next);
573 
574  tail = tail.substr(next+1, string::npos);
575 
576  fmt = stripFormatString(tail, index);
577 
578  if(index > args.size()) fatal("too many sequential arguments in \"%s\"\n",fstring.c_str());
579 
580  out += setArgString(fmt, args[index-1], arg_no[index-1]);
581 
582  next = tail.find_first_of('%');
583  }
584 
585  out += tail.substr(0, next);
586 
587  } else
588  out = fstring;
589 
590  if(add_sim_no) {
591 
592  ostringstream ostr;
593  ostr << sim;
594 
595  out += "-" + ostr.str();
596  }
597 
598  return out;
599 }
string setArgString(string &fmt, string &arg, unsigned int arg_pos)
Definition: basicsimulation.cc:644
string stripFormatString(string &str, unsigned int &index)
Definition: basicsimulation.cc:603

References fatal(), setArgString(), stripFormatString(), and warning().

Referenced by build_records().

+ Here is the caller graph for this function:

◆ stripFormatString()

string ParamManager::stripFormatString ( string &  str,
unsigned int &  index 
)
private
604 {
605  string fmt;
606  unsigned int digits;
607  size_t fmt_end;
608 
609  //check for the presence of a format string, enclose by two \'
610  if(str[0] == '\'') {
611 
612  fmt_end = str.find('\'', 1);
613 
614  if(fmt_end == string::npos) fatal("format string not closed in filename parameter\n");
615 
616  fmt = str.substr(1, fmt_end-1);
617 
618  str = str.substr(fmt_end +1, string::npos);
619 
620  } else {
621 
622  // check that the placement character '%' is directly followed by a digit (if not by ' )
623  if( !isdigit(str[0]) ) {
624  error("found a mal-formed format string \"%s\" for parameter substitutions in the input file.\n", str.c_str());
625  fatal("Please check that the placement character \"%%\" is directly followed by the reference number of the sequential parameter, or by a format string starting with a \'.\n");
626  }
627  // no formating string provided
628  fmt = "";
629 
630  }
631 
632  index = (unsigned int) strtol(str.c_str(), NULL, 10);
633 
634  digits = (unsigned int) log10((double)index) +1;
635 
636  str = str.substr(digits, string::npos);
637 
638  return fmt;
639 
640 }

References error(), and fatal().

Referenced by setFilename().

+ Here is the caller graph for this function:

Member Data Documentation

◆ _allParams

list< ParamSet* > ParamManager::_allParams
protected

A list of all the parameter sets of all the simulation components loaded in the _component list of the ComponentManager.

Referenced by build_allParams(), SimBuilder::build_currentParams(), get_paramset(), param_consistency_check(), SimRunner::reset(), and set_parameters().

◆ _inputParams

map< string, string > ParamManager::_inputParams
protected

A map of the parameters and their arguments of the current (running) simulation.

Referenced by set_parameters().

◆ _paramSet

ParamSet ParamManager::_paramSet
protected

◆ _simRecords

list< map< string, string > > ParamManager::_simRecords
protected

Sets of parameters of all the simulations to perform.

Referenced by build_records(), and SimRunner::run().

◆ _temporalParams

map< unsigned int, list < pair< string, string> > > ParamManager::_temporalParams
protected

Lists of parameters to be updated during a simulation indexed by generation update time.


The documentation for this class was generated from the following files:

Generated for Nemo v2.4.2 by  doxygen 1.9.1

Catalogued on GSR