Nemo  2.4.0
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.

99 {
100  _paramSet.setName("simulation");
101  _paramSet.setIsRequired(true);
102  _paramSet.setOwner(NULL);
103  _paramSet.add_param("filename",STR,true,false,0,0);
104  _paramSet.add_param("root_dir",STR,false,false,0,0);
105  _paramSet.add_param("logfile",STR,false,false,0,0);
106  _paramSet.add_param("postexec_script",STR,false,false,0,0);
107  _paramSet.add_param("postexec_args",STR,false,false,0,0);
108  _paramSet.add_param("postexec_replicate_wise", BOOL, 0,0,0,0);
109  _paramSet.add_param("random_seed",INT,false,false,0,0);
110  _paramSet.add_param("replicates",INT,true,false,0,0);
111  _paramSet.add_param("generations",INT,true,false,0,0);
112  _paramSet.add_param("run_mode",STR,false,false,0,0);
113 }
ParamSet _paramSet
The ParamSet param set of the simulation.
Definition: basicsimulation.h:150
void add_param(Param *param)
Adds the param argument to the list.
Definition: param.h:242
void setName(string value)
Sets the container's name.
Definition: param.h:281
void setOwner(SimComponent *owner)
Sets the pointer to the SimComponents that owns this set.
Definition: param.h:285
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:283
@ BOOL
Definition: types.h:77
@ STR
Definition: types.h:77
@ INT
Definition: types.h:77

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

◆ ~ParamManager()

ParamManager::~ParamManager ( )
inline
92 {/*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.

95  {
96  _allParams.push_back(paramset);
97  }
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:142

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.

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

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).

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

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
108  {
109  return _allParams;
110  }

◆ get_firstRecord()

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

Accessor to the first element in the simulations parameter list.

136 {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.

138 {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
234 {
235  list<ParamSet*>::iterator pset = _allParams.begin();
236 
237  while(pset != _allParams.end()) {
238 
239  if( (*pset)->getName().compare(name) == 0)
240  return (*pset);
241 
242  pset++;
243  }
244 
245  return NULL;
246 }

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.

134 {return _simRecords;}

◆ lowercase()

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

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

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

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

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

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

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.0 by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR