diff --git a/src/modules/butterflies/CMakeLists.txt b/src/modules/butterflies/CMakeLists.txt
index 5eb11b6d5a4452081c285adf236b7c305d7e2a6d..c20a250845e6cfd490a47a0312602fc2f7ded1c1 100644
--- a/src/modules/butterflies/CMakeLists.txt
+++ b/src/modules/butterflies/CMakeLists.txt
@@ -1,16 +1,16 @@
 add_library(cats-butterflies SHARED ""
-        butterflies_actions.c butterflies_actions.h
-        butterflies_vital_rates.c butterflies_vital_rates.h
-        module.h
-        butterflies_dispersal.c butterflies_dispersal.h
-        butterflies_populations.c butterflies_populations.h
-        butterflies_inline.h
-        butterflies_generations.c butterflies_generations.h
-        butterflies_stats.c
-        butterflies_overlays.c butterflies_overlays.h
-        butterflies_filenames.c butterflies_filenames.h
-        butterflies_action_helpers.c
-        butterflies_action_helpers.h)
+            butterflies_actions.c butterflies_actions.h
+            butterflies_vital_rates.c butterflies_vital_rates.h
+            module.h
+            butterflies_dispersal.c butterflies_dispersal.h
+            butterflies_populations.c butterflies_populations.h
+            butterflies_inline.h
+            butterflies_generations.c butterflies_generations.h
+            butterflies_stats.c
+            butterflies_overlays.c butterflies_overlays.h
+            butterflies_paths.c butterflies_paths.h
+            butterflies_actions_setup.c
+            butterflies_actions_setup.h butterflies_initial_population.c butterflies_initial_population.h butterflies_scale.c butterflies_scale.h)
 
 target_include_directories(cats-butterflies PUBLIC ".")
 
diff --git a/src/modules/butterflies/butterflies_actions.c b/src/modules/butterflies/butterflies_actions.c
index 40e05cd02cd67414a88a82efe53ba2073264faa1..027e1de46b0191a9639ad8827a3dec4566c01d6a 100644
--- a/src/modules/butterflies/butterflies_actions.c
+++ b/src/modules/butterflies/butterflies_actions.c
@@ -13,44 +13,55 @@
 #include "butterflies_generations.h"
 #include "butterflies_dispersal.h"
 #include "butterflies_overlays.h"
-#include "butterflies_filenames.h"
+#include "butterflies_paths.h"
 #include "inline.h"
 #include "lambda/leslie_matrix.h"
 #include "temporal/years.h"
+#include "butterflies_initial_population.h"
 
 
 enum action_status bf_action_stats_reset(struct cats_grid *grid, struct cats_configuration *conf)
 {
-        // FIXME MOVE
-        if (conf->time.year_current == conf->time.year_start) {
+        struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
+        int module_id = CATS_MODULE_ID;
+
+        struct grid_data_butterflies *module_data = grid->grid_modules[module_id].module_data;
+        if (conf->time.year_current == conf->time.year_start &&
+            module_conf->generations_max == module_data->generation_current) {
                 log_message(LOG_INFO, "SUMMARY: Scale factor: %Lf", grid->param.scale_factor);
                 struct lambda_parameters l_param = {0};
                 l_param.calculate_scale = true;
                 l_param.suitability = grid->param.OT;
                 l_param.N = 0;
                 l_param.K = (cats_dt_population)
-                        (get_vital_rate_maximum(&conf->param[grid->id].carrying_capacity) * conf->param->max_adult_cc_fraction);
+                        (get_vital_rate_maximum(&conf->param[grid->id].carrying_capacity) *
+                         conf->param->max_adult_cc_fraction);
                 l_param.grid = 0;
                 l_param.row = 0;
                 l_param.col = 0;
                 l_param.param = &conf->param[grid->id];
                 l_param.species_id = grid->id;
                 bool print_rate = false;
-                struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
                 cats_dt_rates female_fraction = module_conf->female_fraction;
                 cats_dt_rates stationary = module_conf->probability_to_stay;
                 cats_dt_rates mobile = 1.0 - stationary;
                 cats_dt_rates egg_fraction_source = module_conf->egg_fraction_source;
-                cats_dt_rates eggs_per_female = calculate_rate_for_matrix(&module_conf->eggs_per_female, &l_param, print_rate);
-                cats_dt_rates reproduction_rate = calculate_rate_for_matrix(&module_conf->reproduction_rate, &l_param, print_rate);
-                cats_dt_rates K = calculate_rate_for_matrix(&conf->param[grid->id].carrying_capacity, &l_param, print_rate) * conf->param->max_adult_cc_fraction;
-                cats_dt_rates local_eggs =  (stationary + mobile * egg_fraction_source ) * eggs_per_female;
+                cats_dt_rates eggs_per_female = calculate_rate_for_matrix(&module_conf->eggs_per_female, &l_param,
+                                                                          print_rate);
+                cats_dt_rates reproduction_rate = calculate_rate_for_matrix(&module_conf->reproduction_rate, &l_param,
+                                                                            print_rate);
+                cats_dt_rates K =
+                        calculate_rate_for_matrix(&conf->param[grid->id].carrying_capacity, &l_param, print_rate) *
+                        conf->param->max_adult_cc_fraction;
+                cats_dt_rates local_eggs = (stationary + mobile * egg_fraction_source) * eggs_per_female;
                 // female -> female
                 // to achieve the target reproduction rate, the number of eggs per female laid in the cell
                 // that survive and become adult has to be the reproduction rate divided by the female fraction divided by the number of eggs
-                cats_dt_rates eggs_to_adults_rate = bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs, female_fraction);
-                cats_dt_rates result =  local_eggs * eggs_to_adults_rate * female_fraction;
-                cats_dt_rates generations = calculate_rate_for_matrix(&module_conf->butterfly_generations, &l_param, print_rate);
+                cats_dt_rates eggs_to_adults_rate =
+                        bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs) / module_conf->female_fraction;
+                cats_dt_rates result = local_eggs * eggs_to_adults_rate * female_fraction;
+                cats_dt_rates generations = calculate_rate_for_matrix(&module_conf->butterfly_generations, &l_param,
+                                                                      print_rate);
 
 
                 log_message(LOG_INFO, "SUMMARY: reproduction rate at OT: %Lf", reproduction_rate);
@@ -58,7 +69,8 @@ enum action_status bf_action_stats_reset(struct cats_grid *grid, struct cats_con
                 log_message(LOG_INFO, "SUMMARY: local eggs at OT: %Lf", local_eggs);
                 log_message(LOG_INFO, "SUMMARY: stationary females at OT: %Lf", stationary);
                 log_message(LOG_INFO, "SUMMARY: eggs to adult rate at OT: %Lf", eggs_to_adults_rate);
-                log_message(LOG_INFO, "SUMMARY: egg fraction source (non-stationary females) at OT: %Lf", egg_fraction_source);
+                log_message(LOG_INFO, "SUMMARY: egg fraction source (non-stationary females) at OT: %Lf",
+                            egg_fraction_source);
                 log_message(LOG_INFO, "SUMMARY: carrying capacity at OT: %Lf", K);
                 log_message(LOG_INFO, "SUMMARY: generations at OT: %Lf", generations);
                 log_message(LOG_INFO, "SUMMARY: effective female to female rate at OT: %Lf\n", result);
@@ -66,10 +78,12 @@ enum action_status bf_action_stats_reset(struct cats_grid *grid, struct cats_con
                 l_param.suitability = 1.0;
                 eggs_per_female = calculate_rate_for_matrix(&module_conf->eggs_per_female, &l_param, print_rate);
                 reproduction_rate = calculate_rate_for_matrix(&module_conf->reproduction_rate, &l_param, print_rate);
-                K = calculate_rate_for_matrix(&conf->param[grid->id].carrying_capacity, &l_param, print_rate) * conf->param->max_adult_cc_fraction;
-                local_eggs =  (stationary + mobile * egg_fraction_source ) * eggs_per_female;
-                eggs_to_adults_rate = bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs, female_fraction);
-                result =  local_eggs * eggs_to_adults_rate * female_fraction;
+                K = calculate_rate_for_matrix(&conf->param[grid->id].carrying_capacity, &l_param, print_rate) *
+                    conf->param->max_adult_cc_fraction;
+                local_eggs = (stationary + mobile * egg_fraction_source) * eggs_per_female;
+                eggs_to_adults_rate =
+                        bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs) / module_conf->female_fraction;
+                result = local_eggs * eggs_to_adults_rate;
                 generations = calculate_rate_for_matrix(&module_conf->butterfly_generations, &l_param, print_rate);
 
                 log_message(LOG_INFO, "SUMMARY: reproduction rate at suitability 1: %Lf", reproduction_rate);
@@ -77,12 +91,12 @@ enum action_status bf_action_stats_reset(struct cats_grid *grid, struct cats_con
                 log_message(LOG_INFO, "SUMMARY: local eggs at suitability 1: %Lf", local_eggs);
                 log_message(LOG_INFO, "SUMMARY: stationary females at suitability 1: %Lf", stationary);
                 log_message(LOG_INFO, "SUMMARY: eggs to adult rate at suitability 1: %Lf", eggs_to_adults_rate);
-                log_message(LOG_INFO, "SUMMARY: egg fraction source (non-stationary females) at suitability 1: %Lf", egg_fraction_source);
+                log_message(LOG_INFO, "SUMMARY: egg fraction source (non-stationary females) at suitability 1: %Lf",
+                            egg_fraction_source);
                 log_message(LOG_INFO, "SUMMARY: carrying capacity at suitability 1: %Lf", K);
                 log_message(LOG_INFO, "SUMMARY: generations at suitability 1: %Lf", generations);
                 log_message(LOG_INFO, "SUMMARY: effective female to female rate at suitability 1: %Lf\n", result);
 
-
         }
 
         return action_grid_stats_reset(grid, conf);
@@ -99,11 +113,24 @@ void grid_butterflies_maturation(struct cats_grid *grid, struct cats_thread_info
         const cats_dt_coord end_col = ts->area.end_col;
 
         ts->rw_debug_cells_with_adults = 0;
+
         for (cats_dt_coord row = start_row; row < end_row; row++) {
                 for (cats_dt_coord col = start_col; col < end_col; col++) {
-
+#ifdef BF_DEBUG
+                        if (get_adult_population(grid, row, col)) {
+                                printf("BFDBG::%s::adults at maturation::%d,%d,%d\n",
+                                       __func__, row, col, get_adult_population(grid, row, col));
+                        }
+#endif
                         if (cell_excluded_by_overlay(conf, row, col)
                             || bf_cell_excluded_by_generation(grid, row, col)) {
+#ifdef BF_DEBUG
+                                if (get_adult_population(grid, row, col)) {
+                                        printf("BFDBG::%s::adults at maturation::%d,%d,%d - excluded by generation\n",
+                                               __func__, row, col, get_adult_population(grid, row, col));
+                                }
+#endif
+
                                 continue;
                         }
                         bf_cell_maturation(grid, ts, row, col, false);
@@ -113,6 +140,30 @@ void grid_butterflies_maturation(struct cats_grid *grid, struct cats_thread_info
 }
 
 
+void bf_initial_population_to_eggs(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;
+                        }
+                        set_population(grid, row, col, get_adult_population(grid, row, col));
+                        butterflies_cell_dispersal(grid, ts, row, col, false, true);
+                }
+        }
+
+}
+
+
 void butterflies_area_dispersal(struct cats_grid *grid, struct cats_thread_info *ts)
 {
         struct cats_configuration *conf = ts->conf;
@@ -135,15 +186,14 @@ void butterflies_area_dispersal(struct cats_grid *grid, struct cats_thread_info
                                 continue;
                         }
 
-                        butterflies_cell_dispersal(grid, ts, row, col, false);
+                        butterflies_cell_dispersal(grid, ts, row, col, false, false);
                 }
         }
-        if (ts->rw_debug_cells_with_adults)  {
-                printf("thread %d: %ld cells with adults, %ld random walks, %ld deposits\n",
-                       ts->id, ts->rw_debug_cells_with_adults, ts->rw_debug_random_walks, ts->rw_debug_deposits);
+        if (ts->rw_debug_cells_with_adults) {
+                log_message(LOG_INFO, "thread %d: %ld cells with adults, %ld random walks, %ld deposits\n",
+                            ts->id, ts->rw_debug_cells_with_adults, ts->rw_debug_random_walks, ts->rw_debug_deposits);
         }
 
-
 }
 
 
@@ -166,6 +216,7 @@ enum action_status bf_action_save_grid(struct cats_grid *grid, struct cats_confi
         return ACTION_RUN;
 }
 
+
 enum action_status bf_action_save_overlay(struct cats_grid *grid, struct cats_configuration *conf)
 {
         if (!is_output_year(&conf->time)) return ACTION_NOT_RUN;
@@ -183,7 +234,6 @@ enum action_status bf_action_save_overlay(struct cats_grid *grid, struct cats_co
 }
 
 
-
 enum action_status bf_action_save_eggs_grid(struct cats_grid *grid, struct cats_configuration *conf)
 {
         if (!is_output_year(&conf->time)) return ACTION_NOT_RUN;
@@ -198,7 +248,6 @@ enum action_status bf_action_save_eggs_grid(struct cats_grid *grid, struct cats_
 }
 
 
-
 enum action_status bf_action_dispersal(struct cats_grid *grid, struct cats_configuration *conf)
 {
         threaded_action(&butterflies_area_dispersal, grid, conf, TS_DISPERSAL);
@@ -206,7 +255,7 @@ enum action_status bf_action_dispersal(struct cats_grid *grid, struct cats_confi
 
         for (enum butterfly_stats which = BF_POPULATED_AT_DISPERSAL; which < BF_STAT_MAX; which++) {
                 int64_t stat_id = module_conf->stat_ids[which];
-                printf("%s: %ld\n", bf_get_stats_field_name(which), grid->stats.stats[stat_id]);
+                log_message(LOG_INFO, "STAT %s: %ld", bf_get_stats_field_name(which), grid->stats.stats[stat_id]);
         }
 
 
@@ -229,106 +278,6 @@ enum action_status bf_action_stats_write(__attribute__((unused)) struct cats_gri
         return ACTION_RUN;
 }
 
-int64_t count_populated_cells(const struct cats_grid *grid)
-{
-        int64_t cells = 0;
-        cats_dt_coord rows = grid->dimension.rows;
-        cats_dt_coord cols = grid->dimension.cols;
-        for (cats_dt_coord row = 0; row < rows; row++) {
-                for (cats_dt_coord col = 0; col < cols; col++) {
-                        if (get_adult_population(grid, row, col)) {
-                                cells += 1;
-                        }
-
-                }
-        }
-        return cells;
-}
-
-int64_t butterflies_prune_invalid_cells(struct cats_grid *grid)
-{
-        int64_t invalid_habitat = 0;
-        int module_id = CATS_MODULE_ID;
-        struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
-        cats_dt_coord rows = grid->dimension.rows;
-        cats_dt_coord cols = grid->dimension.cols;
-
-        for (cats_dt_coord row = 0; row < rows; row++) {
-                for (cats_dt_coord col = 0; col < cols; col++) {
-                        if (!(data->info_layer[row][col] & BF_CELL_VALID_DISPERSAL_TARGET)) {
-                                set_population_ignore_cc(grid, row, col, 0);
-                                invalid_habitat += 1;
-                        }
-                }
-        }
-        return invalid_habitat;
-}
-
-void initial_population_adjustment(struct cats_configuration *conf, struct cats_grid *grid)
-{
-        int64_t init_populated_cells = count_populated_cells(grid);
-        int64_t invalid_resources = butterflies_prune_invalid_cells(grid);
-        log_message(LOG_IMPORTANT, "Loaded initial populations: %ld cells occupied before adjustment", init_populated_cells);
-        if (grid->param.initial_population.set_to_cc == true) {
-
-//#define DEBUG_INITIAL_POPULATIONS 1
-#ifdef DEBUG_INITIAL_POPULATIONS
-                const int32_t max_i = 10;
-                struct cats_vital_rate *cc_rate = &grid->param.carrying_capacity;
-                cats_dt_rates OT =  grid->param.OT;
-                for (int32_t i = 0; i < max_i; i++) {
-
-                        cats_dt_rates suit = OT + i * (1.0 - OT)/max_i;
-                        cats_dt_rates cc = cc_rate->func->func(cc_rate, &grid->param, suit, 0, NAN);
-                        log_message(LOG_INFO, "Carrying capacity for suitability %Lf: %Lf", suit, cc);
-
-                }
-                const cats_dt_coord rows = grid->dimension.rows;
-                const cats_dt_coord cols = grid->dimension.cols;
-                int64_t start = 0;
-                int64_t multi_excluded = 0;
-
-                for (cats_dt_coord row = 0; row < rows; row++) {
-                        for (cats_dt_coord col = 0; col < cols; col++) {
-
-                                if (get_adult_population(grid, row, col) == 0) continue;
-                                start += 1;
-                                cats_dt_rates multiplier = 1.0;
-                                if (conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
-                                        multiplier *= conf->overlays.habitat_cc->data[row][col];
-                                }
-                                cats_dt_rates suit = get_suitability(grid, row, col);
-                                cats_dt_rates cc_raw = cc_rate->func->func(cc_rate, &grid->param, suit, 0, NAN);
-                                if (multiplier == 0) {
-                                    multi_excluded += 1;
-                                }
-                                cats_dt_population cc = get_carrying_capacity(grid, row, col);
-
-                                printf("DEBUG::row %d col %d, suit %Lf, cc multi %Lf, cc raw %Lf, cc %d\n", row, col, suit, multiplier, cc_raw, cc);
-                        }
-                }
-
-
-
-#endif
-
-                increase_initial_population_to_cc(grid, conf);
-                int64_t populated_cells_after_cc = count_populated_cells(grid);
-                log_message(LOG_IMPORTANT, "\t%ld cells occupied after setting population sizes to carrying capacity", populated_cells_after_cc);
-        }
-
-
-
-        if (grid->param.initial_population.suitability_threshold > 0.0) {
-                prune_initial_population_under_threshold(conf, grid);
-        }
-
-        int64_t after_populated_cells = count_populated_cells(grid);
-
-        log_message(LOG_IMPORTANT, "Pruned initial populations from %ld cells to %ld, (%ld wrong habitat)",
-                    init_populated_cells, after_populated_cells, invalid_resources);
-        grid->param.initial_population.adjusted = true;
-}
 
 // only run at the start of the year
 enum action_status bf_action_generation_update(struct cats_grid *grid, struct cats_configuration *conf)
@@ -345,7 +294,7 @@ enum action_status bf_action_generation_update(struct cats_grid *grid, struct ca
         log_message(LOG_IMPORTANT, "resetting generation to %d", module_conf->generations_max);
 
         if (grid->param.initial_population.adjusted == false) {
-                initial_population_adjustment(conf, grid);
+                bf_initial_population_adjustment(conf, grid);
                 grid->param.initial_population.adjusted = true;
         }
 
@@ -353,7 +302,8 @@ enum action_status bf_action_generation_update(struct cats_grid *grid, struct ca
 
         int64_t cells_with_eggs = grid->stats.custom_stats[egg_cells_id];
         int64_t cells_with_eggs_removed = grid->stats.custom_stats[egg_cells_removed_id];
-        log_message(LOG_INFO, "%ld cells with eggs left, %ld cells with eggs removed", cells_with_eggs, cells_with_eggs_removed);
+        log_message(LOG_INFO, "%ld cells with eggs left, %ld cells with eggs removed", cells_with_eggs,
+                    cells_with_eggs_removed);
         grid->stats.custom_stats[egg_cells_id] = 0;
         grid->stats.custom_stats[egg_cells_removed_id] = 0;
         return ACTION_RUN;
@@ -381,13 +331,27 @@ enum action_status bf_action_generation_finish(struct cats_grid *grid, struct ca
         return ACTION_RUN;
 }
 
+
 enum action_status
 bf_action_generation_start(struct cats_grid *grid, __attribute__((unused)) struct cats_configuration *conf)
 {
+#ifdef BF_DEBUG
+        cats_dt_population rows = grid->dimension.rows;
+        cats_dt_population cols = grid->dimension.cols;
+        for (cats_dt_coord row = 0; row < rows; row++) {
+                for (cats_dt_coord col = 0; col < cols; col++) {
+                        if (get_adult_population(grid, row, col)) {
+                                printf("BFDBG::%s::adults at start of generation::%d,%d,%d\n",
+                                       __func__, row, col, get_adult_population(grid, row, col));
+
+                        }
+                }
+        }
+#endif
         int module_id = CATS_MODULE_ID;
 
         struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
-        log_message(LOG_IMPORTANT, "Starting generation to %d\n", data->generation_current);
+        log_message(LOG_INFO, "Starting generation %d", data->generation_current);
         assert(data->generation_current >= 0);
         return ACTION_RUN;
 }
diff --git a/src/modules/butterflies/butterflies_action_helpers.c b/src/modules/butterflies/butterflies_actions_setup.c
similarity index 95%
rename from src/modules/butterflies/butterflies_action_helpers.c
rename to src/modules/butterflies/butterflies_actions_setup.c
index e551e1a9e99f601f3a8b7605b5ae4c8a0086f159..9258f0ffaa45de1ff829a6faeab1329470d4db84 100644
--- a/src/modules/butterflies/butterflies_action_helpers.c
+++ b/src/modules/butterflies/butterflies_actions_setup.c
@@ -1,5 +1,5 @@
 
-#include "butterflies_action_helpers.h"
+#include "butterflies_actions_setup.h"
 #include "configuration/configuration.h"
 #include "actions/setup_actions.h"
 #include "module.h"
@@ -51,10 +51,8 @@ void bf_add_actions(struct cats_configuration *conf)
 {
         struct conf_data_butterflies *data = CATS_MODULE_DATA;
 
-        printf("MAXIMUM GENERATIONS %d\n", data->generations_max);
-        bf_register_actions(conf);
+        log_message(LOG_INFO, "Adding actions of %d generations", data->generations_max);
 
-        list_actions_full(conf);
 
         append_action(conf, bf_action_stats_reset, ALL_STAGES, "resetting butterfly statistics", module_name);
         append_action_by_name(conf, "action_load_environments", ALL_STAGES, "environment update", module_name);
@@ -70,7 +68,7 @@ void bf_add_actions(struct cats_configuration *conf)
                 bf_add_generation_action(conf, bf_action_generation_start, "start generation", generation);
                 bf_add_generation_action(conf, bf_action_maturation, "transition eggs to adults",
                                          generation);
-                bf_add_generation_action(conf, bf_action_save_grid, "output", generation);
+                bf_add_generation_action(conf, bf_action_save_grid, "output adults", generation);
                 bf_add_generation_action(conf, bf_action_stats_gather, "gather stats", generation);
                 bf_add_generation_action(conf, bf_action_dispersal, "dispersal", generation);
                 bf_add_generation_action(conf, bf_action_save_eggs_grid, "output eggs", generation);
diff --git a/src/modules/butterflies/butterflies_action_helpers.h b/src/modules/butterflies/butterflies_actions_setup.h
similarity index 55%
rename from src/modules/butterflies/butterflies_action_helpers.h
rename to src/modules/butterflies/butterflies_actions_setup.h
index bd75bfabe5480e05580a0b123f0da838260afae1..224068527270fadfbef4b2e9a312283468c5a7ab 100644
--- a/src/modules/butterflies/butterflies_action_helpers.h
+++ b/src/modules/butterflies/butterflies_actions_setup.h
@@ -1,9 +1,9 @@
-#ifndef CATS_BUTTERFLIES_ACTION_HELPERS_H
-#define CATS_BUTTERFLIES_ACTION_HELPERS_H
+#ifndef CATS_BUTTERFLIES_ACTIONS_SETUP_H
+#define CATS_BUTTERFLIES_ACTIONS_SETUP_H
 
 #include "configuration/configuration.h"
 
 void bf_register_actions(struct cats_configuration *conf);
 void bf_add_actions(struct cats_configuration *conf);
 
-#endif //CATS_BUTTERFLIES_ACTION_HELPERS_H
+#endif //CATS_BUTTERFLIES_ACTIONS_SETUP_H
diff --git a/src/modules/butterflies/butterflies_dispersal.c b/src/modules/butterflies/butterflies_dispersal.c
index 1582d7fb4aa4968969c92010dd195ddbe6dcbdb6..7422d08ff3c1e0a2c518eedbd374ccc21d5cd12a 100644
--- a/src/modules/butterflies/butterflies_dispersal.c
+++ b/src/modules/butterflies/butterflies_dispersal.c
@@ -53,7 +53,7 @@ static void inline single_random_walk(struct cats_thread_info *ts, struct cats_g
         const cats_dt_coord cols = grid->dimension.cols;
 
 
-        for (cats_dt_coord step = 0; step < max_steps; step++){
+        for (cats_dt_coord step = 0; step < max_steps; step++) {
                 const unsigned long int direction = gsl_rng_uniform_int(ts->rng, N_DIRECTIONS);
 
 
@@ -74,7 +74,8 @@ static void inline single_random_walk(struct cats_thread_info *ts, struct cats_g
                 // is the cell a valid dispersal target location?
                 if (!(data->info_layer[row][col] & BF_CELL_VALID_DISPERSAL_TARGET)) {
                         if (debug_rw) {
-                                fprintf(module_conf->debug_rw_file, "%d,%d,%d,%d,%d,%d,%d\n", rw_num, row, col, step + 1,
+                                fprintf(module_conf->debug_rw_file, "%d,%d,%d,%d,%d,%d,%d\n", rw_num, row, col,
+                                        step + 1,
                                         module_conf->animal_dispersal_max_radius - step - 1, 0, eggs_left);
                         }
 
@@ -106,9 +107,13 @@ static void inline single_random_walk(struct cats_thread_info *ts, struct cats_g
 }
 
 
+
+
+
+
 void
 butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coord row, cats_dt_coord col,
-                           bool check_exclusion)
+                           bool check_exclusion, bool local_only)
 {
         const struct cats_configuration *conf = ts->conf;
         if (check_exclusion
@@ -118,12 +123,15 @@ butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts,
 
         // total adults: the number of adults that became adult in this cell, possibly exceeding the carrying capacity (thanks to poisson processes)
         const cats_dt_population total_adults = get_adult_population(grid, row, col);
+
         if (total_adults == 0) return;
         ts->rw_debug_cells_with_adults++;
         struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
         // total females: how many of the total adults are female, as drawn from a binomial distribution with p = 0.5
         // can be safely cast, because gsl_ran_binomial will return a number <= total_adults
-        const cats_dt_population total_females = (cats_dt_population) gsl_ran_binomial(ts->rng, (double) module_conf->female_fraction, total_adults);
+        const cats_dt_population total_females = (cats_dt_population) gsl_ran_binomial(ts->rng,
+                                                                                       (double) module_conf->female_fraction,
+                                                                                       total_adults);
         assert(total_females >= 0 && total_females <= total_adults);
 
         // total males: the rest
@@ -142,44 +150,18 @@ butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts,
         if (eggs_per_female == 0) return;
 
 
-        // supernumerous_adults: the number of adults exceeding the carrying capacity
-        const cats_dt_population cc = get_carrying_capacity(grid, row, col);
-        const cats_dt_population supernumerous_adults = total_adults - cc;
-
-        // supernumerous_females: the (randomly assigned, drawn from a hypergeometric distribution) number of females
-        // in the number of supernumerous adults
-        cats_dt_population supernumerous_females = 0;
-
-
-        if (supernumerous_adults > 0) {
-                // Too many adults in the cell. These must leave the cell, either to be added to the number of
-                // * dispersing females
-                // * discarded (males)
-                supernumerous_females = (cats_dt_population) gsl_ran_hypergeometric(ts->rng, total_females, total_males,
-                                                                                    supernumerous_adults);
-
-        }
-
-
-        // females_within_cc: the number of females within the carrying capacity
-        cats_dt_population females_within_cc = total_females - supernumerous_females;
-
-        // at this point the number of 'remaining' adults in the cell is equal or less than the carrying capacity
-
-        // how many females will leave the cell (not counting the number of supernumerous ones)?
+        // how many females will leave the cell
         // wandering_females: the number of females that will leave the cell and do a random walk
-        cats_dt_population wandering_females =
-                (cats_dt_population) (females_within_cc * (1.0 - module_conf->probability_to_stay));
+        cats_dt_rates probability_to_leave = (1.0 -  module_conf->probability_to_stay);
+        cats_dt_population wandering_females = poisson_population_capped(ts->rng,
+                                                                         total_females * probability_to_leave,
+                                                                         total_females);
 
         // stationary_females: the number of females that will not leave the cell, and leave all their eggs here
-        cats_dt_population stationary_females = females_within_cc - wandering_females;
-
-        if (wandering_females < 0) {
-                wandering_females = 0;
-        }
+        cats_dt_population stationary_females = total_females - wandering_females;
+        assert(stationary_females >= 0);
+        assert(wandering_females >= 0);
 
-        // we need to add the previously subtracted supernumerous females
-        wandering_females += supernumerous_females;
 
         const int module_id = CATS_MODULE_ID;
         struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
@@ -192,30 +174,33 @@ butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts,
         const cats_dt_rates source_cell_eggs = stationary_females * eggs_per_female +
                                                wandering_females * (eggs_per_female - eggs_to_disperse_per_female);
 
-        // add source cell eggs to the source cell
-
         data->eggs[row][col] += (float) ceill(source_cell_eggs);
 
+
         if (eggs_to_disperse_per_female == 0) {
                 log_message(LOG_ERROR, "%s: random walk with no eggs to distribute in cell %d %d", __func__, row, col);
                 return;
         }
 
-        // FIXME: define threshold over which the random walks are bundled
         const cats_dt_rates egg_fraction_step = module_conf->egg_fraction_step;
-        //printf("thread %d: row %d col %d: doing %d rws\n", ts->id, row, col, wandering_females);
+
+
+
+        if (local_only) {
+                return;
+        }
 
         if (debug_rw) {
-                fprintf(module_conf->debug_rw_file, "# total source cell eggs = %d\n", (int)ceill(source_cell_eggs));
+                fprintf(module_conf->debug_rw_file, "# total source cell eggs = %d\n", (int) ceill(source_cell_eggs));
                 fprintf(module_conf->debug_rw_file, "# stationary females = %d\n", stationary_females);
                 fprintf(module_conf->debug_rw_file, "# wandering females = %d\n", wandering_females);
                 fprintf(module_conf->debug_rw_file, "# total females = %d\n", wandering_females + stationary_females);
-                fprintf(module_conf->debug_rw_file, "# wandering females source cell eggs = %d\n", (int) (wandering_females * (eggs_per_female - eggs_to_disperse_per_female)));
-                fprintf(module_conf->debug_rw_file, "# stationary females source cell eggs = %d\n", (int) (stationary_females * eggs_per_female));
-
+                fprintf(module_conf->debug_rw_file, "# wandering females source cell eggs = %d\n",
+                        (int) (wandering_females * (eggs_per_female - eggs_to_disperse_per_female)));
+                fprintf(module_conf->debug_rw_file, "# stationary females source cell eggs = %d\n",
+                        (int) (stationary_females * eggs_per_female));
                 fprintf(module_conf->debug_rw_file, "id,row,col,step,steps left,eggs deposited,eggs left\n");
 
-
         }
 
         for (int32_t rw_number = 0; rw_number < wandering_females; rw_number++) {
diff --git a/src/modules/butterflies/butterflies_dispersal.h b/src/modules/butterflies/butterflies_dispersal.h
index 6385792ccd2b7055dbc0ad4fa0dac2bf2d07898c..d0fe418daccdaa8a03b71d48406dec781206f9ad 100644
--- a/src/modules/butterflies/butterflies_dispersal.h
+++ b/src/modules/butterflies/butterflies_dispersal.h
@@ -1,12 +1,14 @@
-//
-// Created by gattringera on 21/11/22.
-//
-
 #ifndef CATS_BUTTERFLIES_DISPERSAL_H
 #define CATS_BUTTERFLIES_DISPERSAL_H
 
 #include "threading/threading.h"
 #include "cats/configuration/configuration.h"
-void butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coord row, cats_dt_coord col, bool check_exclusion);
 
+void
+butterflies_cell_dispersal(struct cats_grid *grid, struct cats_thread_info *ts,
+                           cats_dt_coord row, cats_dt_coord col,
+                           bool check_exclusion,
+                           bool local_only);
+
+void bf_initial_population_to_eggs(struct cats_grid *grid, struct cats_thread_info *ts);
 #endif //CATS_BUTTERFLIES_DISPERSAL_H
diff --git a/src/modules/butterflies/butterflies_generations.c b/src/modules/butterflies/butterflies_generations.c
index b046bceae97003bf978fbbb420c023e1917ac1e4..70f21d1b01fc1164d2657db156d93046666c69f3 100644
--- a/src/modules/butterflies/butterflies_generations.c
+++ b/src/modules/butterflies/butterflies_generations.c
@@ -32,7 +32,6 @@ void bf_area_generation_update(struct cats_grid *grid, struct cats_thread_info *
         for (cats_dt_coord row = start_row; row < end_row; row++) {
                 for (cats_dt_coord col = start_col; col < end_col; col++) {
 
-
                         if (get_suitability(grid, row, col) < ot)
                         {
                                 if (data->eggs[row][col] > 0) cells_with_eggs_removed += 1;
@@ -69,4 +68,5 @@ void bf_area_generation_update(struct cats_grid *grid, struct cats_thread_info *
         stats->custom_stats[egg_cells_id] += cells_with_eggs;
         stats->custom_stats[egg_cells_removed_id] += cells_with_eggs_removed;
 
+
 }
\ No newline at end of file
diff --git a/src/modules/butterflies/butterflies_initial_population.c b/src/modules/butterflies/butterflies_initial_population.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4fc811d292b12b08cf0ad73a594ee11e36c3319
--- /dev/null
+++ b/src/modules/butterflies/butterflies_initial_population.c
@@ -0,0 +1,112 @@
+
+#include "lambda/leslie_matrix.h"
+#include "inline.h"
+
+#include "butterflies_dispersal.h"
+#include "butterflies_generations.h"
+#include "populations/population.h"
+#include "paths/paths.h"
+
+#include "butterflies_populations.h"
+
+#include "butterflies_main.h"
+#include "butterflies_actions.h"
+#include "modules/module_header.h"
+#include "actions/cats_actions.h"
+#include "butterflies_initial_population.h"
+
+
+void bf_initial_population_adjustment(struct cats_configuration *conf, struct cats_grid *grid)
+{
+        int64_t init_populated_cells = count_populated_cells(grid);
+        int64_t invalid_resources = butterflies_prune_invalid_cells(grid);
+        log_message(LOG_IMPORTANT, "Loaded initial populations: %ld cells occupied before adjustment",
+                    init_populated_cells);
+        if (grid->param.initial_population.set_to_cc == true) {
+
+//#define DEBUG_INITIAL_POPULATIONS 1
+#ifdef DEBUG_INITIAL_POPULATIONS
+                const int32_t max_i = 10;
+                struct cats_vital_rate *cc_rate = &grid->param.carrying_capacity;
+                cats_dt_rates OT =  grid->param.OT;
+                for (int32_t i = 0; i < max_i; i++) {
+
+                        cats_dt_rates suit = OT + i * (1.0 - OT)/max_i;
+                        cats_dt_rates cc = cc_rate->func->func(cc_rate, &grid->param, suit, 0, NAN);
+                        log_message(LOG_INFO, "Carrying capacity for suitability %Lf: %Lf", suit, cc);
+
+                }
+                const cats_dt_coord rows = grid->dimension.rows;
+                const cats_dt_coord cols = grid->dimension.cols;
+                int64_t start = 0;
+                int64_t multi_excluded = 0;
+
+                for (cats_dt_coord row = 0; row < rows; row++) {
+                        for (cats_dt_coord col = 0; col < cols; col++) {
+
+                                if (get_adult_population(grid, row, col) == 0) continue;
+                                start += 1;
+                                cats_dt_rates multiplier = 1.0;
+                                if (conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
+                                        multiplier *= conf->overlays.habitat_cc->data[row][col];
+                                }
+                                cats_dt_rates suit = get_suitability(grid, row, col);
+                                cats_dt_rates cc_raw = cc_rate->func->func(cc_rate, &grid->param, suit, 0, NAN);
+                                if (multiplier == 0) {
+                                    multi_excluded += 1;
+                                }
+                                cats_dt_population cc = get_carrying_capacity(grid, row, col);
+
+                                printf("DEBUG::row %d col %d, suit %Lf, cc multi %Lf, cc raw %Lf, cc %d\n", row, col, suit, multiplier, cc_raw, cc);
+                        }
+                }
+
+
+
+#endif
+
+                increase_initial_population_to_cc(grid, conf);
+                int64_t populated_cells_after_cc = count_populated_cells(grid);
+                log_message(LOG_IMPORTANT, "\t%ld cells occupied after setting population sizes to carrying capacity",
+                            populated_cells_after_cc);
+        }
+
+
+        if (grid->param.initial_population.suitability_threshold > 0.0) {
+                prune_initial_population_under_threshold(conf, grid);
+        }
+
+        int64_t after_populated_cells = count_populated_cells(grid);
+
+        log_message(LOG_IMPORTANT, "Pruned initial populations from %ld cells to %ld, (%ld wrong habitat)",
+                    init_populated_cells, after_populated_cells, invalid_resources);
+
+
+        cats_dt_population rows = grid->dimension.rows;
+        cats_dt_population cols = grid->dimension.cols;
+
+        threaded_action(&bf_initial_population_to_eggs, grid, conf, TS_DISPERSAL);
+
+#ifdef BF_DEBUG
+        int module_id = CATS_MODULE_ID;
+        struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
+#endif
+
+
+        for (cats_dt_coord row = 0; row < rows; row++) {
+                for (cats_dt_coord col = 0; col < cols; col++) {
+#ifdef BF_DEBUG
+                        if (get_adult_population(grid, row, col) || data->eggs[row][col]) {
+                                printf(""
+                                       "BFDBG::%s::initial adults -> eggs::%d,%d,%d,%f\n",
+                                       __func__, row, col, get_adult_population(grid, row, col),
+                                       data->eggs[row][col]);
+                        }
+#endif
+                        set_population_ignore_cc(grid, row, col, 0);
+                }
+        }
+
+
+        grid->param.initial_population.adjusted = true;
+}
\ No newline at end of file
diff --git a/src/modules/butterflies/butterflies_initial_population.h b/src/modules/butterflies/butterflies_initial_population.h
new file mode 100644
index 0000000000000000000000000000000000000000..718f3cf48fa1380bc16b757767ea4107ceb4b04f
--- /dev/null
+++ b/src/modules/butterflies/butterflies_initial_population.h
@@ -0,0 +1,5 @@
+#ifndef CATS_BUTTERFLIES_INITIAL_POPULATION_H
+#define CATS_BUTTERFLIES_INITIAL_POPULATION_H
+#include "data/cats_grid.h"
+void bf_initial_population_adjustment(struct cats_configuration *conf, struct cats_grid *grid);
+#endif //CATS_BUTTERFLIES_INITIAL_POPULATION_H
diff --git a/src/modules/butterflies/butterflies_main.c b/src/modules/butterflies/butterflies_main.c
index bd0d13a8c7068a36610f77a16a360d15a60bb362..bd1ee7b29daa0262dc949bb5361af95ea7417ae0 100644
--- a/src/modules/butterflies/butterflies_main.c
+++ b/src/modules/butterflies/butterflies_main.c
@@ -7,50 +7,38 @@
 #include "butterflies_actions.h"
 #include "butterflies_vital_rates.h"
 #include "cats_ini/cats_ini.h"
-#include "butterflies_action_helpers.h"
+#include "butterflies_actions_setup.h"
 #include "paths/output_paths.h"
 #include "paths/directory_helper.h"
 #include "butterflies_populations.h"
-#include "butterflies_filenames.h"
+#include "butterflies_paths.h"
 struct cats_global global;
 struct cats_debug_options cats_debug;
 
 #include "lambda/leslie_matrix.h"
+#include "actions/setup_actions.h"
+#include "butterflies_scale.h"
 
 
-double *butterflies_matrix(struct cats_configuration *conf, struct lambda_parameters *l_param,
-                                             bool silent, int32_t *N_out){
-        bool print_rate = !silent;
-
+cats_dt_rates bf_expected_local_eggs_per_female(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
+{
         struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
-        cats_dt_rates eggs_per_female = calculate_rate_for_matrix(&module_conf->eggs_per_female, l_param, print_rate);
-        cats_dt_rates reproduction_rate = calculate_rate_for_matrix(&module_conf->reproduction_rate, l_param, print_rate);
-        cats_dt_rates female_fraction = module_conf->female_fraction;
         cats_dt_rates stationary = module_conf->probability_to_stay;
         cats_dt_rates mobile = 1.0 - stationary;
         cats_dt_rates egg_fraction_source = module_conf->egg_fraction_source;
-
+        cats_dt_rates eggs_per_female = calculate_rate(&module_conf->eggs_per_female, NAN, &grid->param, grid, row, col, NULL);
         cats_dt_rates local_eggs =  (stationary + mobile * egg_fraction_source ) * eggs_per_female;
-        // female -> female
-        // to achieve the target reproduction rate, the number of eggs per female laid in the cell
-        // that survive and become adult has to be the reproduction rate divided by the female fraction divided by the number of eggs
-        cats_dt_rates eggs_to_adults_rate = bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs, female_fraction);
-        cats_dt_rates result =  local_eggs * eggs_to_adults_rate * female_fraction;
-
-        double *matrix = calloc_or_die(1, sizeof(double));
-
-        *matrix = (double) result;
-        *N_out = 1;
-        return matrix;
-
+        return local_eggs;
 }
 
 
+
 void *butterfly_grid_init(__attribute__((unused)) struct cats_configuration *conf, struct cats_grid *grid,
                           __attribute__((unused)) void *ignored)
 {
-        log_message(LOG_INFO, "%s: %s: grid init", module_name, __func__);
-        printf("%d %d\n", grid->dimension.cols, grid->dimension.rows);
+        log_message(LOG_INFO, "%s: %s: grid init of grid %d with %d rows and %d cols",
+                    module_name, __func__, grid->id, 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");
@@ -171,24 +159,30 @@ void load_butterflies_species_params(struct cats_configuration *conf, struct cat
 
         if (!data->actions_added) {
                 bf_register_actions(conf);
+                list_actions_full(conf);
+                log_message(LOG_EMPTY, " ");
                 bf_add_actions(conf);
+                log_message(LOG_EMPTY, " ");
+
                 data->actions_added = true;
+
+
         }
 
 }
 
 
-void cats_module_init(struct cats_configuration *conf)
+int 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, butterfly_grid_cleanup);
         register_load_species_param_config_func(conf, load_butterflies_species_params);
-        register_create_leslie_matrix_func(conf, butterflies_matrix);
+        register_create_leslie_matrix_func(conf, bf_leslie_matrix);
         bf_add_vital_rates(conf, data);
 
-        log_message(LOG_INFO, "Hello from %s (id: %d)\n", module_name, id);
+        log_message(LOG_INFO, "Hello from '%s' (id: %d)", module_name, id);
 
 
         for (enum butterfly_stats which = BF_STAT_MIN; which < BF_STAT_MAX; which++) {
@@ -196,4 +190,5 @@ void cats_module_init(struct cats_configuration *conf)
         }
 
         bf_add_directories(conf);
+        return id;
 }
diff --git a/src/modules/butterflies/butterflies_overlays.c b/src/modules/butterflies/butterflies_overlays.c
index 2dd223fcdadb8090bdd455ecf94a7f55db50ef0a..704b4fb5a10c1c0b60c34bd24a5e5335ad2f190b 100644
--- a/src/modules/butterflies/butterflies_overlays.c
+++ b/src/modules/butterflies/butterflies_overlays.c
@@ -96,6 +96,8 @@ enum action_status bf_grid_overlay_update(const struct cats_configuration *conf,
                     cells_with_eggs, total_eggs, total_eggs / (float) cells_with_eggs);
         log_message(LOG_INFO, "Overlay update: %ld cells with eggs removed", cells_eggs_removed);
         log_message(LOG_INFO, "Overlay update: %ld cells with adults removed", cells_adults_removed);
+
+
         return ACTION_RUN;
 }
 
diff --git a/src/modules/butterflies/butterflies_filenames.c b/src/modules/butterflies/butterflies_paths.c
similarity index 99%
rename from src/modules/butterflies/butterflies_filenames.c
rename to src/modules/butterflies/butterflies_paths.c
index 1b37a6469b0464bb118bf2f720dbc6c80c03847e..29ca2fef3a387c16d5dab0fa6921aa7609f0dfc4 100644
--- a/src/modules/butterflies/butterflies_filenames.c
+++ b/src/modules/butterflies/butterflies_paths.c
@@ -7,7 +7,7 @@
 #include "butterflies_actions.h"
 #include "modules/module_header.h"
 #include "actions/cats_actions.h"
-#include "butterflies_filenames.h"
+#include "butterflies_paths.h"
 #include "module.h"
 
 void bf_add_directories(struct cats_configuration *conf)
diff --git a/src/modules/butterflies/butterflies_filenames.h b/src/modules/butterflies/butterflies_paths.h
similarity index 80%
rename from src/modules/butterflies/butterflies_filenames.h
rename to src/modules/butterflies/butterflies_paths.h
index 05ae28669045342007e32e01ef73bda75ef99d45..a109363339cf3b5e428182be01ffd534304da700 100644
--- a/src/modules/butterflies/butterflies_filenames.h
+++ b/src/modules/butterflies/butterflies_paths.h
@@ -1,5 +1,5 @@
-#ifndef CATS_BUTTERFLIES_FILENAMES_H
-#define CATS_BUTTERFLIES_FILENAMES_H
+#ifndef CATS_BUTTERFLIES_PATHS_H
+#define CATS_BUTTERFLIES_PATHS_H
 
 #include "configuration/configuration.h"
 char *bf_population_eggs_filename(struct cats_configuration *conf, struct cats_grid *grid);
@@ -7,4 +7,4 @@ char *bf_population_filename(struct cats_configuration *conf, struct cats_grid *
 char *bf_stats_filename(struct cats_configuration *conf, struct cats_grid *grid);
 char *bf_population_overlay_filename(struct cats_configuration *conf, struct cats_grid *grid);
 void bf_add_directories(struct cats_configuration *conf);
-#endif //CATS_BUTTERFLIES_FILENAMES_H
+#endif //CATS_BUTTERFLIES_PATHS_H
diff --git a/src/modules/butterflies/butterflies_populations.c b/src/modules/butterflies/butterflies_populations.c
index 8480c84653972b4807570692df82aac798b66675..1ce531422f0946aa649381543248976f8856bf92 100644
--- a/src/modules/butterflies/butterflies_populations.c
+++ b/src/modules/butterflies/butterflies_populations.c
@@ -12,39 +12,80 @@
 #include "butterflies_populations.h"
 #include "butterflies_main.h"
 #include "butterflies_inline.h"
-#include "inline_population.h"
 #include "inline.h"
 #include "populations/population.h"
 
+int64_t count_populated_cells(const struct cats_grid *grid)
+{
+        int64_t cells = 0;
+        cats_dt_coord rows = grid->dimension.rows;
+        cats_dt_coord cols = grid->dimension.cols;
+        for (cats_dt_coord row = 0; row < rows; row++) {
+                for (cats_dt_coord col = 0; col < cols; col++) {
+                        if (get_adult_population(grid, row, col)) {
+                                cells += 1;
+                        }
+
+                }
+        }
+        return cells;
+}
+
+
+int64_t butterflies_prune_invalid_cells(struct cats_grid *grid)
+{
+        int64_t invalid_habitat = 0;
+        int module_id = CATS_MODULE_ID;
+        struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
+        cats_dt_coord rows = grid->dimension.rows;
+        cats_dt_coord cols = grid->dimension.cols;
+
+        for (cats_dt_coord row = 0; row < rows; row++) {
+                for (cats_dt_coord col = 0; col < cols; col++) {
+                        if (!(data->info_layer[row][col] & BF_CELL_VALID_DISPERSAL_TARGET)) {
+                                if(get_adult_population(grid, row, col)) {
+                                        invalid_habitat += 1;
+                                }
+                                set_population_ignore_cc(grid, row, col, 0);
+
+                        }
+                }
+        }
+        return invalid_habitat;
+}
 
-cats_dt_rates bf_egg_to_adult_survival_rate(cats_dt_rates reproduction_rate, cats_dt_rates eggs, cats_dt_rates female_fraction)
+
+cats_dt_rates
+bf_egg_to_adult_survival_rate(cats_dt_rates reproduction_rate, cats_dt_rates eggs)
 {
-        return (reproduction_rate / female_fraction) / eggs;
+        return reproduction_rate / eggs;
 }
 
+
 void bf_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;
         assert (conf->grid_count == 1);
-
         if (check_exclusion) {
                 if (bf_cell_excluded_by_generation(grid, row, col)) return;
         }
 
 
-
         const int module_id = CATS_MODULE_ID;
         struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
 
         if (data->eggs[row][col] == 0) return;
-
         if (data->eggs[row][col] < 0) {
                 log_message(LOG_ERROR, "Number of eggs < 0: row %d col %d: %f", row, col, data->eggs[row][col]);
                 exit(EXIT_FAILURE);
         }
 
+
+
+
+
         // the number of generations per cell is usually not an integer value
         // the non-integer part of the number of generations is used in the generation which is
         // one greater than the integer part of the number of generations
@@ -66,7 +107,7 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
         float current_generation_float = (float) data->generation_current;
 
         if (current_generation_float == local_generation
-        || data->generation_current == module_conf->generations_min) {
+            || data->generation_current == module_conf->generations_min) {
                 this_generation_fraction = 1.0f;
         } else if (data->generation_current == local_max_generation) {
                 this_generation_fraction = (float) local_max_generation - local_generation;
@@ -77,6 +118,11 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
 
         //cats_dt_population max_cc = (cats_dt_population) grid->param.carrying_capacity.max_rate;
         float eggs = this_generation_fraction * data->eggs[row][col];
+#ifdef BF_DEBUG
+        printf("BFDBG::%s::row %d, col %d: local gen %f gen fraction %f, eggs %f, this gen eggs %f\n",
+               __func__, row, col, local_generation, this_generation_fraction, data->eggs[row][col], eggs);
+#endif
+        if (eggs == 0) return;
 
         if (eggs > data->eggs[row][col]) {
                 log_message(LOG_ERROR, "Removing more eggs than present: %d %d: %f/%f", row, col, data->eggs[row][col],
@@ -85,10 +131,8 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
         }
 
         data->eggs[row][col] -= eggs;
-
-
         assert(data->eggs[row][col] >= 0);
-        if (eggs == 0) return;
+
 
         // not capped, we can have more adults than CC
 
@@ -96,7 +140,8 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
         cats_dt_rates reproduction_rate = calculate_rate(&module_conf->reproduction_rate, NAN, &grid->param,
                                                          grid, row, col, NULL);
         if (suit < grid->param.OT && reproduction_rate > 0) {
-                log_message(LOG_ERROR, "Suitability %f under OT %Lf, but adults per female = %Lf", suit, grid->param.OT, reproduction_rate);
+                log_message(LOG_ERROR, "Suitability %f under OT %Lf, but adults per female = %Lf", suit, grid->param.OT,
+                            reproduction_rate);
                 exit_cats(EXIT_FAILURE);
         }
 
@@ -108,15 +153,19 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
                 return;
         }
 
-
-
-
-        cats_dt_rates survival = bf_egg_to_adult_survival_rate(reproduction_rate, eggs, module_conf->female_fraction);
+        cats_dt_rates expected_eggs = bf_expected_local_eggs_per_female(ts->conf, grid, row, col);
+        cats_dt_rates survival = bf_egg_to_adult_survival_rate(reproduction_rate, expected_eggs)/module_conf->female_fraction;
         cats_dt_population adults = poisson(ts->rng, eggs * survival);
         assert(adults >= 0);
-
-
         set_population(grid, row, col, adults);
+#ifdef BF_DEBUG
+        adults = get_adult_population(grid, row, col);
+        printf("BFDBG::%s::row %d, col %d: year %d, suitability %f, OT %Lf\n", __func__, row, col, conf->time.year_current, suit, grid->param.OT);
+        printf("BFDBG::%s::row %d, col %d: year %d, eggs %f, survival rate %Lf, reproduction rate %Lf, adults %d\n",
+               __func__, row, col, conf->time.year_current, eggs, survival, reproduction_rate, adults);
+        printf("XXXX,%d,%f,%d\n", conf->time.year_current, current_generation_float,adults);
+#endif
+
 
 }
 
diff --git a/src/modules/butterflies/butterflies_populations.h b/src/modules/butterflies/butterflies_populations.h
index f8f164b81c7f01c7b20d3bb37c15b81e9a976beb..894fce21b4a0c8315181dc58ce50c016bf901cdb 100644
--- a/src/modules/butterflies/butterflies_populations.h
+++ b/src/modules/butterflies/butterflies_populations.h
@@ -5,8 +5,10 @@
 #ifndef CATS_BUTTERFLIES_POPULATIONS_H
 #define CATS_BUTTERFLIES_POPULATIONS_H
 #include "data/cats_grid.h"
+int64_t count_populated_cells(const struct cats_grid *grid);
 void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coord row, cats_dt_coord col, bool check_exclusion);
 void bf_area_kill_adults(struct cats_grid *grid, struct cats_thread_info *ts);
-cats_dt_rates bf_egg_to_adult_survival_rate(cats_dt_rates reproduction_rate, cats_dt_rates eggs, cats_dt_rates female_ratio);
-
+cats_dt_rates bf_egg_to_adult_survival_rate(cats_dt_rates reproduction_rate, cats_dt_rates eggs);
+cats_dt_rates bf_expected_local_eggs_per_female(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col);
+int64_t butterflies_prune_invalid_cells(struct cats_grid *grid);
 #endif //CATS_BUTTERFLIES_POPULATIONS_H
diff --git a/src/modules/butterflies/butterflies_scale.c b/src/modules/butterflies/butterflies_scale.c
new file mode 100644
index 0000000000000000000000000000000000000000..53627e85d7c4126c8695708abea9bf05f83a4793
--- /dev/null
+++ b/src/modules/butterflies/butterflies_scale.c
@@ -0,0 +1,37 @@
+//
+// Created by andreas on 03/07/23.
+//
+#include "modules/module_header.h"
+#include "butterflies_main.h"
+#include "butterflies_scale.h"
+#include "butterflies_populations.h"
+
+
+double *bf_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters *l_param,
+                         bool silent, int32_t *N_out){
+        bool print_rate = !silent;
+
+        struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
+        cats_dt_rates eggs_per_female = calculate_rate_for_matrix(&module_conf->eggs_per_female, l_param, print_rate);
+        cats_dt_rates reproduction_rate = calculate_rate_for_matrix(&module_conf->reproduction_rate, l_param, print_rate);
+        cats_dt_rates stationary = module_conf->probability_to_stay;
+        cats_dt_rates mobile = 1.0 - stationary;
+        cats_dt_rates egg_fraction_source = module_conf->egg_fraction_source;
+
+        cats_dt_rates local_eggs =  (stationary + mobile * egg_fraction_source ) * eggs_per_female;
+
+        // female -> female
+        // to achieve the target reproduction rate, the number of eggs per female laid in the cell
+        // that survive and become adult has to be the reproduction rate divided by the female fraction divided by the number of eggs
+
+        cats_dt_rates eggs_to_adults_rate = bf_egg_to_adult_survival_rate(reproduction_rate, local_eggs) ;
+        cats_dt_rates result =  local_eggs * eggs_to_adults_rate;
+
+        printf("scale %Lf: eggs %Lf, eggs to adults %Lf\n", conf->param->scale_factor, eggs_per_female, eggs_to_adults_rate);
+        double *matrix = calloc_or_die(1, sizeof(double));
+
+        *matrix = (double) result;
+        *N_out = 1;
+        return matrix;
+
+}
\ No newline at end of file
diff --git a/src/modules/butterflies/butterflies_scale.h b/src/modules/butterflies/butterflies_scale.h
new file mode 100644
index 0000000000000000000000000000000000000000..3dbcd1d911a04e928e5159901818982804dfc5da
--- /dev/null
+++ b/src/modules/butterflies/butterflies_scale.h
@@ -0,0 +1,16 @@
+//
+// Created by andreas on 03/07/23.
+//
+
+#ifndef CATS_BUTTERFLIES_SCALE_H
+#define CATS_BUTTERFLIES_SCALE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "configuration/configuration.h"
+#include "lambda/leslie_matrix.h"
+
+double *bf_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters *l_param,
+                         bool silent, int32_t *N_out);
+
+#endif //CATS_BUTTERFLIES_SCALE_H
diff --git a/src/modules/butterflies/butterflies_stats.c b/src/modules/butterflies/butterflies_stats.c
index ce77d1b323e528ab4be50762f728ead21d26d4b1..20925e9467b81c86abd65d121e3b86430ea1150f 100644
--- a/src/modules/butterflies/butterflies_stats.c
+++ b/src/modules/butterflies/butterflies_stats.c
@@ -8,7 +8,7 @@
 #include "inline_overlays.h"
 #include "inline_population.h"
 #include "inline.h"
-#include "butterflies_filenames.h"
+#include "butterflies_paths.h"
 #include "temporal/phase_names.h"
 #include "temporal/years.h"
 
diff --git a/src/modules/cats_test_module/register_module.c b/src/modules/cats_test_module/register_module.c
index 7e12973861abfb7036f210e2db19e50bbd2aab72..c97616d35e85e56ecbdeb33dfc15df8e1af0b889 100644
--- a/src/modules/cats_test_module/register_module.c
+++ b/src/modules/cats_test_module/register_module.c
@@ -59,7 +59,7 @@ void cats_module_init(struct cats_configuration *conf)
         enum cats_module_flags flags = MODULE_NO_FLAGS;
         int32_t id = register_module(conf, module_name, data, flags);
         register_cats_grid_init_function(conf, grid_init, grid_cleanup);
-        log_message(LOG_INFO, "Hello from %s (id: %d)\n", module_name, id);
+        log_message(LOG_INFO, "Hello from '%s' (id: %d)", module_name, id);
         greeting2();
 
 }