1 /*
2  * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
3  *
4  * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
5  *
6  * This file is part of scrm.
7  *
8  * scrm is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifndef scrm_param
24 #define scrm_param
25 
26 #include <vector>
27 #include <iostream>
28 #include <fstream>
29 #include <string>
30 #include <stdexcept>
31 #include <random>
32 #include <iterator>
33 #include <sstream>
34 
35 
36 #include "model.h"
37 #include "summary_statistics/summary_statistic.h"
38 #include "summary_statistics/tmrca.h"
39 #include "summary_statistics/seg_sites.h"
40 #include "summary_statistics/frequency_spectrum.h"
41 #include "summary_statistics/newick_tree.h"
42 #include "summary_statistics/oriented_forest.h"
43 
44 class Param {
45  public:
46  #ifdef UNITTEST
47   friend class TestParam;
48  #endif
49 
50   // Constructors
Param()51   Param() { init(); }
52 
Param(const std::string & arg)53   Param(const std::string &arg) {
54     std::istringstream iss(arg);
55     copy(std::istream_iterator<std::string>(iss),
56          std::istream_iterator<std::string>(),
57          std::back_inserter(argv_));
58     directly_called_ = true;
59     init();
60   }
61 
62   Param(int argc, char *argv[], bool directly_called=true) :
directly_called_(directly_called)63     directly_called_(directly_called) {
64     argv_ = std::vector<std::string>(argv + 1, argv + argc);
65     init();
66   }
67 
init()68   void init() {
69     this->seed_set_ = false;
70     this->random_seed_ = 0;
71     this->set_help(false);
72     this->set_version(false);
73     this->set_precision(6);
74     this->set_print_model(false);
75     this->argv_i = argv_.begin();
76   }
77 
78   // Getters and setters
help()79   bool help() const { return help_; }
version()80   bool version() const { return version_; }
read_init_genealogy()81   bool read_init_genealogy() const { return this->read_init_genealogy_; }
random_seed()82   size_t random_seed() const { return random_seed_; }
precision()83   size_t precision() const { return precision_; }
seed_is_set()84   bool seed_is_set() const { return this->seed_set_; }
print_model()85   bool print_model() const { return this->print_model_; }
86 
set_precision(const size_t p)87   void set_precision ( const size_t p ) { this->precision_ = p; }
set_random_seed(const size_t seed)88   void set_random_seed(const size_t seed) {
89     this->random_seed_ = seed;
90     this->seed_set_ = true;
91   }
set_print_model(const bool print_model)92   void set_print_model(const bool print_model) { print_model_ = print_model; }
93 
94   // Other methods
95   void printHelp(std::ostream& stream);
96 
97   friend std::ostream& operator<< (std::ostream& stream, const Param& param);
98 
99   Model parse();
100 
101   template<class T>
readNextInput()102   T readNextInput() {
103     ++argv_i;
104 
105     if (argv_i == argv_.end()) {
106       throw std::invalid_argument(std::string("Unexpected end of arguments"));
107     }
108 
109     return convert<T>(*argv_i);
110   }
111 
112   template<class T>
convert(const std::string & arg)113   T convert(const std::string &arg) {
114     T value;
115     std::stringstream ss(arg);
116     ss >> value;
117     if (ss.fail()) {
118       throw std::invalid_argument(std::string("Failed to parse option: ") + arg);
119     }
120     return value;
121   }
122 
123   // Read to double first and then cast to int to support scientific notation
readNextInt()124   size_t readNextInt() {
125     return readNextInput<double>();
126   }
127 
128 
129   std::vector < std::string > init_genealogy;
130 
131  private:
set_help(const bool help)132   void set_help(const bool help) { this->help_ = help; }
set_version(const bool version)133   void set_version(const bool version) { this->version_ = version; }
134 
135   std::vector<std::string> argv_;
136   std::vector<std::string>::iterator argv_i;
137   size_t seed_set_;
138   size_t random_seed_;
139   size_t precision_;
140   bool directly_called_;
141   bool help_;
142   bool version_;
143   bool read_init_genealogy_;
144   bool print_model_;
145 };
146 #endif
147