Nemo  2.4.0b
Simulate forward-in-time genetic evolution in a spatially explicit, individual-based stochastic simulator
ParamsParser Class Referenceabstract

Provides interface to read input parameters from various sources and parses them. More...

#include <paramsparser.h>

+ Inheritance diagram for ParamsParser:
+ Collaboration diagram for ParamsParser:

Public Member Functions

 ParamsParser (const char *name)
 
virtual ~ParamsParser ()
 
void setName (const char *name)
 
map< string, string > get_inputParams ()
 
map< string, vector< string > > & getParsedParameters (const char *stream_name)
 
map< string, vector< string > > & getParsedParameters ()
 
map< string, string > & getParameters (const char *stream_name)
 
map< string, string > & getParameters ()
 
virtual bool read (const char *stream)=0
 Read/parse params & args from a file or a string or an R object. More...
 
void parse ()
 Builds the _parsedParams from the _inputParams. More...
 
string replaceMacro (const string &arg)
 Macros. More...
 
string parseMacroFunctionBlock (const string &in_arg)
 
string callMacro (const string &name, const string &argstr)
 
vector< string > getMacroArgs (const string &args, const int min_arg, const size_t max_arg, const string macro_name, const string syntax, bool lastArgIsSeparatorChar=true)
 
string getMacroSepParamChar (const string &sep_in, const string macro_name)
 
string getMacroParamValue (const string &str_in, const string &par_name, const string &macro_name)
 
string quote (const string &argstr)
 Macro "q" returns a quoted string. More...
 
string concat (const string &argstr)
 Macro "c" returns a character-delimited string of atomic arguments. More...
 
string rep (const string &argstr)
 
string seq (const string &argstr)
 
string tempseq (const string &argstr)
 
string matrix (const string &argstr)
 
string diag_matrix (const string &argstr)
 
string sym_matrix (const string &argstr)
 
string runif (const string &argstr)
 
string rnorm (const string &argstr)
 
string rpoiss (const string &argstr)
 
string rbernoul (const string &argstr)
 
string rgamma (const string &argstr)
 
string rlognorm (const string &argstr)
 
string rexp (const string &argstr)
 

Static Public Member Functions

static void getBlockArgument (istream &IN, char &c, string &arg)
 
static void getArguments (string &arg_str, vector< string > &arg_vect)
 

Protected Member Functions

void reset_inputParams ()
 
void add_inputParam (string &param, const string &arg)
 

Private Attributes

const char * _sname
 Attached file of stream name. More...
 
map< string, string > _inputParams
 The whole, unparsed set of input parameters. More...
 
map< string, vector< string > > _parsedParams
 The parsed set of simulation parameters after sequential parameters have been separated. More...
 
map< string, string(ParamsParser::*)(const string &)> _macroMap
 The macro table, mapping call name to caller. More...
 

Detailed Description

Provides interface to read input parameters from various sources and parses them.

Constructor & Destructor Documentation

◆ ParamsParser()

ParamsParser::ParamsParser ( const char *  name)
58 {
59  _sname = name;
60 
61  _macroMap["rep"] = &ParamsParser::rep;
62  _macroMap["seq"] = &ParamsParser::seq;
63  _macroMap["tempseq"] = &ParamsParser::tempseq;
66  _macroMap["runif"] = &ParamsParser::runif;
67  _macroMap["rnorm"] = &ParamsParser::rnorm;
68  _macroMap["rpois"] = &ParamsParser::rpoiss;
69  _macroMap["rlognorm"] = &ParamsParser::rlognorm;
70  _macroMap["rgamma"] = &ParamsParser::rgamma;
71  _macroMap["rbernoul"] = &ParamsParser::rbernoul;
72  _macroMap["rexp"] = &ParamsParser::rexp;
73  _macroMap["matrix"] = &ParamsParser::matrix;
75  _macroMap["smatrix"] = &ParamsParser::sym_matrix;
76 }
string rexp(const string &argstr)
Definition: paramsparser.cc:1212
string rlognorm(const string &argstr)
Definition: paramsparser.cc:1347
string tempseq(const string &argstr)
Definition: paramsparser.cc:673
string rnorm(const string &argstr)
Definition: paramsparser.cc:1020
string matrix(const string &argstr)
Definition: paramsparser.cc:739
const char * _sname
Attached file of stream name.
Definition: paramsparser.h:106
string sym_matrix(const string &argstr)
Definition: paramsparser.cc:852
string concat(const string &argstr)
Macro "c" returns a character-delimited string of atomic arguments.
Definition: paramsparser.cc:485
map< string, string(ParamsParser::*)(const string &)> _macroMap
The macro table, mapping call name to caller.
Definition: paramsparser.h:115
string rbernoul(const string &argstr)
Definition: paramsparser.cc:1153
string seq(const string &argstr)
Definition: paramsparser.cc:611
string runif(const string &argstr)
Definition: paramsparser.cc:943
string quote(const string &argstr)
Macro "q" returns a quoted string.
Definition: paramsparser.cc:512
string rep(const string &argstr)
Definition: paramsparser.cc:537
string rpoiss(const string &argstr)
Definition: paramsparser.cc:1094
string rgamma(const string &argstr)
Definition: paramsparser.cc:1271
string diag_matrix(const string &argstr)
Definition: paramsparser.cc:785

References concat(), diag_matrix(), matrix(), quote(), rbernoul(), rep(), rexp(), rgamma(), rlognorm(), rnorm(), rpoiss(), runif(), seq(), sym_matrix(), and tempseq().

◆ ~ParamsParser()

virtual ParamsParser::~ParamsParser ( )
inlinevirtual
55 {}

Member Function Documentation

◆ add_inputParam()

void ParamsParser::add_inputParam ( string &  param,
const string &  arg 
)
inlineprotected
102 {_inputParams[param] = arg;}
map< string, string > _inputParams
The whole, unparsed set of input parameters.
Definition: paramsparser.h:109

Referenced by StreamParser::read().

◆ callMacro()

string ParamsParser::callMacro ( const string &  name,
const string &  argstr 
)
364 {
365  string out;
366 #ifdef _DEBUG_
367  message(" ^^^^ calling macro: %s(%s)\n",name.c_str(), argstr.c_str());
368 #endif
369 
370  auto elmnt = _macroMap.find(name);
371 
372  if( elmnt == _macroMap.end())
373  {
374  fatal("macro \"%s(%s)\" could not be mapped to a known function.\n", name.c_str(), argstr.c_str());
375  }
376 
377  out = (this->*(elmnt->second))(argstr);
378 
379 #ifdef _DEBUG_
380  message(" ^^^^ returning: %s\n",out.c_str());
381 #endif
382 
383  return out;
384 }
void fatal(const char *str,...)
Definition: output.cc:96
void message(const char *message,...)
Definition: output.cc:40

References fatal(), and message().

◆ concat()

string ParamsParser::concat ( const string &  argstr)

Macro "c" returns a character-delimited string of atomic arguments.

Can be passed as arguments to other macros.

486 {
487 
488  string syntax="c(... , sep=\",\")";
489  string out;
490 
491  size_t max_arg = INT64_MAX;
492 
493  vector<string> macro_args = getMacroArgs(argstr, 2, max_arg, "c", syntax, true);
494 
495  string sep = macro_args.back();
496 
497  int last = macro_args.size() - 2; //omit separator at last position
498 
499  // stick each element together, un-quoting them, if needed
500  for (int i = 0; i < last; ++i) {
501  out += tstring::removeEnclosingChar(macro_args[i], '"', '"', true) + sep;
502  }
503  // add last element without separator
504  out += tstring::removeEnclosingChar(macro_args[last], '"', '"', true);
505 
506 
507  return out;
508 }
vector< string > getMacroArgs(const string &args, const int min_arg, const size_t max_arg, const string macro_name, const string syntax, bool lastArgIsSeparatorChar=true)
Definition: paramsparser.cc:388
static string removeEnclosingChar(const string &str, const char o, const char c, bool allowMissing=false)
Removes characters enclosing a string.
Definition: tstring.h:356

References tstring::removeEnclosingChar().

Referenced by ParamsParser().

◆ diag_matrix()

string ParamsParser::diag_matrix ( const string &  argstr)
786 {
787  string syntax = "diag(x, n)";
788 
789  int max_arg = 2, min_arg = 1;
790  string out;
791  string off_diag = "0";
792  size_t nrow;
793 
794  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "diag", syntax, false);
795 
796  // the size is inferred from splitting the string provided
797  vector<string> elmnts = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', true), ',');
798 
799  if( macro_args.size() == 1) {
800 
801  nrow = elmnts.size();
802 
803  } else {
804  // already checked that it's not >2 arguments passed
805 
806  nrow = size_t(tstring::str2uint(macro_args[1]));
807 
808  // the value may contain several elements that might need to be repeated:
809  if(elmnts.size() > 1 && elmnts.size() != nrow) {
810 
811  fatal("diag(): the number of elements to use for the diag matrix is different from parameter \"n\" in: diag(%s)\n\
812  use quoted rep() if you intend to repeat a pattern, eg: diag(q(rep(..., n1)),n2)\n", syntax.c_str());
813 
814  } else if (elmnts.size() == 1){
815 
816  // build the vector of elements used below
817 
818  for(unsigned int i = 0; i < nrow-1; ++i)
819  elmnts.push_back(elmnts[0]);
820  }
821  }
822 
823  out += "{";
824 
825  for (unsigned int r = 0, c, e = 0; r < nrow; ++r) {
826 
827  out += "\n{";
828 
829  for (c = 0; c < nrow - 1 && e < elmnts.size(); ++c) {
830 
831  if(c == r)
832  out += elmnts[e++] + ",";
833  else
834  out += off_diag + ",";
835  }
836 
837  if(c == r)
838  out += elmnts[e++] + "}";
839  else
840  out += off_diag + "}";
841 
842  }
843 
844  // close the matrix block
845  out += "}";
846 
847  return out;
848 }
static vector< string > split(const string &str, const char delim, bool splitOnce=false)
splits a string into substrings (tokens) delimited by a single character.
Definition: tstring.h:128
static unsigned int str2uint(const string &str)
Converts a string into an unsigned integer.
Definition: tstring.h:51

References fatal(), tstring::removeEnclosingChar(), tstring::split(), and tstring::str2uint().

Referenced by ParamsParser().

◆ get_inputParams()

map< string, string > ParamsParser::get_inputParams ( )
inline
59 {return _inputParams;}

◆ getArguments()

void ParamsParser::getArguments ( string &  arg_str,
vector< string > &  arg_vect 
)
static
174 {
175  istringstream IN;
176  string arg;
177  int dummy_line = 0;
178  char c;
179 
180  IN.str(arg_str);
181 
182  while(IN.get(c) && IN.good() && !IN.eof()){
183 
184  if(isspace(c)) {
185  StreamParser::removeSpaceAndComment(IN, dummy_line);
186  continue;
187  }
188 
189  if(c == '{' || c == '(' || c == '[' || c == '\"')
190  {
191  getBlockArgument(IN, c, arg); //because it may span more than one line
192  }
193  else //not a block argument
194  {
195  IN.putback(c);
196  IN>>arg; //this stops if a whitespace is found, thus not including macro arguments if a macro
197  }
198 
199 
200  arg_vect.push_back( arg );
201  }
202 }
static void getBlockArgument(istream &IN, char &c, string &arg)
Definition: paramsparser.cc:206
static bool removeSpaceAndComment(istream &IN, int &l_count, bool keepLast=false)
Removes whitespace char on a line until a non-ws or EOL is reached.
Definition: paramsparser.cc:1518

References StreamParser::removeSpaceAndComment().

◆ getBlockArgument()

void ParamsParser::getBlockArgument ( istream &  IN,
char &  c,
string &  arg 
)
static
207 {
208  char e = 0;
209  int dummy_line = 0;
210 
211  switch (start_c) {
212  case '{': e = '}';
213  break;
214  case '(': e = ')';
215  break;
216  case '[': e = ']';
217  break;
218  case '\"': e = '\"';
219  break;
220  default:
221  break;
222  }
223 
224  arg = StreamParser::readUntilCharacter(IN, dummy_line, start_c, (const char)e);
225 
226 // cout<<"added arg to vector: "<<out<<" next char='"<<IN.peek()<<"'\n";
227 }
static string readUntilCharacter(istream &IN, int &l_count, const char start_c, const char end_c)
Definition: paramsparser.cc:1668

References StreamParser::readUntilCharacter().

◆ getMacroArgs()

vector< string > ParamsParser::getMacroArgs ( const string &  args,
const int  min_arg,
const size_t  max_arg,
const string  macro_name,
const string  syntax,
bool  lastArgIsSeparatorChar = true 
)
390 {
391 
392 // cout<<" getMacroArgs:: argstr="<<argstr<<endl;
393 
394  vector<string> macro_args = tstring::splitExcludeEnclosedDelimiters(argstr, ',');
395 
396  if(macro_args.size() > max_arg ){
397  fatal("macro \"%s\" can have max %i arguments: %s\n", macro_name.c_str(), max_arg, syntax.c_str());
398  }
399  else if (macro_args.size() < min_arg) {
400  fatal("macro \"%s\" must have at least %i arguments: %s\n", macro_name.c_str(), min_arg, syntax.c_str());
401  }
402 
403  size_t last_arg = macro_args.size() -1;
404 
405  string sep = ","; // default sep
406 
407  // treat the last argument specially if it is a separator char
408  // or add the default separator char to the arg vector if not specified in input
409  if(lastArgIsSeparatorChar) {
410 
411  // make sure it was specified in input
412  if(macro_args.size() > min_arg) {
413  // check if separator is given in arg (we'll assume it is the last arg...)
414  if(argstr.rfind("sep") != string::npos) {
415 
416  // get the separator char from the last character string
417  sep = getMacroSepParamChar(macro_args[ last_arg ], macro_name);
418 
419  macro_args[ last_arg ] = sep; // we replace the string "sep=..." with the char
420 
421  } else
422  macro_args.push_back(sep); //default
423  } else
424  macro_args.push_back(sep); //default
425  }
426 
427 // auto print = [this](const string& s){cout<<" getMacroArgs:: "<<s<<endl;};
428 //
429 // for_each(macro_args.cbegin(), macro_args.cend(), print);
430 
431  return macro_args;
432 }
string getMacroSepParamChar(const string &sep_in, const string macro_name)
Definition: paramsparser.cc:436
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:155

References fatal(), and tstring::splitExcludeEnclosedDelimiters().

◆ getMacroParamValue()

string ParamsParser::getMacroParamValue ( const string &  str_in,
const string &  par_name,
const string &  macro_name 
)
474 {
475  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(str_in, '=');
476 
477  if(param_args[0] != par_name)
478  fatal("expected \"%s\" as input param to macro \"%s\", received \"%s\"\n", par_name.c_str(), macro_name.c_str(), str_in.c_str());
479 
480  return param_args[1];
481 }

References fatal(), and tstring::splitExcludeEnclosedDelimiters().

◆ getMacroSepParamChar()

string ParamsParser::getMacroSepParamChar ( const string &  sep_in,
const string  macro_name 
)
437 {
438 
439  if( tstring::isanumber(sep_in))
440  fatal("last argument \"sep\" of macro \"%s\" must be a character string in \"%s\"\n", macro_name.c_str(), sep_in.c_str());
441 
442  vector<string> sep_args = tstring::splitExcludeEnclosedDelimiters(sep_in, '=');
443 
444  string sep;
445 
446  // check format of sep argument specification: sep="c", or "c"
447  if(sep_args.size() == 0)
448  fatal("wrong format of \"sep\" argument to macro \"%s\" in \"%s\"\n", macro_name.c_str(), sep_in.c_str());
449 
450  if(sep_args[0] == "sep") {
451 
452  if(sep_args.size() > 2){
453  fatal("argument \"sep\" of macro \"%s\" must receive only one value in \"%s\" \n", macro_name.c_str(), sep_in.c_str());
454  }
455 
456  sep = sep_args[1];
457 
458  } else {
459  sep = sep_args[0];
460  }
461 
462  if(sep[0] != '"') {
463  fatal("argument to \"sep\" of macro \"%s\" must be enclosed with two \" in \"%s\" \n", macro_name.c_str(), sep_in.c_str());
464  }
465 
466  sep = tstring::removeEnclosingChar(sep, '"', '"');
467 
468  return sep;
469 }
static bool isanumber(const string &str)
Check whether the string is a number.
Definition: tstring.h:410

References fatal(), tstring::isanumber(), tstring::removeEnclosingChar(), and tstring::splitExcludeEnclosedDelimiters().

◆ getParameters() [1/2]

map< string, string >& ParamsParser::getParameters ( )
inline
63 {return _inputParams;}

◆ getParameters() [2/2]

map< string, string > & ParamsParser::getParameters ( const char *  stream_name)
81 {
82 #ifdef _DEBUG_
83  cout<<"ParamsParser::getParameters:"<<endl;
84 #endif
85  if(stream_name == NULL) {
86 
87  if(_sname == NULL)
88 
89  fatal("ParamsParser::getParameters::no stream attached to the parser!\n");
90 
91  else if( !(read(_sname)) ) // read the input text stream and extract parameters and their arguments
92 
93  fatal("ParamsParser::getParameters::failed from file \"%s\"\n",_sname);
94 
95  } else if( !(read(stream_name)) ) // read the input text stream and extract parameters and their arguments
96 
97  fatal("ParamsParser::getParameters::failed from file \"%s\"\n",stream_name);
98 
99  if(stream_name != NULL) _sname = stream_name;
100 
101  // pairs of parameter name & values have been recorder in _inputParams map
102  return _inputParams;
103 }
virtual bool read(const char *stream)=0
Read/parse params & args from a file or a string or an R object.

References fatal().

Referenced by BinaryDataLoader::extractPop().

◆ getParsedParameters() [1/2]

map< string, vector< string > >& ParamsParser::getParsedParameters ( )
inline
61 {return _parsedParams;}
map< string, vector< string > > _parsedParams
The parsed set of simulation parameters after sequential parameters have been separated.
Definition: paramsparser.h:112

◆ getParsedParameters() [2/2]

map< string, vector< string > > & ParamsParser::getParsedParameters ( const char *  stream_name)
108 {
109 #ifdef _DEBUG_
110  cout<<"ParamsParser::getParsedParameters:"<<endl;
111 #endif
112  // read the input parameters from the input text stream
113  getParameters(stream_name);
114 
115  // parse the input text stream
116  parse();
117 
118  return _parsedParams;
119 }
map< string, string > & getParameters()
Definition: paramsparser.h:63
void parse()
Builds the _parsedParams from the _inputParams.
Definition: paramsparser.cc:123

Referenced by SimRunner::run().

◆ matrix()

string ParamsParser::matrix ( const string &  argstr)
740 {
741  string syntax = "matrix(x, nrow, ncol)";
742 
743  int max_arg = 3, min_arg = 3;
744 
745  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "matrix", syntax, false);
746 
747  if(macro_args[0][0] != '"' && macro_args[0].back() != '"')
748  fatal("matrix(): first argument must be quoted with \" in: matrix(%s)\n",argstr.c_str());
749 
750  vector<string> elmnts = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', false), ',');
751 
752  unsigned int nrow = tstring::str2uint(macro_args[1]);
753  unsigned int ncol = tstring::str2uint(macro_args[2]);
754 
755  if(elmnts.size() < nrow*ncol)
756  fatal("matrix(): not enough elements provided, got %i, must be rows*columns = %i\n", elmnts.size(), nrow*ncol);
757 
758  if(elmnts.size() > nrow*ncol)
759  fatal("matrix(): too many elements provided, got %i, must be rows*columns = %i\n", elmnts.size(), nrow*ncol);
760 
761  // start writing the matrix into the output string
762  string out("{");
763 
764  for (unsigned int r = 0, e = 0; r < nrow; ++r) {
765 
766  out += "\n{";
767 
768  for (unsigned int c = 0; c < ncol - 1 && e < elmnts.size(); ++c, ++e) {
769 
770  out += elmnts[e] + ",";
771  }
772 
773  out += elmnts[e++] + "}";
774 
775  }
776 
777  // close the matrix block
778  out += "}";
779 
780  return out;
781 }

References fatal(), tstring::removeEnclosingChar(), tstring::split(), and tstring::str2uint().

Referenced by ParamsParser().

◆ parse()

void ParamsParser::parse ( )

Builds the _parsedParams from the _inputParams.

This defines rules of sequential, matricial params, etc.

124 {
125 #ifdef _DEBUG_
126  cout<<"ParamsParser::parse:"<<endl;
127 #endif
128 
129  // empty container map of parameters parsed into key - value(s) pairs
130  _parsedParams.clear();
131 
132  // local holder of the arguments read in the input stream, contains whole lines from input
133  vector< string > argvect;
134  string arg;
135 
136  // go through all parameters previously read in the input text stream and parse param values into multiple values
137  map<string, string>::iterator param = _inputParams.begin();
138 
139  while(param != _inputParams.end()) {
140 
141  // first, check and replace macros:
142  param->second = replaceMacro(param->second);
143 
144  argvect.clear();
145 
146  if((param->first == "stats") || (param->first == "stat") )
147 
148  argvect.push_back(param->second); //this one cannot be a sequential parameter
149 
150  else { //other params:
151 
152  getArguments(param->second, argvect);
153 
154  }
155 
156  _parsedParams[param->first] = argvect;
157 
158 #ifdef _DEBUG_
159  message(" %s (", param->first.c_str());
160  unsigned int nb=argvect.size() ;
161  for(unsigned int i=0 ;i<nb; ++i){
162  cout<<argvect[i]<<" ";
163  }
164  message("| %i args)\n", nb);
165 #endif
166 
167  param++;
168  }
169 }
string replaceMacro(const string &arg)
Macros.
Definition: paramsparser.cc:231
static void getArguments(string &arg_str, vector< string > &arg_vect)
Definition: paramsparser.cc:173

References message().

◆ parseMacroFunctionBlock()

string ParamsParser::parseMacroFunctionBlock ( const string &  in_arg)
258 {
259  string front, tail, rest, out_arg;
260  string name;
261 
262 // cout<<"parseMacroFunctionBlock <"<< in_arg <<">\n";
263 
264  size_t opar_pos, cpar_pos, first_macro_ch;
265 
266  // extract the name of the macro, first find the opening parenthesis
267  opar_pos = in_arg.find_first_of('(', 1);
268 
269  //cut the string at the opening par to look for the macro name in the front part
270  front = in_arg.substr(0, opar_pos);
271 
272  //cut the string after the opening par to look for macro arguments and more macros in the rest
273  rest = in_arg.substr(opar_pos+1, in_arg.size() - opar_pos - 1);
274 
275  //a macro name can only start after the last delimiter in front of it
276  first_macro_ch = front.find_last_of("(){}[], =\t");
277  // '=' is included because arguments to macros can be named and assigned a call to a nested macro
278  // eg: tempseq(at=seq(),seq=seq())
279 
280  //the open par may not be part of a macro, or there might not be any delim in front, check this:
281  if(first_macro_ch == string::npos)
282  first_macro_ch = 0; // no delim before name, start at first pos in string
283  else
284  first_macro_ch++; //skip the last delimiter
285 
286  // check if we have a macro name in front and extract it
287  if(opar_pos > first_macro_ch)
288  {
289  name = in_arg.substr(first_macro_ch, opar_pos - first_macro_ch);
290  // keep what was in front of the macro name;
291  front = in_arg.substr(0, first_macro_ch);
292  }
293  else // first_macro_ch == opar_pos; no name, no macro, skip
294  { // this corresponds to cases where multiple blocks are provided in input:
295  // param_name (... macro1(...),...) (... macro2(...), ...)
296  // the second block causes problems if we lose the brackets on the way
297 
298  name = "";
299 
300  // keep what was in front of the false macro block, including the opening '(';
301  front = in_arg.substr(0, first_macro_ch+1);
302  }
303 
304  out_arg += front;
305 
306  // before reading the arguments of the macro function call, check for nested macros, recursively
307  if(rest.find_first_of('(', 1) != string::npos)
308  {
309  //recursion
310  //replace the macro name by the result of the call to the nested macro in the macro_args vect
311  rest = ( parseMacroFunctionBlock(rest) );
312 
313  }
314  //no more nested block, close recursion and return arguments
315 
316 // cout<< " processing: "<<rest<<endl;
317 
318  // find the limit of the macro args
319  cpar_pos = rest.find_first_of(')');
320 
321  if ( cpar_pos != string::npos)
322  {
323  // record what is left after the macro args, excluding the closing macro ')'
324  if( cpar_pos < rest.size()-1 ){
325 
326  tail = rest.substr(cpar_pos+1, rest.size() - cpar_pos - 1);
327  }
328  else
329  tail = "";
330  }
331  else
332  {
333  fatal("Error while parsing argument string \"%s\" for macros, closing bracket not found\n", (rest+tail).c_str());
334  }
335 
336  rest = rest.substr(0, cpar_pos); // this is the string containing the args to the macro
337 
338  if(name == "")
339  {
340 
341 // cout<< " not calling macro: name =\"\"; arg string is <"<<rest<<">"<<"\n";
342 
343  out_arg += rest +")" + tail; //need to put back the closing ')' because not a macro
344 
345  }
346  else
347  {
348 
349 // cout<< " calling macro: "<<name<<"("<<rest<<")"<<"\n";
350 
351  // call the macro and paste the result into the output string
352  out_arg += callMacro(name, rest) + tail;
353 
354  }
355 
356 // cout<< " returning "<<out_arg<<endl;
357  // return the processed string
358  return out_arg;
359 }
string parseMacroFunctionBlock(const string &in_arg)
Definition: paramsparser.cc:257
string callMacro(const string &name, const string &argstr)
Definition: paramsparser.cc:363

References fatal().

◆ quote()

string ParamsParser::quote ( const string &  argstr)

Macro "q" returns a quoted string.

Useful to quote result of call to enclosed macro.

513 {
514 
515  string syntax="q(... , sep=\",\")";
516  string out;
517 
518  size_t max_arg = INT64_MAX;
519 
520  vector<string> macro_args = getMacroArgs(argstr, 1, max_arg, "q", syntax, true);
521 
522  string sep = macro_args.back();
523 
524  int last = macro_args.size() - 2; //omit separator at last position
525 
526  for (int i = 0; i < last; ++i) {
527  out += macro_args[i] + sep;
528  }
529  // add last element without separator
530  out += macro_args[last];
531 
532  return "\"" + out + "\"";
533 }

Referenced by ParamsParser().

◆ rbernoul()

string ParamsParser::rbernoul ( const string &  argstr)
1154 {
1155  string syntax = "rbernoul(n, p=0.5, sep=\",\")";
1156 
1157  int max_arg = 3, min_arg = 1;
1158  double p = 0.5;
1159  unsigned int num_deviates;
1160 
1161  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rbernoul", syntax, true);
1162 
1163  // get and check the number of deviates we need to draw
1164  if(!tstring::isanumber(macro_args[0]))
1165  fatal("rbernoul(): first argument must be a positive integer in: rbernoul(%s)\n", argstr.c_str());
1166 
1167  num_deviates = tstring::str2uint(macro_args[0]);
1168 
1169  if(!(num_deviates > 0))
1170  fatal("rbernoul(): first argument must be a positive integer in: rbernoul(%s)\n", argstr.c_str());
1171 
1172 
1173  // get the mean value, if present
1174  // we omit last arg macro_args[2] which is always the separator character
1175  if(macro_args.size() == 3){
1176 
1177  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1178 
1179  if(param_args[0] == "p") {
1180 
1181  p = tstring::str2dble(param_args[1]);
1182 
1183  } else if(param_args.size() == 1) {
1184 
1185  // the string "mean=" can be omitted by user
1186 
1187  p = tstring::str2dble(param_args[0]);
1188 
1189  } else {
1190 
1191  fatal("rbernoul() syntax is: %s\n",syntax.c_str());
1192  }
1193  }
1194 
1195  string sep = macro_args.back();
1196 
1197  // compute the random deviates
1198  string out;
1199 
1200  auto draw = [p](){return tstring::int2str(RAND::Bernoulli(p));};
1201 
1202  for(unsigned int i = 0; i < num_deviates -1; ++i)
1203  out += draw() + sep;
1204 
1205  out += draw();
1206 
1207  return out;
1208 }
static double Bernoulli(double p)
Definition: Uniform.h:429
static double str2dble(const string &str)
Converts a string into a double.
Definition: tstring.h:84
static string int2str(const int i)
Writes an integer value into a string.
Definition: tstring.h:95

References RAND::Bernoulli(), fatal(), tstring::int2str(), tstring::isanumber(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ read()

virtual bool ParamsParser::read ( const char *  stream)
pure virtual

Read/parse params & args from a file or a string or an R object.

Params and their args are put in the _inputParams.

Implemented in StreamParser, BinaryFileParser, and FileParser.

◆ rep()

string ParamsParser::rep ( const string &  argstr)
538 {
539 
540  string syntax="rep(x, n, each=1, sep=\",\")";
541 
542  int max_arg = 4;
543 
544  vector<string> macro_args = getMacroArgs(argstr, 2, max_arg, "rep", syntax, true);
545 
546 // auto print = [this](const string& s){cout<<" "<<s<<endl;};
547 //
548 // for_each(macro_args.cbegin(), macro_args.cend(), print);
549 
550  auto num_args = macro_args.size();
551 
552  // ---- get the string to repeat ----
553  string what = macro_args[0];
554 
555  //removing enclosing "" if added:
556  what = tstring::removeEnclosingChar(what, '"', '"', true);
557 
558  // ---- the second argument is the number of repetition ----
559  if ( !tstring::isanumber(macro_args[1]) ) {
560  fatal("rep(): second argument must be a number in: rep(x, n, each=1, sep=\",\")\n");
561  }
562 
563  int num = tstring::str2int(macro_args[1]);
564 
565  // ---- looking for the "each" argument ----
566  auto has_each = [] (const string& s) {return (s.find("each") != string::npos);};
567 
568  auto argPos = find_if(macro_args.begin(), macro_args.end(), has_each);
569 
570  string arg;
571 
572  if( argPos != macro_args.end() )
573  arg = getMacroParamValue(*argPos, "each", syntax);
574  else
575  arg = "1"; // default value if argument is absent, mean "each" must be named
576 
577  int each = tstring::str2int(arg);
578 
579  // the separator char has been set at the back by default
580  string sep;
581 
582  sep = macro_args[num_args-1];
583 
584 
585  // processing the input in case where "each" has been specified
586  vector<string> elmnts;
587 
588  if(argPos != macro_args.end())
589  elmnts = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', true), ',');
590  else
591  elmnts.push_back(what);
592 
593  string out;
594 
595  for(int i = 0; i < num; ++i) {
596  for(auto e = 0; e < elmnts.size(); ++e) {
597  for(int j = 0; j < each; ++j) {
598  out += elmnts[e] + sep;
599  }
600  }
601  }
602  // remove last separator, only if more than one element was concatenated
603  if(sep == ",")
604  out = tstring::removeLastCharOf(out, ',');
605 
606  return out;
607 }
string getMacroParamValue(const string &str_in, const string &par_name, const string &macro_name)
Definition: paramsparser.cc:473
static int str2int(const string &str)
Converts a string into an integer.
Definition: tstring.h:73
static string removeLastCharOf(const string &str, const char c)
Removes the last of a character found in a string.
Definition: tstring.h:337

References fatal(), tstring::isanumber(), tstring::removeEnclosingChar(), tstring::removeLastCharOf(), tstring::split(), and tstring::str2int().

Referenced by ParamsParser().

◆ replaceMacro()

string ParamsParser::replaceMacro ( const string &  arg)

Macros.

232 {
233  // we now need to check if a macro is part of the argument string
234  // this is detected if the arg string holds a "(" as in "macro_name( "
235  // or "(" is within the whole string as in "macro_name(arg1"
236  // or "(" is within a block argument, we skip the first char to account for that last case
237 
238  string out_arg;
239 
240  if( arg.find_first_of('(', 1) != string::npos )
241  {
242  // there might be a macro, get it
243 
244  out_arg = parseMacroFunctionBlock(arg);
245 
246  }
247  else // no macro
248  {
249  out_arg = arg;
250  }
251 
252  return out_arg;
253 }

◆ reset_inputParams()

void ParamsParser::reset_inputParams ( )
inlineprotected
101 {_inputParams.clear();}

Referenced by StreamParser::read().

◆ rexp()

string ParamsParser::rexp ( const string &  argstr)
1213 {
1214  string syntax = "rexp(n, mean=1, sep=\",\")";
1215 
1216  int max_arg = 3, min_arg = 1;
1217  double mean=1.0;
1218  unsigned int num_deviates;
1219 
1220  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rexp", syntax, true);
1221 
1222  // get and check the number of deviates we need to draw
1223  if(!tstring::isanumber(macro_args[0]))
1224  fatal("rexp(): first argument must be a positive integer in: rexp(%s)\n", argstr.c_str());
1225 
1226  num_deviates = tstring::str2uint(macro_args[0]);
1227 
1228  if(!(num_deviates > 0))
1229  fatal("rexp(): first argument must be a positive integer in: rexp(%s)\n", argstr.c_str());
1230 
1231 
1232  // get the mean value, if present
1233  // we omit last arg macro_args[2] which is always the separator character
1234  if(macro_args.size() == 3){
1235 
1236  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1237 
1238  if(param_args[0] == "mean") {
1239 
1240  mean = tstring::str2dble(param_args[1]);
1241 
1242  } else if(param_args.size() == 1) {
1243 
1244  // the string "mean=" can be omitted by user
1245 
1246  mean = tstring::str2dble(param_args[0]);
1247 
1248  } else {
1249 
1250  fatal("rexp() syntax is: %s\n",syntax.c_str());
1251  }
1252  }
1253 
1254  string sep = macro_args.back();
1255 
1256  // compute the random deviates
1257  string out;
1258 
1259  auto draw = [mean](){return tstring::dble2str(RAND::Exponential(mean));};
1260 
1261  for(unsigned int i = 0; i < num_deviates -1; ++i)
1262  out += draw() + sep;
1263 
1264  out += draw();
1265 
1266  return out;
1267 }
static double Exponential(double mu)
Definition: Uniform.h:447
static string dble2str(const double d)
Writes a floating-point value into a string.
Definition: tstring.h:115

References tstring::dble2str(), RAND::Exponential(), fatal(), tstring::isanumber(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ rgamma()

string ParamsParser::rgamma ( const string &  argstr)
1272 {
1273  string syntax = "rgamma(n, a, b, sep=\",\")";
1274 
1275  // a and b params are mandatory, with no default
1276 
1277  int max_arg = 4, min_arg = 3;
1278  double a = 0.0, b = 1.0;
1279  unsigned int num_deviates;
1280 
1281  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rgamma", syntax, true);
1282 
1283  // get and check the number of deviates we need to draw
1284  if(!tstring::isanumber(macro_args[0]))
1285  fatal("rgamma(): first argument must be a positive integer in: rgamma(%s)\n", argstr.c_str());
1286 
1287  num_deviates = tstring::str2uint(macro_args[0]);
1288 
1289  if(!(num_deviates > 0))
1290  fatal("rgamma(): first argument must be a positive integer in: rgamma(%s)\n", argstr.c_str());
1291 
1292 
1293  // omit last arg which is always the separator character
1294 
1295  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1296 
1297  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1298 
1299  if(param_args[0] == "a") {
1300 
1301  a = tstring::str2dble(param_args[1]);
1302 
1303  } else if(param_args[0] == "b") {
1304 
1305  b = tstring::str2dble(param_args[1]);
1306 
1307  } else if(param_args.size() == 1) {
1308 
1309  // the strings "a=" or "b=" can be omitted by the user
1310  // we assume meaning by position
1311 
1312  if(i == 1)
1313  a = tstring::str2dble(param_args[0]);
1314  else if (i == 2)
1315  b = tstring::str2dble(param_args[0]);
1316 
1317  } else {
1318 
1319  fatal("rgamma() syntax is: %s.\n",syntax.c_str());
1320  }
1321  }
1322 
1323  if(a < 0)
1324  fatal("rgamma(): shape parameter \"a\" must be positive in %s.\n",syntax.c_str());
1325 
1326  if(b < 0)
1327  fatal("rgamma(): rate parameter \"b\" must be positive in %s.\n",syntax.c_str());
1328 
1329 
1330  string sep = macro_args.back();
1331 
1332  // compute the random deviates
1333  string out;
1334 
1335  auto draw = [a, b](){return tstring::dble2str(RAND::Gamma(a,b));};
1336 
1337  for(unsigned int i = 0; i < num_deviates -1; ++i)
1338  out += draw() + sep;
1339 
1340  out += draw();
1341 
1342  return out;
1343 }
static double Gamma(double a, double b)
Definition: Uniform.h:385

References tstring::dble2str(), fatal(), RAND::Gamma(), tstring::isanumber(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ rlognorm()

string ParamsParser::rlognorm ( const string &  argstr)
1348 {
1349  string syntax = "rlognorm(n, mean, sd, sep=\",\")";
1350 
1351  // a and b params are mandatory, with no default
1352 
1353  int max_arg = 4, min_arg = 3;
1354  double a = 0.0, b = 1.0;
1355  unsigned int num_deviates;
1356 
1357  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rlognorm", syntax, true);
1358 
1359  // get and check the number of deviates we need to draw
1360  if(!tstring::isanumber(macro_args[0]))
1361  fatal("rlognorm(): first argument must be a positive integer in: rlognorm(%s)\n", argstr.c_str());
1362 
1363  num_deviates = tstring::str2uint(macro_args[0]);
1364 
1365  if(!(num_deviates > 0))
1366  fatal("rlognorm(): first argument must be a positive integer in: rlognorm(%s)\n", argstr.c_str());
1367 
1368 
1369  // omit last arg which is always the separator character
1370 
1371  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1372 
1373  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1374 
1375  if(param_args[0] == "mean") {
1376 
1377  a = tstring::str2dble(param_args[1]);
1378 
1379  } else if(param_args[0] == "sd") {
1380 
1381  b = tstring::str2dble(param_args[1]);
1382 
1383  } else if(param_args.size() == 1) {
1384 
1385  // the strings "mean=" or "sd=" can be omitted by the user
1386  // we assume meaning by position
1387 
1388  if(i == 1)
1389  a = tstring::str2dble(param_args[0]);
1390  else if (i == 2)
1391  b = tstring::str2dble(param_args[0]);
1392 
1393  } else {
1394 
1395  fatal("rlognorm() syntax is: %s\n",syntax.c_str());
1396  }
1397  }
1398 
1399  string sep = macro_args.back();
1400 
1401  // compute the random deviates
1402  string out;
1403 
1404  auto draw = [a, b](){return tstring::dble2str(RAND::LogNormal(a,b));};
1405 
1406  for(unsigned int i = 0; i < num_deviates -1; ++i)
1407  out += draw() + sep;
1408 
1409  out += draw();
1410 
1411  return out;
1412 }
static double LogNormal(double zeta, double sigma)
Definition: Uniform.h:357

References tstring::dble2str(), fatal(), tstring::isanumber(), RAND::LogNormal(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ rnorm()

string ParamsParser::rnorm ( const string &  argstr)
1021 {
1022  string syntax = "rnorm(n, mean=0, sd=1, sep=\",\")";
1023 
1024  int max_arg = 4, min_arg = 1;
1025  double mean = 0.0, sd = 1.0;
1026  unsigned int num_deviates;
1027 
1028  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rnorm", syntax, true);
1029 
1030 
1031 // auto print = [this](const string& s){cout<<" getMacroArgs:: "<<s<<endl;};
1032 //
1033 // for_each(macro_args.cbegin(), macro_args.cend(), print);
1034 
1035  // get and check the number of deviates we need to draw
1036  if(!tstring::isanumber(macro_args[0]))
1037  fatal("rnorm(): first argument must be a positive integer in: rnorm(%s)\n", argstr.c_str());
1038 
1039  num_deviates = tstring::str2uint(macro_args[0]);
1040 
1041  if(!(num_deviates > 0))
1042  fatal("rnorm(): first argument must be a positive integer in: rnorm(%s)\n", argstr.c_str());
1043 
1044  // get the mean and sd values, if present
1045  if(macro_args.size()-1 > 1){
1046 
1047  // omit last arg which is always the separator character
1048 
1049  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1050 
1051  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1052 
1053  if(param_args[0] == "mean") {
1054 
1055  mean = tstring::str2dble(param_args[1]);
1056 
1057  } else if(param_args[0] == "sd") {
1058 
1059  sd = tstring::str2dble(param_args[1]);
1060 
1061  } else if(param_args.size() == 1) {
1062 
1063  // the "mean=" and "sd=" can be omitted
1064 
1065  if(i == 1)
1066  mean = tstring::str2dble(param_args[0]);
1067  else if (i == 2)
1068  sd = tstring::str2dble(param_args[0]);
1069 
1070  } else {
1071 
1072  fatal("rnorm() syntax is: %s\n",syntax.c_str());
1073  }
1074 
1075  }
1076  }
1077 
1078  string sep = macro_args.back();
1079 
1080  // compute the random deviates
1081  string out;
1082  auto draw = [mean, sd](){return tstring::dble2str(mean + RAND::Gaussian(sd));};
1083 
1084  for(unsigned int i = 0; i < num_deviates -1; ++i)
1085  out += draw() + sep;
1086 
1087  out += draw();
1088 
1089  return out;
1090 }
static double Gaussian(double sigma)
Definition: Uniform.h:261

References tstring::dble2str(), fatal(), RAND::Gaussian(), tstring::isanumber(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ rpoiss()

string ParamsParser::rpoiss ( const string &  argstr)
1095 {
1096  string syntax = "rpois(n, mean=1, sep=\",\")";
1097 
1098  int max_arg = 3, min_arg = 1;
1099  double mean = 1.0;
1100  unsigned int num_deviates;
1101 
1102  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rpois", syntax, true);
1103 
1104  // get and check the number of deviates we need to draw
1105  if(!tstring::isanumber(macro_args[0]))
1106  fatal("rpois(): first argument must be a positive integer in: rpois(%s)\n", argstr.c_str());
1107 
1108  num_deviates = tstring::str2uint(macro_args[0]);
1109 
1110  if(!(num_deviates > 0))
1111  fatal("rpois(): first argument must be a positive integer in: rpois(%s)\n", argstr.c_str());
1112 
1113 
1114  // get the mean value, if present
1115  // we omit last arg macro_args[2] which is always the separator character
1116  if(macro_args.size() == 3){
1117 
1118  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1119 
1120  if(param_args[0] == "mean") {
1121 
1122  mean = tstring::str2dble(param_args[1]);
1123 
1124  } else if(param_args.size() == 1) {
1125 
1126  // the string "mean=" can be omitted by user
1127 
1128  mean = tstring::str2dble(param_args[0]);
1129 
1130  } else {
1131 
1132  fatal("rpois() syntax is: %s\n",syntax.c_str());
1133  }
1134  }
1135 
1136  string sep = macro_args.back();
1137 
1138  // compute the random deviates
1139  string out;
1140 
1141  auto draw = [mean](){return tstring::dble2str(RAND::Poisson(mean));};
1142 
1143  for(unsigned int i = 0; i < num_deviates -1; ++i)
1144  out += draw() + sep;
1145 
1146  out += draw();
1147 
1148  return out;
1149 }
static double Poisson(double mean)
From the Numerical Recieps.
Definition: Uniform.h:219

References tstring::dble2str(), fatal(), tstring::isanumber(), RAND::Poisson(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), and tstring::str2uint().

Referenced by ParamsParser().

◆ runif()

string ParamsParser::runif ( const string &  argstr)
944 {
945  string syntax = "runif(n, min=0, max=1, sep=\",\")";
946 
947  int max_arg = 4, min_arg = 1;
948  double min = 0.0, max = 1.0;
949  unsigned int num_deviates;
950 
951  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "runif", syntax, true);
952 
953  // get and check the number of deviates we need to draw
954  if(!tstring::isanumber(macro_args[0]))
955  fatal("runif(): first argument must be a positive integer in: runif(%s)\n", argstr.c_str());
956 
957  num_deviates = tstring::str2uint(macro_args[0]);
958 
959  if(!(num_deviates > 0))
960  fatal("runif(): first argument must be a positive integer in: runif(%s)\n", argstr.c_str());
961 
962 
963 // map<string, double> dev_param; dev_param["min"] = 0.0; dev_param["max"] = 1.0;
964 //
965 // auto get_param_value = [&](const string& str_in){
966 // vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(str_in, '=');
967 //
968 // };
969 
970  // get the min and max values, if present
971  if(macro_args.size()-1 > 1){
972 
973  // omit last arg which is always the separator character
974 
975  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
976 
977  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
978 
979  if(param_args[0] == "min") {
980 
981  min = tstring::str2dble(param_args[1]);
982 
983  } else if(param_args[0] == "max") {
984 
985  max = tstring::str2dble(param_args[1]);
986 
987  } else if(param_args.size() == 1) {
988 
989  // the "min=" and "max=" can be omitted
990 
991  if(i == 1)
992  min = tstring::str2dble(param_args[0]);
993  else if (i == 2)
994  max = tstring::str2dble(param_args[0]);
995 
996  }else {
997 
998  fatal("runif() syntax is: %s\n",syntax.c_str());
999  }
1000  }
1001  }
1002 
1003  string sep = macro_args.back();
1004 
1005  // compute the random deviates
1006  string out;
1007 
1008  auto draw = [min, max](){return tstring::dble2str((max-min)*RAND::Uniform() + min);};
1009 
1010  for(unsigned int i = 0; i < num_deviates -1; ++i)
1011  out += draw() + sep;
1012 
1013  out += draw();
1014 
1015  return out;
1016 }
static double Uniform()
Generates a random number from [0.0, 1.0[ uniformly distributed.
Definition: Uniform.h:124

References tstring::dble2str(), fatal(), tstring::isanumber(), tstring::splitExcludeEnclosedDelimiters(), tstring::str2dble(), tstring::str2uint(), and RAND::Uniform().

Referenced by ParamsParser().

◆ seq()

string ParamsParser::seq ( const string &  argstr)
612 {
613  string syntax="seq(from, to, by, sep=\",\")";
614 
615  int max_arg = 4;
616 
617  vector<string> macro_args = getMacroArgs(argstr, 3, max_arg, "seq", syntax, true);
618 
619  string sep = macro_args[ 3 ];
620 
621  for (int i = 0; i < 3; ++i) {
622 
623  if(!tstring::isanumber(macro_args[i]))
624  fatal("seq(): argument %i must be a number in: seq(%s)\n", i+1, argstr.c_str());
625 
626  }
627 
628  // now create the sequence of numbers:
629  string out;
630 
631  int index = 0;
632  double current = tstring::str2dble(macro_args[0]);
633  double to = tstring::str2dble(macro_args[1]);
634  double i = tstring::str2dble(macro_args[2]);
635 
636  double sign = 1.0; // indicate whether the sequence is increasing (+1.0) or decreasing (-1.0)
637 
638  // check if the sequence is decreasing
639  if(current > to) {
640 
641  sign = -1.0;
642 
643  if(i > 0)
644  fatal("seq(): third argument \"by\" must be a negative number when from > to in: seq(%s).\n", argstr.c_str());
645 
646 // i *= sign; // must be negative when decrement
647  }
648 
649  // check the sign of the increment if increasing sequence
650  if(current < to && i < 0) {
651 
652  fatal("seq(): third argument \"by\" must be a positive number when from < to in: seq(%s).\n", argstr.c_str());
653 
654 // i *= -1.0; //make it positive
655  }
656  // loop until reaching "to"
657  while(sign*(current-to) < 1.0e-15) { // to avoid precision errors, it's a workaround, setting epsilon to a fixed value
658 
659  out += tstring::dble2str(current);
660 
661  current += i;
662 
663  // check next value to place the separator thus avoiding adding a separator after the last value
664  if(sign*(current-to) < 1.0e-15)
665  out += sep;
666  };
667 
668  return out;
669 }

References tstring::dble2str(), fatal(), tstring::isanumber(), and tstring::str2dble().

Referenced by ParamsParser().

◆ setName()

void ParamsParser::setName ( const char *  name)
inline
57 {_sname = name;}

Referenced by BinaryDataLoader::extractPop().

◆ sym_matrix()

string ParamsParser::sym_matrix ( const string &  argstr)
853 {
854  string syntax = "smatrix(x, nrow, diag=0)";
855 
856  // first arg is row-oriented
857  int max_arg = 3, min_arg = 2;
858  string out;
859  size_t nrow;
860 
861  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "smatrix", syntax, false);
862 
863  // the size is inferred from splitting the string provided
864  vector<string> upper = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', true), ',');
865 
866  if(!tstring::isanumber(macro_args[1]))
867  fatal("smatrix(): secong argument \"nrow\" is not a number in: smatrix(%s)\n", argstr.c_str());
868  else
869  nrow = tstring::str2int(macro_args[1]);
870 
871  size_t num_el = nrow*(nrow-1)/2;
872 
873  //fill "upper" if only one value was passed, that value will be copied
874  if( upper.size() == 1) {
875  string val = upper[0];
876  upper.assign(num_el, val);
877  }
878 
879  // check size
880  if( upper.size() != nrow*(nrow-1)/2 )
881  fatal("smatrix(): number of elements (%i) passed doesn't match with the number of rows (%i) specified in: smatrix(%s)\n", upper.size(), nrow, argstr.c_str());
882 
883  // look for diagonal elements
884  auto is_diag = [] (const string& s) {return (s.find("diag") != string::npos);};
885 
886  vector<string>::const_iterator diagPos = find_if(macro_args.begin(), macro_args.end(), is_diag);
887 
888  vector<string> diag;
889  string diag_arg;
890 
891  if( diagPos != macro_args.end() ) // user specified the diagonal elements
892  {
893  diag_arg = *diagPos;
894  //remove the front string "diag=" and get the argument value
895  diag_arg = getMacroParamValue(diag_arg, "diag", syntax);
896 
897  diag = tstring::split(tstring::removeEnclosingChar(diag_arg, '"', '"', true), ',');
898 
899  if(diag.size() == 1) {
900  string val = diag[0];
901  diag.assign(nrow, val);
902  }
903  else if (diag.size() != nrow) {
904  fatal("smatrix(): number of elements to \"diag\" doesn't match with the matrix size in: smatrix(%s)\n", argstr.c_str());
905  }
906 
907  } else
908  diag.assign(nrow, "0");
909 
910  // create the matrix
911 
912  TMatrix mat(nrow, nrow);
913 
914  for (unsigned int r = 0, c, e = 0, d = 0; r < nrow ; ++r) {
915 
916  for (c = r; c < nrow && e < upper.size(); ++c) {
917 
918  if(c == r)
919  mat.set(r, c, tstring::str2dble(diag[d++]));
920  else
921  mat.set(r, c, tstring::str2dble(upper[e++]));
922  }
923 
924  // catch the last diagonal element of the matrix, after having copied all off-diagonal elements
925  if(c == r)
926  mat.set(r, c, tstring::str2dble(diag[d++]));
927  }
928 
929  // fill the lower triangle:
930  for (unsigned int r = nrow-1; r > 0 ; --r) {
931 
932  for(unsigned int c = 0; c < r; ++c)
933 
934  mat.set(r, c, mat.get(c,r));
935 
936  }
937 
938  return mat.to_string();
939 }
A class to handle matrix in params, coerces matrix into a vector of same total size.
Definition: tmatrix.h:50

References fatal(), TMatrix::get(), tstring::isanumber(), tstring::removeEnclosingChar(), TMatrix::set(), tstring::split(), tstring::str2dble(), tstring::str2int(), and TMatrix::to_string().

Referenced by ParamsParser().

◆ tempseq()

string ParamsParser::tempseq ( const string &  argstr)
674 {
675  string syntax = "tempseq(at, seq) ";
676 
677  int max_arg = 2, min_arg = 2;
678 
679  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "tempseq", syntax, false);
680 
681  //get arg values by name:
682  string arg;
683  vector<string>::const_iterator argPos;
684 
685 
686  // look for a named argument
687 
688  // check if arg "at" is named ( at="..." )
689  auto has_at = [] (const string& s) {return (s.find("at") != string::npos);};
690 
691  argPos = find_if(macro_args.begin(), macro_args.end(), has_at);
692 
693  if( argPos != macro_args.end() )
694  arg = getMacroParamValue(*argPos, "at", syntax);
695  else
696  arg = macro_args[0]; // default assignment by position
697 
698  vector<string> at_time = tstring::split(tstring::removeEnclosingChar(arg, '"', '"', false), ',');
699 
700  if(at_time[0] != "0")
701  fatal("tempseq(): argument \"at\" must start with value \'0\' (for parameter's initial value at generation 0) in: tempseq(%s).\n",argstr.c_str());
702 
703  // check if arg "seq" is named:
704  auto has_seq = [] (const string& s) {return (s.find("seq") != string::npos);};
705 
706  argPos = find_if(macro_args.begin(), macro_args.end(), has_seq);
707 
708  if( argPos != macro_args.end() )
709  arg = getMacroParamValue(*argPos, "seq", syntax);
710  else
711  arg = macro_args[1]; // default assignment by position
712 
713  vector<string> values = tstring::split(tstring::removeEnclosingChar(arg, '"', '"', false), ',');
714 
715  //------- process input and build output string ---------
716  size_t num_gen = at_time.size();
717  size_t num_val = values.size();
718 
719  if(num_val < num_gen)
720  fatal("tempseq(): argument \"seq\" contains less values than \"at\" in: tempseq(%s).\n",argstr.c_str());
721 
722  if(num_val > num_gen)
723  fatal("tempseq(): argument \"seq\" contains more values than \"at\" in: tempseq(%s)\n",argstr.c_str());
724 
725  string out = "(";
726 
727  for(auto i = 0; i < num_gen-1; ++i) {
728 
729  out += "@g" + at_time[i] + " " + values[ i % num_val] + ", ";
730  }
731 
732  out += "@g" + at_time[num_gen-1] + " " + values[ (num_gen-1) % num_val] + ")";
733 
734  return out;
735 }

References fatal(), tstring::removeEnclosingChar(), and tstring::split().

Referenced by ParamsParser().

Member Data Documentation

◆ _inputParams

map< string, string > ParamsParser::_inputParams
private

The whole, unparsed set of input parameters.

◆ _macroMap

map< string, string (ParamsParser::* )(const string& )> ParamsParser::_macroMap
private

The macro table, mapping call name to caller.

◆ _parsedParams

map< string, vector< string > > ParamsParser::_parsedParams
private

The parsed set of simulation parameters after sequential parameters have been separated.

◆ _sname

const char* ParamsParser::_sname
private

Attached file of stream name.


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

Generated for Nemo v2.4.0b by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR