diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 334dac1cf7d5a79819550fbce2f0561c27f82fe5..2bf1b6ad8c63fa00570e3adfeff8cf18fcb32a36 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(cats_strings) add_subdirectory(cats_ini) add_subdirectory(cats_csv) add_subdirectory(modules/cats_test_module) +add_subdirectory(modules/butterflies) \ No newline at end of file diff --git a/src/modules/butterflies/CMakeLists.txt b/src/modules/butterflies/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a9f3c1f0770d1bda90df1e7573698c7375479643 --- /dev/null +++ b/src/modules/butterflies/CMakeLists.txt @@ -0,0 +1,17 @@ +add_library(cats-butterflies SHARED "" butterfly_actions.c butterfly_actions.h butterfly_vital_rates.c butterfly_vital_rates.h module.h butterflies_dispersal.c butterflies_dispersal.h butterflies_populations.c butterflies_populations.h) + +target_include_directories(cats-butterflies PUBLIC ".") + +target_sources(cats-butterflies + PRIVATE + butterflies_main.c butterflies_main.h random_walk.c random_walk.h + + PUBLIC + + + ) + + + +set_property(TARGET cats-butterflies PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(cats-butterflies cats_logging libcats) diff --git a/src/modules/butterflies/butterflies_dispersal.c b/src/modules/butterflies/butterflies_dispersal.c new file mode 100644 index 0000000000000000000000000000000000000000..a30bbf1f40d012e77d6eb13c38436b0f7e3d9112 --- /dev/null +++ b/src/modules/butterflies/butterflies_dispersal.c @@ -0,0 +1,16 @@ +// +// Created by gattringera on 21/11/22. +// +#include <math.h> +#include "butterflies_main.h" +#include "butterflies_dispersal.h" +#include "configuration/configuration.h" +#include "modules/module_header.h" + +void add_dispersed_eggs(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, float eggs) +{ + //struct conf_data_butterflies *module_conf = CATS_MODULE_DATA; + const int module_id = CATS_MODULE_ID; + struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data; + data->eggs[row][col] += eggs; +} \ No newline at end of file diff --git a/src/modules/butterflies/butterflies_dispersal.h b/src/modules/butterflies/butterflies_dispersal.h new file mode 100644 index 0000000000000000000000000000000000000000..4017a409fb645905a05f0a7ab6a89f4dd153cad0 --- /dev/null +++ b/src/modules/butterflies/butterflies_dispersal.h @@ -0,0 +1,8 @@ +// +// Created by gattringera on 21/11/22. +// + +#ifndef CATS_BUTTERFLIES_DISPERSAL_H +#define CATS_BUTTERFLIES_DISPERSAL_H + +#endif //CATS_BUTTERFLIES_DISPERSAL_H diff --git a/src/modules/butterflies/butterflies_main.c b/src/modules/butterflies/butterflies_main.c new file mode 100644 index 0000000000000000000000000000000000000000..5c9bfcff076a584355da10c51ee8e0354f368ad7 --- /dev/null +++ b/src/modules/butterflies/butterflies_main.c @@ -0,0 +1,80 @@ +#include <math.h> +#include "modules/module_header.h" +#include "butterflies_main.h" +#include "configuration/load_configuration_species_params.h" +#include "module.h" +#include "actions/cats_actions.h" +#include "butterfly_actions.h" +#include "butterfly_vital_rates.h" +#include "cats_ini/cats_ini.h" + +struct cats_global global; +struct cats_debug_options cats_debug; + + +void *butterfly_grid_init(struct cats_configuration *conf, struct cats_grid *grid, void *ignored) +{ + log_message(LOG_INFO, "%s: %s: grid init", module_name, __func__); + printf("%d %d\n", grid->dimension.cols, grid->dimension.rows); + + struct grid_data_butterflies *data = malloc_or_die(sizeof(struct grid_data_butterflies)); + log_message(LOG_INFO, "allocating data for generations"); + data->generations = new_raw_2d_array_from_dimension(grid->dimension, sizeof(float)); + log_message(LOG_INFO, "done allocating data for generations"); + data->generation_current = 0; + //struct conf_data_butterflies *conf_data = CATS_MODULE_DATA; + data->eggs = new_raw_2d_array_from_dimension(grid->dimension, sizeof(float)); + + + return data; +} + + +void *grid_cleanup(struct cats_configuration *conf, struct cats_grid *grid, void *data) +{ + log_message(LOG_INFO, "%s: grid cleanup", module_name); + assert(grid != NULL); + struct grid_data_butterflies *grid_data = data; + free_grid(&grid_data->generations, grid->dimension.rows); + free(grid_data->generations); + grid_data->generation_current = -1; + return NULL; +} + + +void load_butterflies_species_params(struct cats_configuration *conf, struct cats_ini *ini, const char *section_name, + struct cats_species_param *param) +{ + struct conf_data_butterflies *data = CATS_MODULE_DATA; + load_conf_vital_rate(&data->eggs_per_female, conf, ini, section_name, param); + load_conf_vital_rate(&data->butterfly_generations, conf, ini, section_name, param); + load_conf_vital_rate(&data->butterfly_egg_to_adult_survival, conf, ini, section_name, param); + + //bool _get_int32_config_value(const struct cats_ini *ini, const char *section, const char *key, bool required, int32_t *value); + int32_t rw_max; + cats_dt_rates female_percentage; + load_conf_value(true, ini, section_name, "butterflies random walk steps maximum", &rw_max); + load_conf_value(true, ini, section_name, "butterflies female fraction", &female_percentage); + data->generations_max = (int32_t) ceill(data->butterfly_generations.max_rate); + if (! data->actions_added) { + add_actions(conf); + data->actions_added = true; + } + +} + + +void cats_module_init(struct cats_configuration *conf) +{ + struct conf_data_butterflies *data = calloc_or_die(1,sizeof(struct conf_data_butterflies)); + enum cats_module_flags flags = MODULE_ALTERNATE_DEMOGRAPHIC | MODULE_OVERRIDE_ACTIONS; + int32_t id = register_module(conf, module_name, data, flags); + register_cats_grid_init_function(conf, butterfly_grid_init, grid_cleanup); + register_load_species_param_config_func(conf, load_butterflies_species_params); + add_vital_rates(conf, data); + + + log_message(LOG_INFO, "Hello from %s (id: %d)\n", module_name, id); + +} + diff --git a/src/modules/butterflies/butterflies_main.h b/src/modules/butterflies/butterflies_main.h new file mode 100644 index 0000000000000000000000000000000000000000..2a93c9cb762b625d042e5b5affadca7c3745a176 --- /dev/null +++ b/src/modules/butterflies/butterflies_main.h @@ -0,0 +1,29 @@ +#ifndef CATS_BUTTERFLIES_MAIN_H +#define CATS_BUTTERFLIES_MAIN_H +#include "cats_global.h" +#include <stdint.h> +#include "data/cats_datatypes.h" +#include "vital_rates/vital_rates.h" + +struct grid_data_butterflies { + float **generations; + int32_t generation_current; + float **eggs; + + +}; + +struct conf_data_butterflies { + + int32_t generations_max; + int32_t current_generation; + int32_t animal_dispersal_max_radius; ///< maximal flight/dispersal distance + cats_dt_rates egg_to_adult_survival_rate_maximum; + cats_dt_rates egg_per_female_maximum; + bool actions_added; + struct cats_vital_rate eggs_per_female; + struct cats_vital_rate butterfly_egg_to_adult_survival; + struct cats_vital_rate butterfly_generations; +}; + +#endif //CATS_BUTTERFLIES_MAIN_H diff --git a/src/modules/butterflies/butterflies_populations.c b/src/modules/butterflies/butterflies_populations.c new file mode 100644 index 0000000000000000000000000000000000000000..3ac7549b8f65dbf1e87f59a74851ae0cd7934a05 --- /dev/null +++ b/src/modules/butterflies/butterflies_populations.c @@ -0,0 +1,46 @@ +// +// Created by gattringera on 21/11/22. +// + +#include <assert.h> +#include <math.h> +#include "butterflies_populations.h" +#include "data/cats_grid.h" +#include "overlays/overlay_exclusion.h" +#include "inline_overlays.h" +#include "threading/threading-helpers.h" +#include "modules/module_header.h" +#include "butterflies_main.h" +#include "inline_carrying_capacity.h" +#include "inline_population.h" +#include "inline.h" +#include "misc/cats_random.h" +#include "populations/population.h" +void butterflies_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coord row, cats_dt_coord col, bool check_exclusion) +{ + const struct cats_configuration *conf = ts->conf; + if (check_exclusion && cell_excluded_by_overlay(conf, row, col)) return; + + struct conf_data_butterflies *module_conf = CATS_MODULE_DATA; + const int module_id = CATS_MODULE_ID; + struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data; + int32_t local_max_generation = (int32_t) ceilf(data->generations[row][col]); + if (data->generation_current > local_max_generation ) return; + if (data->eggs[row][col] == 0) return; + + float proportion = 1.0f; + if (data->generation_current == local_max_generation && (float) local_max_generation > proportion) { + proportion = data->generations[row][col] - (float) local_max_generation; + } + + + assert (conf->grid_count == 1); + float eggs = proportion * data->eggs[row][col]; + data->eggs[row][col] -= eggs; + cats_dt_rates maturation_rate = calculate_rate(&module_conf->butterfly_egg_to_adult_survival, NAN, &grid->param, grid, row, col, NULL); + cats_dt_population K = get_carrying_capacity(grid, row, col); + cats_dt_population adults = poisson_population_capped(ts->rng, eggs * proportion * maturation_rate, K); + set_population_ignore_cc(grid, row, col, adults); +} + + diff --git a/src/modules/butterflies/butterflies_populations.h b/src/modules/butterflies/butterflies_populations.h new file mode 100644 index 0000000000000000000000000000000000000000..5babb7ec7ca98f7ef8d82479158e816c9d62cc61 --- /dev/null +++ b/src/modules/butterflies/butterflies_populations.h @@ -0,0 +1,9 @@ +// +// Created by gattringera on 21/11/22. +// + +#ifndef CATS_BUTTERFLIES_POPULATIONS_H +#define CATS_BUTTERFLIES_POPULATIONS_H +#include "data/cats_grid.h" +void butterflies_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coord row, cats_dt_coord col, bool check_exclusion); +#endif //CATS_BUTTERFLIES_POPULATIONS_H diff --git a/src/modules/butterflies/butterfly_actions.c b/src/modules/butterflies/butterfly_actions.c new file mode 100644 index 0000000000000000000000000000000000000000..e74afb51aff94e39a8c01c500ee5046f4f68eab0 --- /dev/null +++ b/src/modules/butterflies/butterfly_actions.c @@ -0,0 +1,172 @@ + +#include "actions/cats_actions.h" +#include "actions/setup_actions.h" +#include "modules/module_header.h" +#include "butterfly_actions.h" +#include "module.h" +#include "butterflies_main.h" +#include "inline_overlays.h" +#include "butterflies_populations.h" +#include "inline_population.h" + +enum action_status action_butterfly_stats_reset(struct cats_grid *grid, struct cats_configuration *conf) +{ + return ACTION_RUN; +} + +void grid_butterflies_maturation(struct cats_grid *grid, struct cats_thread_info *ts) +{ + struct cats_configuration *conf = ts->conf; + const cats_dt_coord start_row = ts->area.start_row; + const cats_dt_coord end_row = ts->area.end_row; + + const cats_dt_coord start_col = ts->area.start_col; + const cats_dt_coord end_col = ts->area.end_col; + + for (cats_dt_coord row = start_row; row < end_row; row++) { + for (cats_dt_coord col = start_col; col < end_col; col++) { + if (cell_excluded_by_overlay(conf, row, col)) { + continue; + } + butterflies_cell_maturation(grid, ts, row, col, false); + } + } +} + + + + +void grid_butterflies_kill_adults(struct cats_grid *grid, struct cats_thread_info *ts) +{ + const cats_dt_coord start_row = ts->area.start_row; + const cats_dt_coord end_row = ts->area.end_row; + + const cats_dt_coord start_col = ts->area.start_col; + const cats_dt_coord end_col = ts->area.end_col; + + for (cats_dt_coord row = start_row; row < end_row; row++) { + for (cats_dt_coord col = start_col; col < end_col; col++) { + set_population_ignore_cc(grid, row, col, 0); + } + } +} + + +enum action_status action_butterflies_maturation(struct cats_grid *grid, struct cats_configuration *conf) +{ + threaded_action(&grid_butterflies_maturation, grid, conf, TS_DEFAULT); + + return ACTION_RUN; +} + + +enum action_status action_butterflies_kill_adults(struct cats_grid *grid, struct cats_configuration *conf) +{ + threaded_action(&grid_butterflies_kill_adults, grid, conf, TS_DEFAULT); + + return ACTION_RUN; +} + + +enum action_status action_butterflies_dispersal(struct cats_grid *grid, struct cats_configuration *conf) +{ + return ACTION_RUN; +} + +enum action_status action_butterflies_output(struct cats_grid *grid, struct cats_configuration *conf) +{ + return ACTION_RUN; +} + +enum action_status action_butterfly_stats_gather(struct cats_grid *grid, struct cats_configuration *conf) +{ + return ACTION_RUN; +} + +enum action_status action_butterfly_stats_write(struct cats_grid *grid, struct cats_configuration *conf) +{ + return ACTION_RUN; +} + + +void grid_update_generations(struct cats_grid *grid, struct cats_thread_info *ts) +{ + struct cats_configuration *conf = ts->conf; + + + struct conf_data_butterflies *module_conf = CATS_MODULE_DATA; + int module_id = CATS_MODULE_ID; + struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data; + struct cats_vital_rate *rate = &module_conf->butterfly_generations; + + const cats_dt_coord start_row = ts->area.start_row; + const cats_dt_coord end_row = ts->area.end_row; + + const cats_dt_coord start_col = ts->area.start_col; + const cats_dt_coord end_col = ts->area.end_col; + for (cats_dt_coord row = start_row; row < end_row; row++) { + for (cats_dt_coord col = start_col; col < end_col; col++) { + + if (cell_excluded_by_overlay(conf, row, col)) { + data->generations[row][col] = 0.0f; + continue; + } + cats_dt_rates gen = calculate_rate(rate, 0, conf->param, grid, row, col, NULL); + data->generations[row][col] = (float) gen; + //printf("GENERATIONS::thread %03d:: %d %d %f\n", ts->id ,row, col, (float) gen); + } + } +} + +enum action_status action_butterfly_update_generations(struct cats_grid *grid, struct cats_configuration *conf) +{ + struct conf_data_butterflies *data = CATS_MODULE_DATA; + data-> + threaded_action(&grid_update_generations, grid, conf, TS_DEFAULT); + return ACTION_RUN; +} + +enum action_status action_update_generation(struct cats_grid *grid, struct cats_configuration *conf) +{ + struct conf_data_butterflies *data = CATS_MODULE_DATA; + return ACTION_RUN; +} + +void add_butterfly_generation_action(struct cats_configuration *conf, action_function function, const char *name, int generation) +{ + char *result = NULL; + int rc = asprintf(&result, "%s (generation %d)", name, generation); + asprintf_check(rc); + append_action(conf, function, ALL_STAGES, result, module_name); + free(result); +} + + + +void add_actions(struct cats_configuration *conf) +{ + struct conf_data_butterflies *data = CATS_MODULE_DATA; + printf("MAXIMUM GENERATIONS %d\n", data->generations_max); + + register_action_function(conf, action_butterfly_stats_reset, "butterfly_action_reset_stats", "resetting butterfly statistics"); + register_action_function(conf, action_butterfly_update_generations, "butterfly_action_update_generations", "update generations"); + register_action_function(conf, action_butterflies_maturation, "butterfly_action_egg_to_adult", + "transition eggs to adults"); + + register_action_function(conf, action_butterflies_dispersal, "butterfly_action_dispersal", "egg dispersal"); + register_action_function(conf, action_butterflies_kill_adults, "butterfly_kill_adults", "kill adults"); + list_actions_full(conf); + + + append_action(conf, action_butterfly_stats_reset, ALL_STAGES, "resetting butterfly statistics", module_name); + append_action_by_name(conf, "action_load_environments", ALL_STAGES, "environment update", module_name); + append_action_by_name(conf, "action_overlay_update", ALL_STAGES, "overlay update", module_name); + append_action(conf, action_butterfly_update_generations, ALL_STAGES, "update generations", module_name); + for (int32_t generation = data->generations_max ; generation > 0 ; generation-- ) { + add_butterfly_generation_action(conf, action_update_generation, "update generation", generation); + add_butterfly_generation_action(conf, action_butterflies_maturation, "transition eggs to adults", generation); + add_butterfly_generation_action(conf, action_butterflies_dispersal, "dispersal", generation); + add_butterfly_generation_action(conf, action_butterflies_kill_adults, "kill adults", generation); + } + +} \ No newline at end of file diff --git a/src/modules/butterflies/butterfly_actions.h b/src/modules/butterflies/butterfly_actions.h new file mode 100644 index 0000000000000000000000000000000000000000..95595768f3ea4c4434e5591dde82d7a881b85916 --- /dev/null +++ b/src/modules/butterflies/butterfly_actions.h @@ -0,0 +1,6 @@ + +#ifndef CATS_BUTTERFLY_ACTIONS_H +#define CATS_BUTTERFLY_ACTIONS_H +#include "configuration/configuration.h" +void add_actions(struct cats_configuration *conf); +#endif //CATS_BUTTERFLY_ACTIONS_H diff --git a/src/modules/butterflies/butterfly_vital_rates.c b/src/modules/butterflies/butterfly_vital_rates.c new file mode 100644 index 0000000000000000000000000000000000000000..f40c73de5b166cdf7d1355ab36dea6102186c1b7 --- /dev/null +++ b/src/modules/butterflies/butterfly_vital_rates.c @@ -0,0 +1,25 @@ + + +#include "butterfly_vital_rates.h" + +void add_vital_rates(struct cats_configuration *conf, struct conf_data_butterflies *data) +{ + // generations + register_module_vital_rate(conf, &data->butterfly_generations,"butterflies generations"); + set_vital_rate_name(&data->butterfly_generations, "butterflies generations"); + set_vital_rate_suitability_cutoff_hint(&data->butterfly_generations, HYBRID_SUIT_TS_ZT); + set_vital_rate_link_hybrid_function(&data->butterfly_generations, conf, LINK_SUITABILITY_SIGMOID); + + // eggs + register_module_vital_rate(conf, &data->eggs_per_female, "butterflies eggs per female"); + set_vital_rate_name(&data->eggs_per_female, "butterflies eggs per female"); + set_vital_rate_suitability_cutoff_hint(&data->eggs_per_female, HYBRID_SUIT_TS_ZT); + set_vital_rate_link_hybrid_function(&data->eggs_per_female, conf, LINK_SUITABILITY_SIGMOID); + + // egg to adult survival + register_module_vital_rate(conf, &data->butterfly_egg_to_adult_survival,"butterflies egg to adult survival rate"); + set_vital_rate_name(&data->butterfly_egg_to_adult_survival, "butterflies eggs to adult survival rate"); + set_vital_rate_suitability_cutoff_hint(&data->butterfly_egg_to_adult_survival, HYBRID_SUIT_TS_ZT); + set_vital_rate_link_hybrid_function(&data->butterfly_egg_to_adult_survival, conf, LINK_SUITABILITY_SIGMOID); + set_vital_density(&data->butterfly_egg_to_adult_survival, DENSITY_DEP_NEGATIVE); +} diff --git a/src/modules/butterflies/butterfly_vital_rates.h b/src/modules/butterflies/butterfly_vital_rates.h new file mode 100644 index 0000000000000000000000000000000000000000..ab32c356889e4fb62fe9e1764b1fee6b7f12e81a --- /dev/null +++ b/src/modules/butterflies/butterfly_vital_rates.h @@ -0,0 +1,10 @@ + +#ifndef CATS_BUTTERFLY_VITAL_RATES_H +#define CATS_BUTTERFLY_VITAL_RATES_H +#include "configuration/configuration.h" +#include "butterflies_main.h" +#include "vital_rates/setup_rates.h" +#include "modules/module_header.h" + +void add_vital_rates(struct cats_configuration *conf, struct conf_data_butterflies *data) ; +#endif //CATS_BUTTERFLY_VITAL_RATES_H diff --git a/src/modules/butterflies/module.h b/src/modules/butterflies/module.h new file mode 100644 index 0000000000000000000000000000000000000000..02ce2be565ffc98fe6d576ff673ef7857bd8217b --- /dev/null +++ b/src/modules/butterflies/module.h @@ -0,0 +1,6 @@ + + +#ifndef CATS_MODULE_H +#define CATS_MODULE_H +static const char *module_name = "cats-butterflies"; +#endif //CATS_MODULE_H diff --git a/src/modules/butterflies/random_walk.c b/src/modules/butterflies/random_walk.c new file mode 100644 index 0000000000000000000000000000000000000000..22b263f0303bac2a60d1f8dd9e7c5502a892c0f1 --- /dev/null +++ b/src/modules/butterflies/random_walk.c @@ -0,0 +1,17 @@ +// +// Created by gattringera on 22/06/22. +// + +#include "random_walk.h" + +void random_step(struct cats_grid *grid, cats_dt_coord start_row, cats_dt_coord col) +{ + + +} + + +void random_walk(struct cats_configuration *conf, struct cats_grid *grid) +{ + +} diff --git a/src/modules/butterflies/random_walk.h b/src/modules/butterflies/random_walk.h new file mode 100644 index 0000000000000000000000000000000000000000..ab3a7d59db481d3325ff8dc4625af50a9faa04fc --- /dev/null +++ b/src/modules/butterflies/random_walk.h @@ -0,0 +1,4 @@ +#ifndef CATS_RANDOM_WALK_H +#define CATS_RANDOM_WALK_H +#include "cats/configuration/configuration.h" +#endif //CATS_RANDOM_WALK_H