diff --git a/src/aevol_create.cpp b/src/aevol_create.cpp index 605385d092b765c250b70c9e7f3420b2f439af01..35c127f1b1872568157ae12a367958742d4e7099 100644 --- a/src/aevol_create.cpp +++ b/src/aevol_create.cpp @@ -24,15 +24,6 @@ // // **************************************************************************** -/** \class - * \brief - */ - -const char* DEFAULT_PARAM_FILE_NAME = "param.in"; - -// ============================================================================ -// Includes -// ============================================================================ #include <cstdlib> #include <cstdio> #include <cstring> @@ -40,7 +31,11 @@ const char* DEFAULT_PARAM_FILE_NAME = "param.in"; #include <getopt.h> +#include <fstream> +#include <list> #include <sstream> +#include <string> +#include <tuple> #include "legacy/ExpManager.h" #include "aevol_version.h" @@ -51,81 +46,38 @@ using namespace aevol; // Helper functions void print_help(char* prog_path); -void interpret_cmd_line_options(int argc, char* argv[]); - -// Command-line option variables -static char* param_file_name = nullptr; -static char* chromosome_file_name = nullptr; +auto interpret_cmd_line_options(int argc, char* argv[]) -> std::tuple<std::string, std::string>; +auto read_sequence_file(const std::string& chromosome_file_name) -> std::list<std::string>; int main(int argc, char* argv[]) { - interpret_cmd_line_options(argc, argv); + const auto [param_file_name, chromosome_file_name] = interpret_cmd_line_options(argc, argv); // Print the hash and date of the commit used to compile this executable printf("Running aevol version %s\n", version_string); - assert(param_file_name != nullptr); // Read the parameter file - ParamValues param_values = ParamReader::read_file(param_file_name); + ParamValues param_values = ParamReader::read_file(param_file_name.c_str()); // Initialize the experiment manager exp_manager = new ExpManager(); - - // Initialize the simulation from the parameter file - int32_t lchromosome = -1; - char* chromosome = nullptr; - - if (chromosome_file_name != nullptr) { - const int max_input_chrom_size = 1000000; - char raw_chromosome[max_input_chrom_size]; - FILE* chromosome_file = fopen(chromosome_file_name, "r"); - if (chromosome_file == nullptr) { - printf("ERROR: failed to open source chromosome file %s\n", - chromosome_file_name); - exit(EXIT_FAILURE); - } - if (fgets(raw_chromosome, max_input_chrom_size, chromosome_file) == nullptr) - { - printf("ERROR: failed to read from chromosome file %s\n", - chromosome_file_name); - exit(EXIT_FAILURE); - } - lchromosome = strlen(raw_chromosome) - 1; - chromosome = new char[lchromosome]; // Warning: will become the DNA of the - // first individual created -> do not - // delete, will be freed in Dna - strncpy(chromosome, raw_chromosome, lchromosome); - printf("Loading chromosome from text file %s (%" PRId32 " base pairs) \n", - chromosome_file_name, lchromosome); - fclose(chromosome_file); + // Initialize the simulation from the parameter file (and the provided sequences if any) + if (chromosome_file_name.length() != 0) { + auto chromosomes = read_sequence_file(chromosome_file_name); + std::cout << "Loading chromosome from text file " << chromosome_file_name << " (" << chromosomes.front().length() + << " base pairs)" << std::endl; + ParamLoader::load(param_values, exp_manager, chromosomes, true); } - - if(param_file_name != nullptr) { - if (lchromosome > -1) { - ParamLoader::load(param_values, exp_manager, true, chromosome, lchromosome); - } else { - ParamLoader::load(param_values, exp_manager, true); - } + else { + ParamLoader::load(param_values, exp_manager, true); } - // 8) Save the experiment - if(exp_manager->indivs().front()==nullptr){printf("null\n");} + // Save the experiment exp_manager->Save(true); delete exp_manager; - delete[] param_file_name; } - - - - - - -/*! - \brief - -*/ void print_help(char* prog_path) { // Get the program file-name in prog_name (strip prog_path of the path) char* prog_name; // No new, it will point to somewhere inside prog_path @@ -163,7 +115,11 @@ void print_help(char* prog_path) { printf("\tload chromosome from given text file instead of generating it\n"); } -void interpret_cmd_line_options(int argc, char* argv[]) { +auto interpret_cmd_line_options(int argc, char* argv[]) -> std::tuple<std::string, std::string> { + // Command-line option variables + std::string param_file_name = "param.in"; + std::string chromosome_file_name; + // Define allowed options const char* options_list = "hVf:C:r:"; static struct option long_options_list[] = { @@ -188,13 +144,11 @@ void interpret_cmd_line_options(int argc, char* argv[]) { exit(EXIT_SUCCESS); } case 'f' : { - param_file_name = new char[strlen(optarg) + 1]; - strcpy(param_file_name, optarg); + param_file_name = optarg; break; } case 'C': { - chromosome_file_name = new char[strlen(optarg) + 1]; - strcpy(chromosome_file_name, optarg); + chromosome_file_name = optarg; break; } default : { @@ -205,9 +159,31 @@ void interpret_cmd_line_options(int argc, char* argv[]) { } } - // Set undefined command line parameters to default values - if (param_file_name == nullptr) { - param_file_name = new char[strlen(DEFAULT_PARAM_FILE_NAME) + 1]; - strcpy(param_file_name, DEFAULT_PARAM_FILE_NAME); + return std::make_tuple(param_file_name, chromosome_file_name); +} + +auto read_sequence(std::ifstream& chromosome_file, const std::string& chromosome_file_name) { + std::string chromosome; + + std::getline(chromosome_file, chromosome); + if (not chromosome_file or chromosome.length() == 0) { + Utils::ExitWithUsrMsg(std::string("failed to read from chromosome file ") + chromosome_file_name); + } + + return chromosome; +} + +auto read_sequence_file(const std::string& chromosome_file_name) -> std::list<std::string> { + assert(chromosome_file_name.length() != 0); + + std::list<std::string> chromosomes; + + std::ifstream chromosome_file(chromosome_file_name); + if (not chromosome_file) { + Utils::ExitWithUsrMsg(std::string("failed to open source chromosome file ") + chromosome_file_name); } + + chromosomes.push_back(read_sequence(chromosome_file, chromosome_file_name)); + + return chromosomes; } diff --git a/src/libaevol/io/parameters/ParamLoader.cpp b/src/libaevol/io/parameters/ParamLoader.cpp index 4c9397f1a0127b69fbf65d7e8cc9d0e82b9c8495..f75cfee647a42e5170c6505f3a2a8cc348f0c815 100644 --- a/src/libaevol/io/parameters/ParamLoader.cpp +++ b/src/libaevol/io/parameters/ParamLoader.cpp @@ -45,9 +45,14 @@ namespace aevol { void ParamLoader::load(const ParamValues& param_values, ExpManager* exp_m, - bool verbose, - char* chromosome, - int32_t lchromosome) { + bool verbose) { + load(param_values, exp_m, std::list<std::string>(), verbose); +} + +void ParamLoader::load(const ParamValues& param_values, + ExpManager* exp_m, + const std::list<std::string>& chromosomes, + bool verbose) { // Initialize master prng // Will be used to create the initial genome(s) and to generate seeds for the other prngs auto prng = std::make_shared<JumpingMT>(param_values.seed_); @@ -247,8 +252,7 @@ void ParamLoader::load(const ParamValues& param_values, Individual * indiv = NULL; int32_t id_new_indiv = 0; - if (chromosome != NULL) - { + if (not chromosomes.empty()) { printf("Option -c is used: chromosome will be loaded from a text file\n"); #ifndef __REGUL Individual * indiv = new Individual(exp_m, @@ -275,7 +279,14 @@ void ParamLoader::load(const ParamValues& param_values, #endif - indiv->add_GU(chromosome, lchromosome); + // Make a copy of the provided chromosome and transfer ownership to the genetic unit we create with it + assert(chromosomes.size() == 1); + auto& chromosome = chromosomes.front(); + char* chromosome_copy = new char[chromosome.length() + 1]; + strncpy(chromosome_copy, chromosome.c_str(), chromosome.length() + 1); + indiv->add_GU(chromosome_copy, chromosome.length()); + chromosome_copy = nullptr; + indiv->genetic_unit_nonconst(0).set_min_gu_length(param_values.chromosome_minimal_length_); indiv->genetic_unit_nonconst(0).set_max_gu_length(param_values.chromosome_maximal_length_); diff --git a/src/libaevol/io/parameters/ParamLoader.h b/src/libaevol/io/parameters/ParamLoader.h index de423c1f10f5840f2892b60fb6aca920617be86f..51cbac6b53a1024dda78097081fd3a801f2c58a5 100644 --- a/src/libaevol/io/parameters/ParamLoader.h +++ b/src/libaevol/io/parameters/ParamLoader.h @@ -31,6 +31,8 @@ // Includes // ================================================================= #include <cinttypes> +#include <list> +#include <string> #include "legacy/ExpManager.h" #include "ParamValues.h" @@ -58,9 +60,11 @@ class ParamLoader { // ========================================================================= static void load(const ParamValues& param_values, ExpManager* exp_m, - bool verbose = false, - char* chromosome = nullptr, - int32_t lchromosome = 0); + bool verbose = false); + static void load(const ParamValues& param_values, + ExpManager* exp_m, + const std::list<std::string>& chromosomes, + bool verbose = false); protected: };