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