comparison src/program_options.cpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:add35537fdbb
1 // Copyright 2011, Ian Hobson.
2 //
3 // This file is part of gpsynth.
4 //
5 // gpsynth is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // gpsynth is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with gpsynth in the file COPYING.
17 // If not, see http://www.gnu.org/licenses/.
18
19 #include "program_options.hpp"
20
21 #include "boost/filesystem.hpp"
22 #include "boost/program_options.hpp"
23
24 #include <ctime>
25
26 namespace bf = boost::filesystem;
27 namespace bo = boost::program_options;
28
29 namespace {
30
31 const std::string g_default_sc_app_path = "/Applications/SuperCollider";
32
33 void PrintHelpAndQuit(const bo::options_description& options,
34 int exit_code = 0) {
35 bo::arg = "value";
36 std::cout << '\n' << options << std::endl;
37 exit(exit_code);
38 }
39
40 std::string GetTimeString() {
41 std::time_t raw_time;
42 time(&raw_time);
43 tm* time_info = localtime(&raw_time);
44 char buffer[20];
45 strftime(buffer, 20, "%Y-%m-%d_%H:%M:%S", time_info);
46 return buffer;
47 }
48
49
50 } // namespace
51
52
53 void ParseCommandLine(int argument_count,
54 const char* arguments[],
55 ProgramOptions* options) {
56 bo::options_description description;
57 description.add_options()
58 ("help,?", "Displays this message")
59 ("target,t",
60 bo::value<std::string>(&options->target_path_)->required(),
61 "Target sound file path")
62 ("grammar,g",
63 bo::value<std::string>(&options->grammar_path_),
64 "Grammar file path")
65 ("scpath,s",
66 bo::value<std::string>(&options->sc_app_path_),
67 "Path to SuperCollider application folder")
68 ("workfolder,w",
69 bo::value<std::string>(&options->work_folder_),
70 "Path of folder to place files in")
71 ("population,p",
72 bo::value<std::size_t>(&options->population_size_)->default_value(500),
73 "Population size")
74 ("generations,G",
75 bo::value<std::size_t>(&options->generations_)->default_value(20),
76 "Number of Generations")
77 ("fitness,f",
78 bo::value<double>(&options->fitness_threshold_)->default_value(0),
79 "Fitness threshold")
80 ("tournament,T",
81 bo::value<std::size_t>(&options->tournament_size_)->default_value(7),
82 "Tournament selection size")
83 ("crossover,c",
84 bo::value<double>(&options->crossover_rate_)->default_value(0.6, "0.6"),
85 "Crossover rate")
86 ("mutation,m",
87 bo::value<double>(&options->mutation_rate_)->default_value(0.35, "0.35"),
88 "Mutation rate")
89 ("reproducebest,r",
90 bo::value<bool>(&options->reproduce_best_individual_)->default_value(false),
91 "Automatically reproduce best individual when populating next generation.")
92 ("features,F",
93 bo::value<std::string>(&options->fitness_features_),
94 "Set of features that the fitness function will measure when comparing files."
95 " Must be a comma separated list of feature names, which can be any of the following:"
96 " pitch, energy, mfccs, dmfccs, ddmfccs, mag, logmag, centroid, spread, flux."
97 " Default value is 'mfccs,dmfccs,ddmfccs'.")
98 ("windowsize,w",
99 bo::value<std::size_t>(&options->analysis_window_size_)->default_value(1024),
100 "Analysis Window Size")
101 ("hopsize,h",
102 bo::value<std::size_t>(&options->analysis_hop_size_)->default_value(256),
103 "Analysis Hop Size")
104 ("maxtreedepth,M",
105 bo::value<std::size_t>(&options->maximum_tree_depth_)->default_value(3),
106 "Maximum generated tree depth (can grow bigger through mutation).")
107 ("keepfolders,k",
108 bo::value<bool>(&options->keep_temp_folders_)->default_value(false),
109 "When set to 1 the temporary generation folders won't be deleted")
110 ("corelimit,C",
111 bo::value<std::size_t>(&options->core_limit_)->default_value(0),
112 "Limits the number of cores gpsynth will use simultaneously, 0=unlimited.")
113 ;
114
115 bo::command_line_parser parser(argument_count, arguments);
116 parser.options(description);
117 bo::variables_map config;
118 try {
119 bo::store(parser.run(), config);
120 bo::notify(config);
121 } catch (std::exception& e) {
122 std::cout << "Error parsing options: " << e.what() << ".\n";
123 PrintHelpAndQuit(description, -1);
124 }
125
126 if (config.count("help")) {
127 PrintHelpAndQuit(description);
128 }
129
130 if (config.count("workfolder") == 0) {
131 options->work_folder_ = bf::current_path().string();
132 }
133 // validate the work folder path
134 if (!bf::is_directory(options->work_folder_)) {
135 std::cout << "Work folder path '" << options->work_folder_
136 << "' doesn't exist.\n";
137 exit(-1);
138 }
139 options->work_folder_ += "/gpsynth_" + GetTimeString() + "/";
140
141 if (config.count("scpath") == 0) {
142 options->sc_app_path_ = g_default_sc_app_path;
143 }
144 if (!bf::is_directory(options->sc_app_path_)) {
145 std::cout << "SC App path '" << options->sc_app_path_
146 << "' doesn't exist.\n";
147 exit(-1);
148 }
149
150 if (options->tournament_size_ < 1) {
151 std::cout << "Tournament size must be greater than zero.\n";
152 exit(-1);
153 }
154
155 if (options->tournament_size_ > options->population_size_) {
156 std::cout << "Tournament size can not be larger than population size.\n";
157 exit(-1);
158 }
159
160 if (options->crossover_rate_ < 0 || options->crossover_rate_ > 1) {
161 std::cout << "The crossover rate should be between 0-1.\n";
162 exit(-1);
163 }
164
165 if (options->mutation_rate_ < 0 || options->mutation_rate_ > 1) {
166 std::cout << "The mutation rate should be between 0-1.\n";
167 exit(-1);
168 }
169
170 if (options->maximum_tree_depth_ < 1) {
171 std::cout << "Maximum tree depth must be greater than zero.\n";
172 exit(-1);
173 }
174
175 if (options->fitness_features_.empty()) {
176 options->fitness_features_ = "mfccs,dmfccs,ddmfccs";
177 }
178 }
179
180