Nemo  2.4.0
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)
57 {
58  _sname = name;
59 
60  _macroMap["rep"] = &ParamsParser::rep;
61  _macroMap["seq"] = &ParamsParser::seq;
62  _macroMap["tempseq"] = &ParamsParser::tempseq;
65  _macroMap["runif"] = &ParamsParser::runif;
66  _macroMap["rnorm"] = &ParamsParser::rnorm;
67  _macroMap["rpois"] = &ParamsParser::rpoiss;
68  _macroMap["rlognorm"] = &ParamsParser::rlognorm;
69  _macroMap["rgamma"] = &ParamsParser::rgamma;
70  _macroMap["rbernoul"] = &ParamsParser::rbernoul;
71  _macroMap["rexp"] = &ParamsParser::rexp;
72  _macroMap["matrix"] = &ParamsParser::matrix;
74  _macroMap["smatrix"] = &ParamsParser::sym_matrix;
75 }
string rexp(const string &argstr)
Definition: paramsparser.cc:1231
string rlognorm(const string &argstr)
Definition: paramsparser.cc:1366
string tempseq(const string &argstr)
Definition: paramsparser.cc:672
string rnorm(const string &argstr)
Definition: paramsparser.cc:1039
string matrix(const string &argstr)
Definition: paramsparser.cc:738
const char * _sname
Attached file of stream name.
Definition: paramsparser.h:105
string sym_matrix(const string &argstr)
Definition: paramsparser.cc:871
string concat(const string &argstr)
Macro "c" returns a character-delimited string of atomic arguments.
Definition: paramsparser.cc:484
map< string, string(ParamsParser::*)(const string &)> _macroMap
The macro table, mapping call name to caller.
Definition: paramsparser.h:114
string rbernoul(const string &argstr)
Definition: paramsparser.cc:1172
string seq(const string &argstr)
Definition: paramsparser.cc:610
string runif(const string &argstr)
Definition: paramsparser.cc:962
string quote(const string &argstr)
Macro "q" returns a quoted string.
Definition: paramsparser.cc:511
string rep(const string &argstr)
Definition: paramsparser.cc:536
string rpoiss(const string &argstr)
Definition: paramsparser.cc:1113
string rgamma(const string &argstr)
Definition: paramsparser.cc:1290
string diag_matrix(const string &argstr)
Definition: paramsparser.cc:804

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

◆ ~ParamsParser()

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

Member Function Documentation

◆ add_inputParam()

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

Referenced by StreamParser::read().

+ Here is the caller graph for this function:

◆ callMacro()

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

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.

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

References tstring::removeEnclosingChar().

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ diag_matrix()

string ParamsParser::diag_matrix ( const string &  argstr)
805 {
806  string syntax = "diag(x, n)";
807 
808  int max_arg = 2, min_arg = 1;
809  string out;
810  string off_diag = "0";
811  size_t nrow;
812 
813  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "diag", syntax, false);
814 
815  // the size is inferred from splitting the string provided
816  vector<string> elmnts = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', true), ',');
817 
818  if( macro_args.size() == 1) {
819 
820  nrow = elmnts.size();
821 
822  } else {
823  // already checked that it's not >2 arguments passed
824 
825  nrow = size_t(tstring::str2uint(macro_args[1]));
826 
827  // the value may contain several elements that might need to be repeated:
828  if(elmnts.size() > 1 && elmnts.size() != nrow) {
829 
830  fatal("diag(): the number of elements to use for the diag matrix is different from parameter \"n\" in: diag(%s)\n\
831  use quoted rep() if you intend to repeat a pattern, eg: diag(q(rep(..., n1)),n2)\n", syntax.c_str());
832 
833  } else if (elmnts.size() == 1){
834 
835  // build the vector of elements used below
836 
837  for(unsigned int i = 0; i < nrow-1; ++i)
838  elmnts.push_back(elmnts[0]);
839  }
840  }
841 
842  out += "{";
843 
844  for (unsigned int r = 0, c, e = 0; r < nrow; ++r) {
845 
846  out += "\n{";
847 
848  for (c = 0; c < nrow - 1 && e < elmnts.size(); ++c) {
849 
850  if(c == r)
851  out += elmnts[e++] + ",";
852  else
853  out += off_diag + ",";
854  }
855 
856  if(c == r)
857  out += elmnts[e++] + "}";
858  else
859  out += off_diag + "}";
860 
861  }
862 
863  // close the matrix block
864  out += "}";
865 
866  return out;
867 }
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:127
static unsigned int str2uint(const string &str)
Converts a string into an unsigned integer.
Definition: tstring.h:50

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ get_inputParams()

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

◆ getArguments()

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

References StreamParser::removeSpaceAndComment().

◆ getBlockArgument()

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

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

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

◆ getMacroParamValue()

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

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

◆ getMacroSepParamChar()

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

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

◆ getParameters() [1/2]

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

◆ getParameters() [2/2]

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

+ Here is the caller graph for this function:

◆ getParsedParameters() [1/2]

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

◆ getParsedParameters() [2/2]

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

Referenced by SimRunner::run().

+ Here is the caller graph for this function:

◆ matrix()

string ParamsParser::matrix ( const string &  argstr)
739 {
740  string syntax = "matrix(x, nrow, ncol, fill_by=row)";
741 
742  int max_arg = 4, min_arg = 3;
743 
744  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "matrix", syntax, false);
745 
746  if(macro_args[0][0] != '"' && macro_args[0].back() != '"')
747  fatal("matrix(): first argument must be quoted with \" in: matrix(%s)\n",argstr.c_str());
748 
749  vector<string> elmnts = tstring::split(tstring::removeEnclosingChar(macro_args[0], '"', '"', false), ',');
750 
751  unsigned int nrow = tstring::str2uint(macro_args[1]);
752  unsigned int ncol = tstring::str2uint(macro_args[2]);
753 
754  if(elmnts.size() < nrow*ncol)
755  fatal("matrix(): not enough elements provided, got %i, must be rows*columns = %i\n", elmnts.size(), nrow*ncol);
756 
757  if(elmnts.size() > nrow*ncol)
758  fatal("matrix(): too many elements provided, got %i, must be rows*columns = %i\n", elmnts.size(), nrow*ncol);
759 
760  // check filling option -------------
761 
762  // ---- looking for the argument ----
763  auto has_fill_by = [] (const string& s) {return (s.find("fill_by=") != string::npos);};
764 
765  auto argPos = find_if(macro_args.begin(), macro_args.end(), has_fill_by);
766 
767  // Initialize fill mode default
768  string fill_mode = "row";
769 
770  if( argPos != macro_args.end() )
771  fill_mode = getMacroParamValue(*argPos, "fill_by", syntax);
772 
773  if (fill_mode != "row" && fill_mode != "col")
774  fatal("matrix(): invalid value for 'fill_by'. Must be 'row' or 'col'. Received: %s\n", fill_mode.c_str());
775 
776  // start writing the matrix into the output string
777  string out("{");
778 
779  for (unsigned int r = 0; r < nrow; ++r) {
780  out += "\n{";
781 
782  for (unsigned int c = 0; c < ncol - 1; ++c) {
783 
784  // Index calculation: e = row * ncol + col
785  size_t e = (size_t)(fill_mode == "row"? r * ncol + c : c * nrow + r);
786 
787  out += elmnts[e] + ",";
788  }
789  // Last element of the row
790  size_t e_last = (size_t)(fill_mode == "row"? r * ncol + (ncol - 1) :
791  (ncol - 1) * nrow + r);
792  out += elmnts[e_last] + "}";
793 
794  }
795 
796  // close the matrix block
797  out += "}";
798 
799  return out;
800 }
string getMacroParamValue(const string &str_in, const string &par_name, const string &macro_name)
Definition: paramsparser.cc:472

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ parse()

void ParamsParser::parse ( )

Builds the _parsedParams from the _inputParams.

This defines rules of sequential, matricial params, etc.

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

References message().

◆ parseMacroFunctionBlock()

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

References fatal().

◆ quote()

string ParamsParser::quote ( const string &  argstr)

Macro "q" returns a quoted string.

Useful to quote result of call to enclosed macro.

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ rbernoul()

string ParamsParser::rbernoul ( const string &  argstr)
1173 {
1174  string syntax = "rbernoul(n, p=0.5, sep=\",\")";
1175 
1176  int max_arg = 3, min_arg = 1;
1177  double p = 0.5;
1178  unsigned int num_deviates;
1179 
1180  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rbernoul", syntax, true);
1181 
1182  // get and check the number of deviates we need to draw
1183  if(!tstring::isanumber(macro_args[0]))
1184  fatal("rbernoul(): first argument must be a positive integer in: rbernoul(%s)\n", argstr.c_str());
1185 
1186  num_deviates = tstring::str2uint(macro_args[0]);
1187 
1188  if(!(num_deviates > 0))
1189  fatal("rbernoul(): first argument must be a positive integer in: rbernoul(%s)\n", argstr.c_str());
1190 
1191 
1192  // get the mean value, if present
1193  // we omit last arg macro_args[2] which is always the separator character
1194  if(macro_args.size() == 3){
1195 
1196  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1197 
1198  if(param_args[0] == "p") {
1199 
1200  p = tstring::str2dble(param_args[1]);
1201 
1202  } else if(param_args.size() == 1) {
1203 
1204  // the string "mean=" can be omitted by user
1205 
1206  p = tstring::str2dble(param_args[0]);
1207 
1208  } else {
1209 
1210  fatal("rbernoul() syntax is: %s\n",syntax.c_str());
1211  }
1212  }
1213 
1214  string sep = macro_args.back();
1215 
1216  // compute the random deviates
1217  string out;
1218 
1219  auto draw = [p](){return tstring::int2str(RAND::Bernoulli(p));};
1220 
1221  for(unsigned int i = 0; i < num_deviates -1; ++i)
1222  out += draw() + sep;
1223 
1224  out += draw();
1225 
1226  return out;
1227 }
static double Bernoulli(double p)
Definition: Uniform.h:429
static double str2dble(const string &str)
Converts a string into a double.
Definition: tstring.h:83
static string int2str(const int i)
Writes an integer value into a string.
Definition: tstring.h:94

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

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

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ replaceMacro()

string ParamsParser::replaceMacro ( const string &  arg)

Macros.

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

◆ reset_inputParams()

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

Referenced by StreamParser::read().

+ Here is the caller graph for this function:

◆ rexp()

string ParamsParser::rexp ( const string &  argstr)
1232 {
1233  string syntax = "rexp(n, mean=1, sep=\",\")";
1234 
1235  int max_arg = 3, min_arg = 1;
1236  double mean=1.0;
1237  unsigned int num_deviates;
1238 
1239  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rexp", syntax, true);
1240 
1241  // get and check the number of deviates we need to draw
1242  if(!tstring::isanumber(macro_args[0]))
1243  fatal("rexp(): first argument must be a positive integer in: rexp(%s)\n", argstr.c_str());
1244 
1245  num_deviates = tstring::str2uint(macro_args[0]);
1246 
1247  if(!(num_deviates > 0))
1248  fatal("rexp(): first argument must be a positive integer in: rexp(%s)\n", argstr.c_str());
1249 
1250 
1251  // get the mean value, if present
1252  // we omit last arg macro_args[2] which is always the separator character
1253  if(macro_args.size() == 3){
1254 
1255  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1256 
1257  if(param_args[0] == "mean") {
1258 
1259  mean = tstring::str2dble(param_args[1]);
1260 
1261  } else if(param_args.size() == 1) {
1262 
1263  // the string "mean=" can be omitted by user
1264 
1265  mean = tstring::str2dble(param_args[0]);
1266 
1267  } else {
1268 
1269  fatal("rexp() syntax is: %s\n",syntax.c_str());
1270  }
1271  }
1272 
1273  string sep = macro_args.back();
1274 
1275  // compute the random deviates
1276  string out;
1277 
1278  auto draw = [mean](){return tstring::dble2str(RAND::Exponential(mean));};
1279 
1280  for(unsigned int i = 0; i < num_deviates -1; ++i)
1281  out += draw() + sep;
1282 
1283  out += draw();
1284 
1285  return out;
1286 }
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:114

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ rgamma()

string ParamsParser::rgamma ( const string &  argstr)
1291 {
1292  string syntax = "rgamma(n, a, b, sep=\",\")";
1293 
1294  // a and b params are mandatory, with no default
1295 
1296  int max_arg = 4, min_arg = 3;
1297  double a = 0.0, b = 1.0;
1298  unsigned int num_deviates;
1299 
1300  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rgamma", syntax, true);
1301 
1302  // get and check the number of deviates we need to draw
1303  if(!tstring::isanumber(macro_args[0]))
1304  fatal("rgamma(): first argument must be a positive integer in: rgamma(%s)\n", argstr.c_str());
1305 
1306  num_deviates = tstring::str2uint(macro_args[0]);
1307 
1308  if(!(num_deviates > 0))
1309  fatal("rgamma(): first argument must be a positive integer in: rgamma(%s)\n", argstr.c_str());
1310 
1311 
1312  // omit last arg which is always the separator character
1313 
1314  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1315 
1316  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1317 
1318  if(param_args[0] == "a") {
1319 
1320  a = tstring::str2dble(param_args[1]);
1321 
1322  } else if(param_args[0] == "b") {
1323 
1324  b = tstring::str2dble(param_args[1]);
1325 
1326  } else if(param_args.size() == 1) {
1327 
1328  // the strings "a=" or "b=" can be omitted by the user
1329  // we assume meaning by position
1330 
1331  if(i == 1)
1332  a = tstring::str2dble(param_args[0]);
1333  else if (i == 2)
1334  b = tstring::str2dble(param_args[0]);
1335 
1336  } else {
1337 
1338  fatal("rgamma() syntax is: %s.\n",syntax.c_str());
1339  }
1340  }
1341 
1342  if(a < 0)
1343  fatal("rgamma(): shape parameter \"a\" must be positive in %s.\n",syntax.c_str());
1344 
1345  if(b < 0)
1346  fatal("rgamma(): rate parameter \"b\" must be positive in %s.\n",syntax.c_str());
1347 
1348 
1349  string sep = macro_args.back();
1350 
1351  // compute the random deviates
1352  string out;
1353 
1354  auto draw = [a, b](){return tstring::dble2str(RAND::Gamma(a,b));};
1355 
1356  for(unsigned int i = 0; i < num_deviates -1; ++i)
1357  out += draw() + sep;
1358 
1359  out += draw();
1360 
1361  return out;
1362 }
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().

+ Here is the caller graph for this function:

◆ rlognorm()

string ParamsParser::rlognorm ( const string &  argstr)
1367 {
1368  string syntax = "rlognorm(n, mean, sd, sep=\",\")";
1369 
1370  // a and b params are mandatory, with no default
1371 
1372  int max_arg = 4, min_arg = 3;
1373  double a = 0.0, b = 1.0;
1374  unsigned int num_deviates;
1375 
1376  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rlognorm", syntax, true);
1377 
1378  // get and check the number of deviates we need to draw
1379  if(!tstring::isanumber(macro_args[0]))
1380  fatal("rlognorm(): first argument must be a positive integer in: rlognorm(%s)\n", argstr.c_str());
1381 
1382  num_deviates = tstring::str2uint(macro_args[0]);
1383 
1384  if(!(num_deviates > 0))
1385  fatal("rlognorm(): first argument must be a positive integer in: rlognorm(%s)\n", argstr.c_str());
1386 
1387 
1388  // omit last arg which is always the separator character
1389 
1390  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1391 
1392  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1393 
1394  if(param_args[0] == "mean") {
1395 
1396  a = tstring::str2dble(param_args[1]);
1397 
1398  } else if(param_args[0] == "sd") {
1399 
1400  b = tstring::str2dble(param_args[1]);
1401 
1402  } else if(param_args.size() == 1) {
1403 
1404  // the strings "mean=" or "sd=" can be omitted by the user
1405  // we assume meaning by position
1406 
1407  if(i == 1)
1408  a = tstring::str2dble(param_args[0]);
1409  else if (i == 2)
1410  b = tstring::str2dble(param_args[0]);
1411 
1412  } else {
1413 
1414  fatal("rlognorm() syntax is: %s\n",syntax.c_str());
1415  }
1416  }
1417 
1418  string sep = macro_args.back();
1419 
1420  // compute the random deviates
1421  string out;
1422 
1423  auto draw = [a, b](){return tstring::dble2str(RAND::LogNormal(a,b));};
1424 
1425  for(unsigned int i = 0; i < num_deviates -1; ++i)
1426  out += draw() + sep;
1427 
1428  out += draw();
1429 
1430  return out;
1431 }
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().

+ Here is the caller graph for this function:

◆ rnorm()

string ParamsParser::rnorm ( const string &  argstr)
1040 {
1041  string syntax = "rnorm(n, mean=0, sd=1, sep=\",\")";
1042 
1043  int max_arg = 4, min_arg = 1;
1044  double mean = 0.0, sd = 1.0;
1045  unsigned int num_deviates;
1046 
1047  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rnorm", syntax, true);
1048 
1049 
1050 // auto print = [this](const string& s){cout<<" getMacroArgs:: "<<s<<endl;};
1051 //
1052 // for_each(macro_args.cbegin(), macro_args.cend(), print);
1053 
1054  // get and check the number of deviates we need to draw
1055  if(!tstring::isanumber(macro_args[0]))
1056  fatal("rnorm(): first argument must be a positive integer in: rnorm(%s)\n", argstr.c_str());
1057 
1058  num_deviates = tstring::str2uint(macro_args[0]);
1059 
1060  if(!(num_deviates > 0))
1061  fatal("rnorm(): first argument must be a positive integer in: rnorm(%s)\n", argstr.c_str());
1062 
1063  // get the mean and sd values, if present
1064  if(macro_args.size()-1 > 1){
1065 
1066  // omit last arg which is always the separator character
1067 
1068  for (unsigned int i = 1; i < macro_args.size()-1; ++i) {
1069 
1070  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[i], '=');
1071 
1072  if(param_args[0] == "mean") {
1073 
1074  mean = tstring::str2dble(param_args[1]);
1075 
1076  } else if(param_args[0] == "sd") {
1077 
1078  sd = tstring::str2dble(param_args[1]);
1079 
1080  } else if(param_args.size() == 1) {
1081 
1082  // the "mean=" and "sd=" can be omitted
1083 
1084  if(i == 1)
1085  mean = tstring::str2dble(param_args[0]);
1086  else if (i == 2)
1087  sd = tstring::str2dble(param_args[0]);
1088 
1089  } else {
1090 
1091  fatal("rnorm() syntax is: %s\n",syntax.c_str());
1092  }
1093 
1094  }
1095  }
1096 
1097  string sep = macro_args.back();
1098 
1099  // compute the random deviates
1100  string out;
1101  auto draw = [mean, sd](){return tstring::dble2str(mean + RAND::Gaussian(sd));};
1102 
1103  for(unsigned int i = 0; i < num_deviates -1; ++i)
1104  out += draw() + sep;
1105 
1106  out += draw();
1107 
1108  return out;
1109 }
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().

+ Here is the caller graph for this function:

◆ rpoiss()

string ParamsParser::rpoiss ( const string &  argstr)
1114 {
1115  string syntax = "rpois(n, mean=1, sep=\",\")";
1116 
1117  int max_arg = 3, min_arg = 1;
1118  double mean = 1.0;
1119  unsigned int num_deviates;
1120 
1121  vector<string> macro_args = getMacroArgs(argstr, min_arg, max_arg, "rpois", syntax, true);
1122 
1123  // get and check the number of deviates we need to draw
1124  if(!tstring::isanumber(macro_args[0]))
1125  fatal("rpois(): first argument must be a positive integer in: rpois(%s)\n", argstr.c_str());
1126 
1127  num_deviates = tstring::str2uint(macro_args[0]);
1128 
1129  if(!(num_deviates > 0))
1130  fatal("rpois(): first argument must be a positive integer in: rpois(%s)\n", argstr.c_str());
1131 
1132 
1133  // get the mean value, if present
1134  // we omit last arg macro_args[2] which is always the separator character
1135  if(macro_args.size() == 3){
1136 
1137  vector<string> param_args = tstring::splitExcludeEnclosedDelimiters(macro_args[1], '=');
1138 
1139  if(param_args[0] == "mean") {
1140 
1141  mean = tstring::str2dble(param_args[1]);
1142 
1143  } else if(param_args.size() == 1) {
1144 
1145  // the string "mean=" can be omitted by user
1146 
1147  mean = tstring::str2dble(param_args[0]);
1148 
1149  } else {
1150 
1151  fatal("rpois() syntax is: %s\n",syntax.c_str());
1152  }
1153  }
1154 
1155  string sep = macro_args.back();
1156 
1157  // compute the random deviates
1158  string out;
1159 
1160  auto draw = [mean](){return tstring::dble2str(RAND::Poisson(mean));};
1161 
1162  for(unsigned int i = 0; i < num_deviates -1; ++i)
1163  out += draw() + sep;
1164 
1165  out += draw();
1166 
1167  return out;
1168 }
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().

+ Here is the caller graph for this function:

◆ runif()

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

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ seq()

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

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ setName()

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

Referenced by BinaryDataLoader::extractPop().

+ Here is the caller graph for this function:

◆ sym_matrix()

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

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

◆ tempseq()

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

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

Referenced by ParamsParser().

+ Here is the caller graph for this function:

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

Locations of visitors to this page
Catalogued on GSR