diff --git a/src/cats/CMakeLists.txt b/src/cats/CMakeLists.txt index a2c84bc7ae9ebf8a4bec0c5e1bc5476fe282d7f8..f55fd2d79f16213b2789123782a9011b39211692 100644 --- a/src/cats/CMakeLists.txt +++ b/src/cats/CMakeLists.txt @@ -39,7 +39,7 @@ include_directories(${GDAL_INCLUDE_DIR}) include_directories(${GSL_INCLUDE_DIR}) include_directories(${MPI_C_INCLUDE_PATH}) -add_library(libcats STATIC "" stats/statistics.c stats/statistics.h data/cats_global.c ../cats_windows.h test/test_ini.c test/test_ini.h debug/debug_vital_rates.c debug/debug_vital_rates.h) +add_library(libcats STATIC "" stats/statistics.c stats/statistics.h data/cats_global.c ../cats_windows.h test/test_ini.c test/test_ini.h debug/debug_vital_rates.c debug/debug_vital_rates.h overlays/overlay_resources.c overlays/overlay_resources.h) target_include_directories(libcats PUBLIC ".") target_sources(libcats PRIVATE diff --git a/src/cats/cats_global.h b/src/cats/cats_global.h index 1795b433c170f28a84e05a22e432899d6dabe49f..cc7a794edd752308d9cc0cce1078686bcdc1b6a4 100644 --- a/src/cats/cats_global.h +++ b/src/cats/cats_global.h @@ -98,6 +98,9 @@ struct cats_debug_options { FILE *misc_debug_file; /// @brief global variable: file handle for a debug file documenting a single cells }; - +static void abort_implemented(const char *name) { + fprintf(stderr, "function '%s' is not yet implemented\n", name); + exit_cats(EXIT_FAILURE); +} #endif //CATS_GLOBAL_H_ diff --git a/src/cats/configuration/configuration.c b/src/cats/configuration/configuration.c index eb3ca901e97a896bd3412c402d91dbf8d647dba9..6841aaf8e734673f2111fa02d7cdcfd47576c8aa 100644 --- a/src/cats/configuration/configuration.c +++ b/src/cats/configuration/configuration.c @@ -79,6 +79,10 @@ void init_cats_configuration(struct cats_configuration *conf) conf->performance_file = NULL; conf->grid_count = 1; + conf->overlays.custom_overlay_count = 0; + conf->overlays.custom_overlays = NULL; + conf->overlays.registered_custom_overlay_names = new_string_array(); + #ifdef USEMPI conf->mpi.world_size = 1; diff --git a/src/cats/configuration/load_configuration_overlays.c b/src/cats/configuration/load_configuration_overlays.c index 074c1c9e5f51cc6a8cea1d85935aaa604f67eeb2..bbacc6f7e1b1828624bd3efdbb463d9cb2e68028 100644 --- a/src/cats/configuration/load_configuration_overlays.c +++ b/src/cats/configuration/load_configuration_overlays.c @@ -52,25 +52,34 @@ void load_overlay_configuration(struct cats_configuration *conf, struct cats_ini char *type_name = NULL; load_conf_value(true, ini, overlay_section, "type", &type_name); - enum overlay_type type = get_overlay_type_from_name(type_name); - free(type_name); + enum overlay_type type = get_overlay_type_from_name(type_name, conf->overlays.registered_custom_overlay_names); + + struct cats_overlay *overlay = NULL; + + if (type < OL_CUSTOM && type > OL_NONE) { + overlay = &conf->overlays.overlay[type]; + } else if (type == OL_CUSTOM) { + overlay = add_overlay(conf, type_name); + } - conf->overlays.overlay[type].enabled = true; - load_conf_value(true, ini, overlay_section, "filename pattern", &conf->overlays.overlay[type].filename); - load_conf_value(false, ini, overlay_section, "reload interval", &conf->overlays.overlay[type].reload_interval); + overlay->enabled = true; - if (conf->overlays.overlay[type].reload_interval > 0) { - conf->overlays.overlay[type].is_static = false; + + load_conf_value(true, ini, overlay_section, "filename pattern", &overlay->filename); + load_conf_value(false, ini, overlay_section, "reload interval", &overlay->reload_interval); + + if (overlay->reload_interval > 0) { + overlay->is_static = false; } else { - conf->overlays.overlay[type].is_static = true; + overlay->is_static = true; } conf->overlays.have_overlays = true; long double default_value = NAN; - conf->overlays.overlay[type].name = strdup(overlay_name); + overlay->name = strdup(overlay_name); switch (type) { case OL_EXCLUSION: @@ -78,18 +87,21 @@ void load_overlay_configuration(struct cats_configuration *conf, struct cats_ini case OL_HABITAT_TYPE_CC: load_conf_value(true, ini, overlay_section, "table filename", - &conf->overlays.overlay[type].filename_aux); + &overlay->filename_aux); load_conf_value(true, ini, overlay_section, "default value", &default_value); - conf->overlays.overlay[type].aux_data = load_habitat_layer_cc_aux( - conf->overlays.overlay[type].filename_aux, + overlay->aux_data = load_habitat_layer_cc_aux( + overlay->filename_aux, (double) default_value); break; + case OL_RESOURCE: + break; case OL_NONE: case OL_MAX: - default: + case OL_CUSTOM: log_message(LOG_ERROR, "unknown or unhandled overlay type '%s'", overlay_name); exit(EXIT_FAILURE); } + free(type_name); } free_string_array(&overlay_names); diff --git a/src/cats/overlays/overlay_resources.c b/src/cats/overlays/overlay_resources.c new file mode 100644 index 0000000000000000000000000000000000000000..744523a07b5ef6f130e51c7eaf7b7fc9de3272db --- /dev/null +++ b/src/cats/overlays/overlay_resources.c @@ -0,0 +1,34 @@ +// +// Created by andreas on 08/02/23. +// + +#include <assert.h> +#include <math.h> +#include "overlay_resources.h" +#include "memory/arrays.h" + + +struct cats_2d_array_double *translate_resources(const struct cats_2d_array_double *data) +{ + struct cats_2d_array_double *result = new_2d_array_double(data->dimension); + + const cats_dt_coord rows = data->dimension.rows; + const cats_dt_coord cols = data->dimension.cols; + + for (cats_dt_coord row = 0; row < rows; row++) { + for (cats_dt_coord col = 0; col < cols; col++) { + + double value = data->data[row][col]; + + if (isnan(value)) { + result->data[row][col] = 0.0; + } else { + + if (value <0 ) value = 0; + result->data[row][col] = value; + } + } + } + + return result; +} diff --git a/src/cats/overlays/overlay_resources.h b/src/cats/overlays/overlay_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..012b5acdd11a3310cad339e5a391010d71be8a93 --- /dev/null +++ b/src/cats/overlays/overlay_resources.h @@ -0,0 +1,8 @@ +// +// Created by andreas on 08/02/23. +// + +#ifndef CATS_OVERLAY_RESOURCES_H +#define CATS_OVERLAY_RESOURCES_H +struct cats_2d_array_double *translate_resources(const struct cats_2d_array_double *data); +#endif //CATS_OVERLAY_RESOURCES_H diff --git a/src/cats/overlays/overlays.c b/src/cats/overlays/overlays.c index d2e035b146dc762647d91a9adfd47a9dac6882bc..cb5ef96f13088f8a46131e921e17553613793603 100644 --- a/src/cats/overlays/overlays.c +++ b/src/cats/overlays/overlays.c @@ -33,6 +33,7 @@ #include "grids/cats_grid.h" #include "overlay_habitat_type_cc.h" #include "overlay_exclusion.h" +#include "overlay_resources.h" const char *get_overlay_name(enum overlay_type type) @@ -42,10 +43,12 @@ const char *get_overlay_name(enum overlay_type type) return "exclusion"; case OL_HABITAT_TYPE_CC: return "habitat_type_cc"; - + case OL_RESOURCE: + return "resources"; + break; case OL_NONE: case OL_MAX: - default: + case OL_CUSTOM: break; } @@ -74,14 +77,30 @@ void cleanup_overlays(struct cats_overlays *overlays) } +struct cats_overlay *add_overlay(struct cats_configuration *conf, const char *name) +{ + struct cats_overlay *overlay = NULL; + abort_implemented(__func__); + return overlay; + +} + -enum overlay_type get_overlay_type_from_name(const char *name) +enum overlay_type get_overlay_type_from_name(const char *name, const struct string_array *registered_names) { if (!name) return OL_NONE; if (!strcmp(name, "exclusion")) return OL_EXCLUSION; if (!strcmp(name, "habitat carrying capacity")) return OL_HABITAT_TYPE_CC; + if (registered_names != NULL) { + for (int32_t i = 0; i < registered_names->count; i++) { + if (!strcmp(name, registered_names->string[i])) { + return OL_CUSTOM; + } + } + } + log_message(LOG_ERROR, "%s: unknown overlay type '%s'", __func__, name); exit(EXIT_FAILURE); } @@ -138,9 +157,15 @@ void load_overlay_from_file(struct cats_configuration *conf, enum overlay_type t case OL_CUSTOM: log_message(LOG_ERROR, "OL_CUSTOM not implemented yet"); exit(EXIT_FAILURE); + case OL_RESOURCE: + if (conf->overlays.resources) free_cats_grid(&conf->overlays.resources); + conf->overlays.resources = translate_resources(raw_values); + break; + case OL_NONE: case OL_MAX: break; + } free_cats_grid(&raw_values); diff --git a/src/cats/overlays/overlays.h b/src/cats/overlays/overlays.h index e3dc83fb8236d51c47128606117498f7b65e19d7..cc1f4a8fffa366c36dde9395bb9a2cbf94da9ed9 100644 --- a/src/cats/overlays/overlays.h +++ b/src/cats/overlays/overlays.h @@ -36,7 +36,8 @@ enum overlay_type { OL_NONE = 0, OL_EXCLUSION = 1, OL_HABITAT_TYPE_CC = 2, - OL_CUSTOM = 3, + OL_RESOURCE = 3, + OL_CUSTOM = 4, OL_MAX }; @@ -58,8 +59,8 @@ struct cats_overlay { char *filename_loaded; void *aux_data; - - + struct cats_2d_array_char *data_char; + struct cats_2d_array_double *data_double; cats_dt_coord cols; ///< number of rows (same as grid, for convenience only) cats_dt_coord rows; ///< number of columns (same as grid, for convenience only) @@ -74,19 +75,15 @@ struct cats_overlays { bool have_overlays; ///< do we actually have overlays? True if at least one overlay is enabled. struct cats_overlay overlay[OL_MAX]; - /* - bool enabled[OL_MAX]; ///< which of the overlay types are enabled? - bool is_static[OL_MAX]; ///< do the overlays remain constant over time? - int32_t reload_interval[OL_MAX]; ///< how often do overlays change? - - char *name[OL_MAX]; ///< overlay names (as specified in the configuration file) - char *filename[OL_MAX]; ///< overlay filenames or filename patterns - char *filename_aux[OL_MAX]; - char *filename_loaded[OL_MAX]; - void *aux_data[OL_MAX]; - */ + struct cats_2d_array_char *exclusion; struct cats_2d_array_double *habitat_cc; + struct cats_2d_array_double *resources; + + struct cast_overlay *custom_overlays; + int32_t custom_overlay_count; + + struct string_array *registered_custom_overlay_names; cats_dt_coord cols; ///< number of rows (same as grid, for convenience only) cats_dt_coord rows; ///< number of columns (same as grid, for convenience only) @@ -97,7 +94,7 @@ void cleanup_overlays(struct cats_overlays *overlays); const char *get_overlay_name(enum overlay_type type); -enum overlay_type get_overlay_type_from_name(const char *name); +enum overlay_type get_overlay_type_from_name(const char *name, const struct string_array *registered_names); bool @@ -106,5 +103,5 @@ update_overlay_if_needed(struct cats_configuration *conf, int32_t time, enum ove void reset_overlay(struct cats_overlays *overlay); void load_overlay_from_file(struct cats_configuration *conf, enum overlay_type type, char *filename); - +struct cats_overlay *add_overlay(struct cats_configuration *conf, const char *name); #endif \ No newline at end of file diff --git a/src/modules/butterflies/butterflies_inline.h b/src/modules/butterflies/butterflies_inline.h new file mode 100644 index 0000000000000000000000000000000000000000..e13772480fe6c716b8c39e90222e699118424016 --- /dev/null +++ b/src/modules/butterflies/butterflies_inline.h @@ -0,0 +1,8 @@ +// +// Created by andreas on 08/02/23. +// + +#ifndef CATS_BUTTERFLIES_INLINE_H +#define CATS_BUTTERFLIES_INLINE_H + +#endif //CATS_BUTTERFLIES_INLINE_H