StochHMM  v0.34
Flexible Hidden Markov Model C++ Library and Application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
options.cpp
Go to the documentation of this file.
1 /*
2  * options.cpp
3  * HMM
4  *
5  * Created by Paul C Lott on 8/13/09.
6  * Copyright 2009 University of California, Davis. All rights reserved.
7  *
8  */
9 
10 #include "options.h"
11 
12 namespace StochHMM{
13 
14 
15  //----------------------------------------------------------------------------//
16  // Description: opt_data initialization
17  //
18  //
19  //
20  //----------------------------------------------------------------------------//
22  type=UNDEF_OPT; //what datatype does the option store
23  set=false; //Has the parameter been set
24  required=false; //Is the parameter required, else exit
25  restricted=false; //Are the entries restricted to allowable
26  default_value=false;
27  }
28 
29 
30  //!Setup options to handle the parameters and options defined by the user
31  //!\param param pointer to opt_parameters(user defined options and defaults)
32  //!\param size # of parameters that have been defined
33  //!\param usageStatement User defined usage statement for the program
34  void options::set_parameters(opt_parameters *param,int size,const char* usageStatement){
35 
36  usage=usageStatement;
37 
38  //Process paramaters
39  for(int i=0;i<size;i++){
40  //Get possible commandline tags and split possible tags;
41  std::string opt_tag=param[i].commandline_tag;
42  std::vector<std::string> tags;
43  size_t found=opt_tag.find_first_of(":");
44  if (found==std::string::npos){
45  tags.push_back(opt_tag);
46  }
47  else{
48  while (found!=std::string::npos){
49  tags.push_back(opt_tag.substr(0,found));
50  opt_tag.erase(0,found+1);
51  found=opt_tag.find_first_of(":");
52  if (found==std::string::npos){
53  tags.push_back(opt_tag);
54  }
55  }
56  }
57 
58  // Check allowable;
59  int allowable_defined=0;
60  for (int j=0;j<MAX_ALLOWABLE;j++){
61  if (param[i].allowable[j]!=""){
62  allowable_defined++;
63  }
64  else{
65  break;
66  }
67  }
68 
69  //Make assignments to opt_data
70  opt_data *tp= new(std::nothrow) opt_data;
71  if (tp==NULL){
72  std::cerr << "OUT OF MEMORY\nFile" << __FILE__ << "Line:\t"<< __LINE__ << std::endl;
73  exit(1);
74  }
75  tp->type=param[i].type;
76  tp->required=param[i].required;
77 
78 
79  //Process restricted/allowable secondary options parameters
80  if (allowable_defined>0){
81  tp->restricted =true;
82  for(int k=0;k<allowable_defined;k++){
83  tp->flags[param[i].allowable[k]]=false;
84  }
85  }
86  else {
87  tp->restricted =false;
88  }
89 
90 
91  //Determine presets and assign
92  if (param[i].preset.compare("")!=0){
93  if (tp->type==OPT_INT){
94 
95  double tempValue;
96  std::istringstream input(param[i].preset);
97  if(!(input>>tempValue)){
98  std::cerr << "Couldn't convert preset to numerical integer: " << param[i].preset << std::endl;
99  tp->set=false;
100  }
101  else{
102  tp->data.i=tempValue;
103  tp->default_value=true;
104  tp->set=false;
105  }
106  }
107  else if (tp->type==OPT_DOUBLE){
108 
109  double tempValue;
110  std::istringstream input(param[i].preset);
111  if(!(input >> tempValue)){
112  std::cerr << "Couldn't convert preset to numerical double: " << param[i].preset << std::endl;
113  tp->set=false;
114  }
115  else{
116  tp->data.d=tempValue;
117  tp->default_value=true;
118  tp->set=false;
119  }
120  }
121  else if (tp->type==OPT_STRING){
122  tp->str=param[i].preset;
123  tp->default_value = true;
124  tp->set=false;
125  }
126  else if (tp->type==OPT_FLAG){
127  tp->set=false;
128  for(size_t k=0;k<param[i].preset.size();k++){
129  if (k>=MAX_ALLOWABLE){
130  std::cerr << "More presets than allowed OPT_FLAG" <<std::endl;
131  exit(0);
132  }
133  char c=param[i].preset[k];
134  if (c=='1'){
135  tp->flags[param[i].allowable[k]]=true;
136  }
137  else{
138  tp->flags[param[i].allowable[k]]=false;
139  }
140  }
141  }
142  }
143 
144 
145  //Assign the possible tags to map. Linked to pointer to opt_data
146  for(size_t j=0; j<tags.size();j++){
147  //cout << tags[j] << endl;
148  opts[tags[j]]=tp;
149  alternatives[tags[j]]=tags[0];
150  }
151  }
152 
153  return;
154  }
155 
156 
157 
158  //!Parse the commandline arguments and save them in the options clas
159  //!\param argc Number of commandline arguments;
160  //!\param argv Commandline argurments
161  void options::parse_commandline(int argc, const char * argv[]){
162 
163  for(int i=1;i<argc;i++){
164  std::string tag=argv[i];
165  if (tag[0]!='-'){
166  std::cout << "Unpaired/Unknown commandline argument:\t" << tag <<std::endl;
167  std::cout << usage << std::endl; //Print Usage statement
168  exit(1);
169  }
170  else if (opts.count(tag)){
171  std::string secondary;
172  opts[tag]->set=true;
173  switch (opts[tag]->type) {
174  case OPT_NONE:
175  break;
176  case OPT_INT:
177  if (i+1==argc){
178  if (!opts[tag]->default_value){
179  std::cerr << "Command:\t" << tag <<" is missing a secondary command line argument\n";
180  std::cout << usage << std::endl; //Print Usage statement
181  exit(2);
182  }
183  }
184  else if (argv[i+1][0]=='-'){
185  if (!opts[tag]->default_value){
186  std::cerr << "Command:\t" << tag <<" is missing a secondary command line argument\n";
187  }
188  }
189  else{
190  //Probably need to check to make sure that the argument is a number;
191  opts[tag]->data.i=atoi(argv[++i]);
192  }
193  break;
194  case OPT_DOUBLE:
195  if (i+1==argc){
196  if (!opts[tag]->default_value){
197  std::cerr << "Command:\t" << tag <<" is missing a argument\n";
198  std::cout << usage << std::endl; //Print Usage statement
199  exit(2);
200  }
201  }
202  else if (argv[i+1][0]=='-'){
203  if (!opts[tag]->default_value){
204  std::cerr << "Command:\t" << tag <<" is missing a secondary command line argument\n";
205  }
206  }
207  else{
208  opts[tag]->data.d=atof(argv[++i]);
209  }
210 
211  break;
212  case OPT_STRING:
213  //Check that secondary doesn't start with a dash;
214  if (i+1==argc){
215  secondary="";
216  }
217  else{
218  secondary=argv[i+1];
219  }
220 
221  if (secondary[0]=='-'){
222  if (!opts[tag]->default_value){
223  opts[tag]->str="";
224  }
225  }
226  else{
227  i++;
228  if (opts[tag]->restricted){
229  if (opts[tag]->flags.count(secondary)){
230  opts[tag]->str=secondary;
231  }
232  else{
233  std::cerr << "Secondary option for:\t" << tag << " ->" << secondary << " is not allowed.\n";
234  std::cout << usage << std::endl; //Print Usage statement
235  exit(2);
236  }
237  }
238  else{
239  if (secondary.compare("")==0){
240  if (!opts[tag]->default_value){
241  opts[tag]->str=secondary;
242  }
243  }
244  else{
245  opts[tag]->str=secondary;
246  }
247  }
248  }
249  break;
250  case OPT_FLAG:
251  if (i+1==argc){
252  std::cerr << "Command:\t" << tag <<" is missing a secondary command line argument\n";
253  std::cout << usage << std::endl; //Print Usage statement
254  exit(2);
255  }
256 
257  secondary=argv[++i];
258  if (opts[tag]->flags.count(secondary)){
259  opts[tag]->flags[secondary]=true;
260  }
261  else{
262  std::cerr << "Secondary option for:\t" << tag << " ->" << secondary << " is not allowed.\n";
263  std::cout << usage << std::endl; //Print Usage statement
264  exit(2);
265  }
266  break;
267  default:
268  break;
269  }
270  }
271  }
272 
273  //check that all required are now set;
274  bool set(true);
275  std::map<std::string,bool> RequiredNotSet;
276  std::map<std::string,opt_data*>::iterator it;
277 
278  for(it=opts.begin();it!=opts.end();it++){
279  if ((*it).second->required && !(*it).second->set){
280  set=false;
281  RequiredNotSet[alternatives[(*it).first]]=false;
282  }
283  }
284 
285  if (!set){
286  std::map<std::string,bool>::iterator it;
287  for(it=RequiredNotSet.begin();it!=RequiredNotSet.end();it++){
288  std::cout << "Required option:\t" << (*it).first <<" not set on command-line\n";
289  }
290  std::cout << usage <<std::endl;
291  exit(1);
292  }
293 
294  return;
295  }
296 
297 
298  //!Get the integer value for option
299  //!\param [in] param the option name
300  //!\param [out] value integer is to be returned to
301  //!\return true if option existed and is returned
302  //!\return false if option does not exist
303  bool options::getopt(const char* param,int &value){
304  if (opts.count(param)){
305  if (opts[param]->set && opts[param]->type==OPT_INT){
306  value=opts[param]->data.i;
307  return true;
308  }
309  else{
310  std::cerr << "Option: " << param << " not set or not of type OPT_INT\n";
311  return false;
312  }
313  }
314  else{
315  std::cerr << "Option: " << param <<" type doesn't exist\n";
316  return false;
317  }
318  }
319 
320 
321  //!Get double type option values
322  //!\param [in] param the option name
323  //!\param [out] value double is to be returned to
324  //!\return true if option existed and is returned
325  //!\return false if option does not exist
326  bool options::getopt(const char* param,double &value){
327  if (opts.count(param)){
328  if (opts[param]->set && opts[param]->type==OPT_DOUBLE){
329  value=opts[param]->data.d;
330  return true;
331  }
332  else{
333  std::cerr << "Option: " << param << " not set or not of type OPT_DOUBLE\n";
334  return false;
335  }
336  }
337  else{
338  std::cerr << "Option: " << param <<" type doesn't exist\n";
339  return false;
340  }
341  }
342 
343 
344  //!Get string type options values
345  //!\param [in] param the option name
346  //!\param [out] value std::string is to be returned to
347  //!\return true if option existed and is returned
348  //!\return false if option does not exist
349  bool options::getopt(const char* param,std::string &value){
350  if (opts.count(param)){
351  if (opts[param]->set && opts[param]->type==OPT_STRING){
352  value=opts[param]->str;
353  return true;
354  }
355  else{
356  std::cerr << "Option: " << param << " not set or not of type OPT_STRING\n";
357  return false;
358  }
359  }
360  else{
361  std::cerr << "Option: " << param <<" type doesn't exist\n";
362  return false;
363  }
364  }
365 
366 
367  //!Check primary and secondary options and returns value of bool flag
368  //! \param param primary option name
369  //! \param sec secondary option name
370  //! \return true if secondary option is set
371  //! \return false if secondary option is not set
372  bool options::isFlagSet(const char* param,const char* sec){
373  std::string secondary=sec;
374  if (opts.count(param)){
375  if (opts[param]->set && opts[param]->type==OPT_FLAG){
376  if (opts[param]->flags.count(secondary)){
377  return opts[param]->flags[secondary];
378  }
379  else {
380  std::cerr << "Secondary command: " << secondary << " doesn't exist.\n";
381  return false;
382  }
383  }
384  else{
385  //cerr << "Option: " << param << " not set or not of type OPT_FLAG\n";
386  return false;
387  }
388  }
389  else{
390  std::cerr << "Option: " << param <<" type doesn't exist\n";
391  exit(2);
392  }
393  }
394 
395 
396 
397  //!Returns whether an option is set
398  //!Used also for OPT_NONE option types
399  //!\param param parameter name
400  //!\return true if option is set or exists in commandline argument
401  //!\return false if option is not set or didn't exist in commandline argument
402  bool options::isSet(const char* param){
403  if (opts.count(param)){
404  return opts[param]->set;
405  }
406  else{
407  std::cerr << "Option: " << param <<" type doesn't exist\n";
408  return false;
409  }
410  }
411 
412  //!Get string value for option
413  //!If option is not an OPT_STRING, this will produce an error
414  //!\param param parameter name
415  //!\return std::string
416  std::string &options::sopt(const char * param){
417  if (opts.count(param)){
418  if (opts[param]->set && opts[param]->type==OPT_STRING){
419  return opts[param]->str;
420  }
421  else{
422  std::cerr << "Option: " << param << " not set or not of type OPT_STRING\n";
423  exit(2);
424  }
425  }
426  else{
427  std::cerr << "Option: " << param <<" type doesn't exist\n";
428  exit(2);
429  }
430  }
431 
432 
433  //!Get integer value for option
434  //!If option is not an OPT_INT, this will produce an error
435  //!\param param parameter name
436  //!\return int
437  int &options::iopt(const char * param){
438  if (opts.count(param)){
439  if (opts[param]->set && opts[param]->type==OPT_INT){
440  return opts[param]->data.i;
441  }
442  else{
443  std::cerr << "Option: " << param << " not set or not of type OPT_INT\n";
444  exit(2);
445  }
446  }
447  else{
448  std::cerr << "Option: " << param <<" type doesn't exist\n";
449  exit(2);
450  }
451  }
452 
453  //!Get double value for option
454  //!If option is not an OPT_DOUBLE, this will produce an error
455  //!\param param parameter name
456  //!\return double
457  double &options::dopt(const char * param){
458  if (opts.count(param)){
459  if (opts[param]->set && opts[param]->type==OPT_DOUBLE){
460  return opts[param]->data.d;
461  }
462  else{
463  std::cerr << "Option: " << param << " not set or not of type OPT_DOUBLE\n";
464  exit(2);
465  }
466  }
467  else{
468  std::cerr << "Option: " << param <<" type doesn't exist\n";
469  exit(2);
470  }
471  }
472 
474  return;
475  }
476 
477 
478 }