Skip to content
Snippets Groups Projects
Commit 35c4d20f authored by Andreas Gattringer's avatar Andreas Gattringer
Browse files

added new command line options (and corresponding functionality)

- log file
- output (summary file)
- qiuiet
parent 751a5438
No related branches found
No related tags found
No related merge requests found
...@@ -83,7 +83,7 @@ int main(int argc, char **argv) ...@@ -83,7 +83,7 @@ int main(int argc, char **argv)
print_version_info(); print_version_info();
print_runtime_information(argc, argv); print_runtime_information(argc, argv);
struct program_options options = check_cats_main_arguments(argc, argv); struct program_options options = check_cats_main_arguments(argc, argv);
logging_initialize(options.default_log_level, &global.time_info); logging_initialize(options.default_log_level, &global.time_info, options.log_file, options.quiet);
#ifdef USEMPI #ifdef USEMPI
mpi_update(); mpi_update();
#endif #endif
...@@ -115,7 +115,7 @@ int main(int argc, char **argv) ...@@ -115,7 +115,7 @@ int main(int argc, char **argv)
cleanup_debugging(&cats_debug, conf); cleanup_debugging(&cats_debug, conf);
cleanup_configuration(&conf); cleanup_configuration(&conf);
// FIXME cleanup_logging
free(global.program_name); free(global.program_name);
fflush(stdout); fflush(stdout);
......
...@@ -61,12 +61,22 @@ void print_usage(const char *name, const char *error_msg) ...@@ -61,12 +61,22 @@ void print_usage(const char *name, const char *error_msg)
" -h, --help Show this message\n"); " -h, --help Show this message\n");
fprintf(stderr, fprintf(stderr,
" -v, --version Show version information\n"); " -v, --version Show version information\n");
fprintf(stderr,
" -q, --quiet Don't output logging output to console (log file is not affected)\n");
fprintf(stderr, fprintf(stderr,
" -l, --log-level=<level> Default log level (default info). Allowed values: debug, info, important, warning, error\n"); " -l, --log-level=<level> Default log level (default info). Allowed values: debug, info, important, warning, error\n");
fprintf(stderr, fprintf(stderr,
" --%s Output additional information in JSON format to stderr, prefixed with 'JSON::' ( e.g. for use with a GUI)\n", " --%s Output additional information in JSON format to stderr, prefixed with 'JSON::' ( e.g. for use with a GUI)\n",
OPTION_JSON_NAME); OPTION_JSON_NAME);
fprintf(stderr,
" --%s <logfile> Save program output to log file <log-file>\n",
OPTION_LOG_FILE_NAME);
fprintf(stderr,
" --%s <summary-file> Save a list of output filenames to the csv file <summary-file>\n",
OPTION_SUMMARY_FILE_NAME);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "[Hybrid mode only] Scale factor options:\n"); fprintf(stderr, "[Hybrid mode only] Scale factor options:\n");
...@@ -88,8 +98,7 @@ void print_usage(const char *name, const char *error_msg) ...@@ -88,8 +98,7 @@ void print_usage(const char *name, const char *error_msg)
" --%s <years> Override simulation length of scale factor test " " --%s <years> Override simulation length of scale factor test "
"(default: 10000) \n", "(default: 10000) \n",
OPTION_SCALE_LAMBDA_YEARS_NAME); OPTION_SCALE_LAMBDA_YEARS_NAME);
fprintf(stderr, " --%s Run a simulation on a virtual suitability grid", OPTION_SCALE_GRADIENT_NAME); fprintf(stderr, " --%s Run a simulation on a virtual suitability grid\n", OPTION_SCALE_GRADIENT_NAME);
fprintf(stderr, "\nRandom number options:\n"); fprintf(stderr, "\nRandom number options:\n");
fprintf(stderr, fprintf(stderr,
" --%s Which fraction [0.0, 1.0] of random quantities is rounded instead of drawn from a poisson distribution. Default %f\n", " --%s Which fraction [0.0, 1.0] of random quantities is rounded instead of drawn from a poisson distribution. Default %f\n",
......
...@@ -35,10 +35,12 @@ static struct option longopts[] = { ...@@ -35,10 +35,12 @@ static struct option longopts[] = {
{"log-level", required_argument, NULL, 'l',}, {"log-level", required_argument, NULL, 'l',},
{"version", no_argument, NULL, 'v',}, {"version", no_argument, NULL, 'v',},
{"help", no_argument, NULL, 'h',}, {"help", no_argument, NULL, 'h',},
{"quiet", no_argument, NULL, 'q'},
{OPTION_SCALE_LAMBDA_ONLY_NAME, no_argument, NULL, OPTION_SCALE_LAMBDA_ONLY}, {OPTION_SCALE_LAMBDA_ONLY_NAME, no_argument, NULL, OPTION_SCALE_LAMBDA_ONLY},
{OPTION_SCALE_LAMBDA_TEST_NAME, no_argument, NULL, OPTION_SCALE_LAMBDA_TEST}, {OPTION_SCALE_LAMBDA_TEST_NAME, no_argument, NULL, OPTION_SCALE_LAMBDA_TEST},
{OPTION_SCALE_GRADIENT_NAME, no_argument, NULL, OPTION_SCALE_GRADIENT}, {OPTION_SCALE_GRADIENT_NAME, no_argument, NULL, OPTION_SCALE_GRADIENT},
{OPTION_LOG_FILE_NAME, required_argument, NULL, OPTION_LOG_FILE},
{OPTION_SUMMARY_FILE_NAME, required_argument, NULL, OPTION_SUMMARY_FILE},
{OPTION_JSON_NAME, no_argument, NULL, OPTION_JSON}, {OPTION_JSON_NAME, no_argument, NULL, OPTION_JSON},
{OPTION_DEBUG_MPI_NAME, no_argument, NULL, OPTION_DEBUG_MPI}, {OPTION_DEBUG_MPI_NAME, no_argument, NULL, OPTION_DEBUG_MPI},
{OPTION_SCALE_LAMBDA_CC_NAME, required_argument, NULL, OPTION_SCALE_LAMBDA_CC}, {OPTION_SCALE_LAMBDA_CC_NAME, required_argument, NULL, OPTION_SCALE_LAMBDA_CC},
...@@ -63,6 +65,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv) ...@@ -63,6 +65,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv)
{ {
struct program_options options = { struct program_options options = {
.replicate = 0, .replicate = 0,
.summary_file = NULL,
.log_file = NULL,
.quiet = false,
.direct_scale_factor = -1, .direct_scale_factor = -1,
.default_log_level = LOG_INFO, .default_log_level = LOG_INFO,
.lambda_test = false, .lambda_test = false,
...@@ -88,7 +93,7 @@ struct program_options check_cats_main_arguments(int argc, char **argv) ...@@ -88,7 +93,7 @@ struct program_options check_cats_main_arguments(int argc, char **argv)
int error = 0; int error = 0;
// FIXME unify error messages, start with Error: // FIXME unify error messages, start with Error:
while ((opt = getopt_long(argc, argv, "s:r:l:v:ho:", while ((opt = getopt_long(argc, argv, "qs:r:l:v:ho:",
longopts, &optind)) != -1) { longopts, &optind)) != -1) {
bool success; bool success;
...@@ -107,6 +112,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv) ...@@ -107,6 +112,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv)
success = string_to_double(optarg, &options.direct_scale_factor); success = string_to_double(optarg, &options.direct_scale_factor);
if (!success) { log_message(LOG_WARNING, "unable to convert %s to number", optarg); } if (!success) { log_message(LOG_WARNING, "unable to convert %s to number", optarg); }
break; break;
case 'q':
options.quiet = true;
break;
case 'l': case 'l':
...@@ -142,6 +150,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv) ...@@ -142,6 +150,9 @@ struct program_options check_cats_main_arguments(int argc, char **argv)
case OPTION_SCALE_LAMBDA_TEST: case OPTION_SCALE_LAMBDA_TEST:
options.lambda_test = true; options.lambda_test = true;
break; break;
case OPTION_SUMMARY_FILE:
options.summary_file = strdup(optarg);
break;
case OPTION_SCALE_LAMBDA_CC: case OPTION_SCALE_LAMBDA_CC:
conversion_success = string_to_integer(optarg, &options.lambda_cc); conversion_success = string_to_integer(optarg, &options.lambda_cc);
if (!conversion_success) { if (!conversion_success) {
...@@ -207,6 +218,10 @@ struct program_options check_cats_main_arguments(int argc, char **argv) ...@@ -207,6 +218,10 @@ struct program_options check_cats_main_arguments(int argc, char **argv)
error += 1; error += 1;
} }
break; break;
case OPTION_LOG_FILE:
options.log_file = strdup(optarg);
break;
case OPTION_POISSON_DAMPENING_MIN: case OPTION_POISSON_DAMPENING_MIN:
conversion_success = string_to_float(optarg, &value); conversion_success = string_to_float(optarg, &value);
if (conversion_success) { if (conversion_success) {
......
...@@ -47,6 +47,11 @@ ...@@ -47,6 +47,11 @@
#define OPTION_DEBUG_VR 5040 #define OPTION_DEBUG_VR 5040
#define OPTION_DEBUG_VR_NAME "debug-vital-rates" #define OPTION_DEBUG_VR_NAME "debug-vital-rates"
#define OPTION_LOG_FILE 1111
#define OPTION_LOG_FILE_NAME "log-file"
#define OPTION_SUMMARY_FILE 1112
#define OPTION_SUMMARY_FILE_NAME "summary-file"
#define OPTION_JSON 8000 #define OPTION_JSON 8000
#define OPTION_JSON_NAME "json" #define OPTION_JSON_NAME "json"
...@@ -81,6 +86,9 @@ ...@@ -81,6 +86,9 @@
struct program_options { struct program_options {
char *summary_file;
char *log_file;
bool quiet;
char *configuration_file; char *configuration_file;
int32_t replicate; int32_t replicate;
bool no_input_rasters_required; bool no_input_rasters_required;
......
...@@ -217,6 +217,10 @@ void cleanup_configuration(struct cats_configuration **conf_orig) ...@@ -217,6 +217,10 @@ void cleanup_configuration(struct cats_configuration **conf_orig)
struct cats_configuration *conf = *conf_orig; struct cats_configuration *conf = *conf_orig;
// THIS HAS TO BE THE FIRST ENTRY // THIS HAS TO BE THE FIRST ENTRY
cleanup_module_registry(&conf->modules); cleanup_module_registry(&conf->modules);
if (conf->summary_file) {
fclose(conf->summary_file);
free(conf->summary_file_name);
}
if (conf->statsfile_global) fclose(conf->statsfile_global); if (conf->statsfile_global) fclose(conf->statsfile_global);
free(conf->file_content); free(conf->file_content);
......
...@@ -124,7 +124,12 @@ struct cats_environment_collection { ...@@ -124,7 +124,12 @@ struct cats_environment_collection {
/// @brief Contains the configuration and state of the simulation /// @brief Contains the configuration and state of the simulation
struct cats_configuration { struct cats_configuration {
char *output_directory; char *output_directory;
char *summary_file_name;
FILE *summary_file;
char *log_file_name;
bool quiet;
struct cats_global *global; struct cats_global *global;
struct program_options command_line_options; struct program_options command_line_options;
bool debug_enabled; bool debug_enabled;
......
...@@ -66,7 +66,16 @@ load_configuration_from_file(const char *filename, const struct program_options ...@@ -66,7 +66,16 @@ load_configuration_from_file(const char *filename, const struct program_options
// create empty configuration // create empty configuration
struct cats_configuration *conf = new_configuration(); struct cats_configuration *conf = new_configuration();
conf->quiet = command_line_options->quiet;
conf->log_file_name = command_line_options->log_file;
conf->summary_file = NULL;
conf->summary_file_name = command_line_options->summary_file;
if (conf->summary_file_name) {
conf->summary_file = fopen(conf->summary_file_name, "w");
ENSURE_FILE_OPENED(conf->summary_file, conf->summary_file_name)
fprintf(conf->summary_file, "type,path,year\n");
if (conf->log_file_name) fprintf(conf->summary_file, "log,%s,\n",conf->log_file_name);
}
#ifdef USEMPI #ifdef USEMPI
mpi_setup(conf); mpi_setup(conf);
#endif #endif
......
...@@ -54,6 +54,7 @@ void init_cats_species_param(struct cats_species_param *param) ...@@ -54,6 +54,7 @@ void init_cats_species_param(struct cats_species_param *param)
param->initial_population.suitability_threshold = 0.0; param->initial_population.suitability_threshold = 0.0;
param->initial_population.set_to_cc = true; param->initial_population.set_to_cc = true;
param->initial_population.adjusted = false; param->initial_population.adjusted = false;
init_cats_vital_rates(param->vital_rates); init_cats_vital_rates(param->vital_rates);
} }
\ No newline at end of file
...@@ -343,6 +343,7 @@ void initialize_grid_stats(struct cats_grid *grid, struct cats_configuration *co ...@@ -343,6 +343,7 @@ void initialize_grid_stats(struct cats_grid *grid, struct cats_configuration *co
remove(filename); remove(filename);
grid->stats.file = fopen(filename, "a+"); grid->stats.file = fopen(filename, "a+");
ENSURE_FILE_OPENED(grid->stats.file, filename) ENSURE_FILE_OPENED(grid->stats.file, filename)
if (conf->summary_file) fprintf(conf->summary_file, "grid-stats,%s,\n",filename);
free(filename); free(filename);
write_grid_stats(conf, grid, true); write_grid_stats(conf, grid, true);
fflush(grid->stats.file); fflush(grid->stats.file);
......
...@@ -70,6 +70,8 @@ void *save_population_to_gdal(struct cats_grid *grid, struct cats_configuration ...@@ -70,6 +70,8 @@ void *save_population_to_gdal(struct cats_grid *grid, struct cats_configuration
(cats_dt_population) get_vital_rate_maximum(&grid->param.carrying_capacity)); (cats_dt_population) get_vital_rate_maximum(&grid->param.carrying_capacity));
fflush(stderr); fflush(stderr);
} }
if (conf->summary_file) fprintf(conf->summary_file, "population,%s,%d\n",filename, conf->time.year_current);
free(filename); free(filename);
return 0; return 0;
} }
......
...@@ -107,7 +107,7 @@ int32_t register_module(struct cats_configuration *conf, const char *module_name ...@@ -107,7 +107,7 @@ int32_t register_module(struct cats_configuration *conf, const char *module_name
int32_t module_id = conf->modules.count; int32_t module_id = conf->modules.count;
CATS_MODULE_ID_INTERNAL = module_id; CATS_MODULE_ID_INTERNAL = module_id;
CATS_MODULE_DATA_INTERNAL = module_data; CATS_MODULE_DATA_INTERNAL = module_data;
logging_initialize(conf->command_line_options.default_log_level, &conf->global->time_info); logging_initialize(conf->command_line_options.default_log_level, &conf->global->time_info, conf->log_file_name, conf->quiet);
logging_set_module_name(module_name); logging_set_module_name(module_name);
conf->modules.module[module_id].flags = module_flags; conf->modules.module[module_id].flags = module_flags;
......
...@@ -49,6 +49,8 @@ void initialize_global_stats(struct cats_configuration *conf) ...@@ -49,6 +49,8 @@ void initialize_global_stats(struct cats_configuration *conf)
conf->statsfile_global = fopen(filename, "a+"); conf->statsfile_global = fopen(filename, "a+");
ENSURE_FILE_OPENED(conf->statsfile_global, filename) ENSURE_FILE_OPENED(conf->statsfile_global, filename)
if (conf->summary_file) fprintf(conf->summary_file, "global-stats,%s,\n",filename);
write_global_stats(conf, NULL, true); write_global_stats(conf, NULL, true);
......
...@@ -30,13 +30,17 @@ ...@@ -30,13 +30,17 @@
#include "logging.h" #include "logging.h"
#include "memory/cats_memory.h" #include "memory/cats_memory.h"
#include "cats_time/cats_time.h" #include "cats_time/cats_time.h"
#include "misc/misc.h"
enum cats_log_level internal_current_log_level = LOG_INFO; enum cats_log_level internal_current_log_level = LOG_INFO;
int32_t logging_mpi_rank = -1; int32_t logging_mpi_rank = -1;
struct cats_time cats_logging_start_time; struct cats_time cats_logging_start_time;
FILE *cats_log_file = NULL;
char *cats_log_file_name = NULL;
const char *logging_module_name = NULL; const char *logging_module_name = NULL;
bool time_initialized = false; bool time_initialized = false;
bool logging_quiet = false;
const char *get_log_level_name(enum cats_log_level level) const char *get_log_level_name(enum cats_log_level level)
...@@ -106,15 +110,21 @@ void set_log_level(enum cats_log_level new_level) ...@@ -106,15 +110,21 @@ void set_log_level(enum cats_log_level new_level)
// - mpi world rank can be added later // - mpi world rank can be added later
// FIXME: if start_time is NULL, generate // FIXME: if start_time is NULL, generate
void logging_initialize(enum cats_log_level level, const struct cats_time *start_time) void logging_initialize(enum cats_log_level level, const struct cats_time *start_time, const char *log_file_name, bool quiet)
{ {
set_log_level(level); set_log_level(level);
logging_quiet = quiet;
if (start_time != NULL) { if (start_time != NULL) {
cats_logging_start_time = *start_time; cats_logging_start_time = *start_time;
time_initialized = true; time_initialized = true;
} }
if (log_file_name != NULL) {
cats_log_file_name = strdup(log_file_name);
cats_log_file = fopen(log_file_name, "w");
ENSURE_FILE_OPENED(cats_log_file, cats_log_file_name)
}
} }
...@@ -185,13 +195,15 @@ void log_msg(const char *msg, enum cats_log_level loglevel) ...@@ -185,13 +195,15 @@ void log_msg(const char *msg, enum cats_log_level loglevel)
if (loglevel < internal_current_log_level) return; if (loglevel < internal_current_log_level) return;
if (loglevel == LOG_EMPTY) { if (loglevel == LOG_EMPTY) {
fprintf(stdout, "\n"); if (! logging_quiet) fprintf(stdout, "\n");
if (cats_log_file != NULL) fprintf(stdout, "\n");
return; return;
} }
const char *color = get_log_level_color(loglevel); const char *color = get_log_level_color(loglevel);
if (loglevel == LOG_MARK) { if (loglevel == LOG_MARK) {
fprintf(stdout, "%s%s%s\n", color, msg, C_RESET); if (! logging_quiet) fprintf(stdout, "%s%s%s\n", color, msg, C_RESET);
if (cats_log_file != NULL) fprintf(cats_log_file, "%s%s%s\n", color, msg, C_RESET);
return; return;
} }
const char *log_default = "unknown"; const char *log_default = "unknown";
...@@ -204,22 +216,31 @@ void log_msg(const char *msg, enum cats_log_level loglevel) ...@@ -204,22 +216,31 @@ void log_msg(const char *msg, enum cats_log_level loglevel)
if (logging_mpi_rank >= 0) { if (logging_mpi_rank >= 0) {
fprintf(stdout, "(%02d)::", logging_mpi_rank); if (! logging_quiet) fprintf(stdout, "(%02d)::", logging_mpi_rank);
if (cats_log_file != NULL) fprintf(cats_log_file, "(%02d)::", logging_mpi_rank);
} }
if (time_initialized) { if (time_initialized) {
double secs = seconds_monotonic_since(&cats_logging_start_time); double secs = seconds_monotonic_since(&cats_logging_start_time);
if (cats_log_file != NULL) {
fprintf(stdout, "% 16.4f::", secs); fprintf(cats_log_file, "% 16.4f::", secs);
}
if (! logging_quiet) fprintf(stdout, "% 16.4f::", secs);
} else { } else {
fprintf(stdout, " ::"); if (cats_log_file != NULL) {
fprintf(cats_log_file, " ::");
}
if (! logging_quiet) fprintf(stdout, " ::");
} }
if (logging_module_name != NULL) { if (logging_module_name != NULL) {
fprintf(stdout, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET); if (! logging_quiet) fprintf(stdout, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET);
if (cats_log_file) fprintf(cats_log_file, "%s%s::[%s] %s%s\n", color, loglevel_name, logging_module_name, msg, C_RESET);
} else { } else {
fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET); if (! logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
if (cats_log_file) fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
} }
} }
...@@ -237,10 +258,13 @@ void log_msg_simple(const char *msg, enum cats_log_level loglevel) ...@@ -237,10 +258,13 @@ void log_msg_simple(const char *msg, enum cats_log_level loglevel)
const char *color = get_log_level_color(loglevel); const char *color = get_log_level_color(loglevel);
if (logging_mpi_rank >= 0) { if (logging_mpi_rank >= 0) {
fprintf(stdout, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET); if (! logging_quiet) fprintf(stdout, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET);
if (cats_log_file != NULL) fprintf(cats_log_file, "(%02d)%s%s: %s%s", logging_mpi_rank, color, loglevel_name, msg, C_RESET);
} else { } else {
if (! logging_quiet) fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
if (cats_log_file != NULL) fprintf(cats_log_file, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
fprintf(stdout, "%s%s::%s%s\n", color, loglevel_name, msg, C_RESET);
} }
} }
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#ifndef CATS_LOGGING_H_ #ifndef CATS_LOGGING_H_
#define CATS_LOGGING_H_ #define CATS_LOGGING_H_
#include <stdbool.h>
#include "cats_defs.h" #include "cats_defs.h"
#include <time.h> #include <time.h>
#include "cats_time/cats_time.h" #include "cats_time/cats_time.h"
...@@ -56,7 +56,7 @@ enum cats_log_level { ...@@ -56,7 +56,7 @@ enum cats_log_level {
LOG_UNKNOWN LOG_UNKNOWN
}; };
void logging_initialize(enum cats_log_level level, const struct cats_time *start_time); void logging_initialize(enum cats_log_level level, const struct cats_time *start_time, const char *log_file_name, bool quiet);
void logging_set_mpi_rank(int mpi_world_rank); void logging_set_mpi_rank(int mpi_world_rank);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment