diff --git a/CMakeLists.txt b/CMakeLists.txt
index 05993bf744095920ea251a6b776c119aaf8a45da..cf625b9a48322ab57e452a9be1518ca5047b3579 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,6 @@ if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUA
             -Wall
             -Werror
             -O3
-            -g
             -D_GNU_SOURCE
             -DHAVE_INLINE
             -DGSL_C99_INLINE
diff --git a/src/cats/CMakeLists.txt b/src/cats/CMakeLists.txt
index 00239ae79b9860e9a72cbc61f3233041b377a531..fb05cbcc22490e4cb15fc96ea5f9e61d72a8cd6c 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 overlays/overlay_resources.c overlays/overlay_resources.h paths/path_patterns.c paths/path_patterns.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 paths/path_patterns.c paths/path_patterns.h grids/dimensions.c grids/dimensions.h grids/direct_access.c grids/direct_access.h)
 target_include_directories(libcats PUBLIC ".")
 
 target_sources(libcats PRIVATE
diff --git a/src/cats/actions/process_inter_period_survival.c b/src/cats/actions/process_inter_period_survival.c
index 479385a710b9537fb919d1156d0de5ce54e15fdb..24c48b3000a25ca838e877d9d10e590efec142e9 100644
--- a/src/cats/actions/process_inter_period_survival.c
+++ b/src/cats/actions/process_inter_period_survival.c
@@ -57,22 +57,18 @@ void write_stats(struct cats_grid *grid, const struct cats_configuration *conf,
                 j_sum_weighted,
                 get_seed_sum(g, 0, 0));
 
-        fprintf(f, ",%f", g->dispersed_seeds[0][0]);
+        fprintf(f, ",%f", get_dispersed_seeds(grid, 0, 0));
         for (int32_t i = 0; i < seed_persistence; i++) {
-                if (g->seed_bank[0][0]) {
-                        fprintf(f, ",%f", g->seed_bank[0][0][i]);
+                if (seed_bank_exists(g, 0, 0)) {
+                        fprintf(f, ",%f", get_seed_bank_seeds(g, 0, 0, i));
                 } else {
                         fprintf(f, ",%f", 0.0);
 
                 }
         }
-        for (int32_t i = 0; i < max_age_of_maturity + 1; i++) {
-                if (g->juveniles[0][0]) {
-                        fprintf(f, ",%d", g->juveniles[0][0][i]);
-                } else {
 
-                        fprintf(f, ",%d", 0);
-                }
+        for (int32_t i = 0; i < max_age_of_maturity + 1; i++) {
+                fprintf(f, ",%d", get_juveniles(g, 0, 0, i));
         }
         fprintf(f, "\n");
 
diff --git a/src/cats/actions/process_seed_dispersal.c b/src/cats/actions/process_seed_dispersal.c
index 8157c95b09fcf74f17d9d72cbca5e0bdac6cf45c..ab47e317a7d4c765bc19bceb3f73e30616402330 100644
--- a/src/cats/actions/process_seed_dispersal.c
+++ b/src/cats/actions/process_seed_dispersal.c
@@ -43,6 +43,7 @@
 #include "inline_overlays.h"
 #include "actions/cats_actions.h"
 #include "temporal/years.h"
+#include "inline.h"
 
 void area_post_process_seeds(struct cats_grid *grid, struct cats_thread_info *ts);
 
@@ -106,7 +107,7 @@ enum action_status process_disperse_seeds(struct cats_grid *grid, struct cats_co
 
         if (conf->command_line_options.lambda_test) {
                 disperse_seeds(grid, 0, 0, grid->single_thread);
-                grid->seeds_produced[0][0] = 0.0f;
+                set_produced_seeds(grid, 0, 0, 0.0f);
                 cell_post_process_seeds(grid, conf, 0, 0, grid->single_thread);
                 return ACTION_RUN;
         }
@@ -172,7 +173,7 @@ void area_post_process_seeds(struct cats_grid *grid, struct cats_thread_info *ts
                         mark_cell_done(&debug, row, col);
 #endif
                         if (cell_excluded_by_overlay(conf, row, col)) {
-                                grid->dispersed_seeds[row][col] = 0;
+                                set_dispersed_seeds(grid, row, col, 0.0f);
                         } else {
                                 cell_post_process_seeds(grid, conf, row, col, ts);
                         }
@@ -194,8 +195,8 @@ void dispersal_wrapper(struct cats_grid *grid, struct cats_thread_info *ts)
                         mark_cell_done(&debug, row, col);
 #endif
                         if (cell_excluded_by_overlay(conf, row, col)) { continue; }
-                        if (grid->seeds_produced[row][col] > 0.0) disperse_seeds(grid, row, col, ts);
-                        grid->seeds_produced[row][col] = 0.0f;
+                        if (get_produced_seeds(grid, row, col) > 0.0) disperse_seeds(grid, row, col, ts);
+                        set_produced_seeds(grid, row, col, 0.0f);
                 }
         }
 }
diff --git a/src/cats/actions/setup.c b/src/cats/actions/setup.c
index d88079d3b9f4f5fe416fee6c3f9d6d6b7c425dc1..7252e60aae619729cbad693cd91ee1ddccd27b0d 100644
--- a/src/cats/actions/setup.c
+++ b/src/cats/actions/setup.c
@@ -37,6 +37,7 @@
 #include "temporal/simulation_time.h"
 #include "populations/population.h"
 #include "dispersal/dispersal.h"
+#include "inline.h"
 
 
 void setup_lambda_test_simulation(struct cats_configuration *conf, struct cats_grid *grid) // FIXME MAYBE MOVE
@@ -55,7 +56,7 @@ void setup_lambda_test_simulation(struct cats_configuration *conf, struct cats_g
         cats_dt_coord row = 0;
         cats_dt_coord col = 0;
 
-        grid->suitability->environments[0]->current.values[row][col] = (cats_dt_environment) grid->param.OT; // FIXME -> set suitability
+        set_suitability(grid, row, col,  (cats_dt_environment) grid->param.OT);
 
         cats_dt_population target_pop = get_adult_carrying_capacity(grid, row, col) / 5;
         set_population_ignore_cc(grid, row, col, target_pop);
@@ -94,7 +95,8 @@ void setup_lambda_gradient_simulation(struct cats_configuration *conf, struct ca
         cats_dt_environment diff = 1.0f / ((cats_dt_environment) conf->geometry.dimension.cols - 1.0f);
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
-                        grid->suitability->environments[0]->current.values[row][col] = (cats_dt_environment) col * diff;
+                        cats_dt_environment  value = (cats_dt_environment) col * diff;
+                        set_suitability(grid, row, col, value);
                 }
         }
 
diff --git a/src/cats/configuration/check_configuration.c b/src/cats/configuration/check_configuration.c
index 4eaae98ecaf30719d2db216b7da409c5473269d9..fb5445585a447ca2e7eeda0e451f22e146c89898 100644
--- a/src/cats/configuration/check_configuration.c
+++ b/src/cats/configuration/check_configuration.c
@@ -32,6 +32,7 @@
 #include "inline_vital_rates.h"
 #include "dispersal/dispersal.h"
 #include "data/simulation_geometry.h"
+#include "inline_vital_ages.h"
 
 
 int check_string(char *value, char *name)
diff --git a/src/cats/configuration/configuration.c b/src/cats/configuration/configuration.c
index 6d6fb2af6824235e861c56bdd6f93df2d5b257e6..c6cc5a61b9f0241d6c9b4076cddfd66e7c530262 100644
--- a/src/cats/configuration/configuration.c
+++ b/src/cats/configuration/configuration.c
@@ -48,6 +48,7 @@
 #include "inline_vital_rates.h"
 #include "dispersal/dispersal.h"
 #include "stats/grid_stats.h"
+#include "inline_vital_ages.h"
 
 #ifdef CATS_ON_WINDOWS
 #include <windows.h>
diff --git a/src/cats/configuration/preset.c b/src/cats/configuration/preset.c
index 562e3cfca9ca1f55ecf4348c38599efc244fb9aa..fef6c8a57e64756a6b57a4240261063187d0e64f 100644
--- a/src/cats/configuration/preset.c
+++ b/src/cats/configuration/preset.c
@@ -21,11 +21,14 @@
  *
  */
 
+#include <string.h>
 #include "cats_global.h"
 #include "preset.h"
 #include "vital_ages/default_vital_ages.h"
 #include "vital_rates/default_vital_rates.h"
 #include "inline_vital_rates.h"
+#include "inline_vital_ages.h"
+#include "misc/cats_maths_inline.h"
 
 
 enum cats_species_preset get_species_preset_from_from_string(const char *string)
diff --git a/src/cats/configuration/print_configuration.c b/src/cats/configuration/print_configuration.c
index 8265fe845b4b8d30efb164dc770ade3b11a814a0..13bb981936a3e8004d5aa5dce601aa421f5c51c4 100644
--- a/src/cats/configuration/print_configuration.c
+++ b/src/cats/configuration/print_configuration.c
@@ -33,6 +33,7 @@
 #include "inline_vital_rates.h"
 #include "dispersal/dispersal.h"
 #include "modules/load_module.h"
+#include "inline_vital_ages.h"
 
 const char *get_dispersal_name(enum dispersal_type type);
 
diff --git a/src/cats/debug/debug_vital_rates.c b/src/cats/debug/debug_vital_rates.c
index ec6f3625f7bbd5623949155b7a2ecf6e19a1f456..4e3de11fbc82b0bbb8a7da3cd59e36f6acc7b22a 100644
--- a/src/cats/debug/debug_vital_rates.c
+++ b/src/cats/debug/debug_vital_rates.c
@@ -90,7 +90,7 @@ struct cats_grid *minimal_grid(struct cats_configuration *conf, struct cats_envi
 }
 
 
-void set_suitability(struct cats_environment *env, cats_dt_environment suit)
+void debug_set_suitability(struct cats_environment *env, cats_dt_environment suit)
 {
         env->environments[0]->current.values[0][0] = suit;
 }
@@ -138,7 +138,7 @@ static inline cats_dt_rates attempt_rate_calculation(cats_dt_environment suit, c
         }
 
 
-        set_suitability(grid->suitability, suit);
+        debug_set_suitability(grid->suitability, suit);
         *K_suit = get_adult_carrying_capacity(grid, 0, 0);
         if (N > *K_suit) return NAN;
 
@@ -209,7 +209,7 @@ void debug_vital_rate(struct cats_vital_rate *vr, struct cats_vital_rate *cc, st
 void debug_vital_rates(struct cats_configuration *conf, const struct program_options *command_line_options)
 {
         struct cats_environment *env = minimal_suitability_environment();
-        set_suitability(env, 0.5f);
+        debug_set_suitability(env, 0.5f);
         struct cats_grid *grid = minimal_grid(conf, env);
         struct cats_species_param *param = &grid->param;
         set_param_values(param, 0.5, 0.25, 0.5);
diff --git a/src/cats/dispersal/dispersal.c b/src/cats/dispersal/dispersal.c
index 938c362b52f6e663e0f524c66a1be237dc1a64e2..4f13f4a51a23bb1a804bd4204457a598e14eeb53 100644
--- a/src/cats/dispersal/dispersal.c
+++ b/src/cats/dispersal/dispersal.c
@@ -51,6 +51,7 @@
 
 #include "memory/cats_memory.h"
 #include "inline_overlays.h"
+#include "inline.h"
 
 // ANSATZPUNKTE
 // 3 verschiedene dispersals:
@@ -153,7 +154,7 @@ void disperse_seeds(const struct cats_grid *restrict grid, cats_dt_coord s_row,
         assert(s_col < grid->dimension.cols);
 
 
-        float seeds = grid->seeds_produced[s_row][s_col];
+        float seeds = get_produced_seeds(grid, s_row, s_col);
         assert(seeds >= 0.0);
         if (seeds < 1.0) return;
 
diff --git a/src/cats/dispersal/local_dispersal.c b/src/cats/dispersal/local_dispersal.c
index c91fd5411d000bcf8d9040f389cd568eb85cb550..14c41918b72f56ddfa462330e76ddc542badd3a0 100644
--- a/src/cats/dispersal/local_dispersal.c
+++ b/src/cats/dispersal/local_dispersal.c
@@ -29,6 +29,7 @@
 #include "configuration/configuration.h"
 #include "data/cats_grid.h"
 #include "local_dispersal.h"
+#include "inline.h"
 
 
 void cell_local_dispersal(struct cats_configuration *conf, struct cats_grid *grid, cats_dt_coord row,
@@ -37,11 +38,12 @@ void cell_local_dispersal(struct cats_configuration *conf, struct cats_grid *gri
         const struct cats_dispersal *const dispersal = grid->dispersal;
         if (dispersal->local_dispersal <= 0.0) return;
 
-        float seeds = grid->seeds_produced[row][col];
+        float seeds = get_produced_seeds(grid, row, col);
 
         cats_dt_seeds self = (float) (seeds * dispersal->local_dispersal);
         self = min_float(seeds, self);
 
-        grid->dispersed_seeds[row][col] += self;
-        grid->seeds_produced[row][col] -= self;
+        increase_dispersed_seeds(grid, row, col, self);
+        decrease_produced_seeds(grid, row, col, self);
+
 }
\ No newline at end of file
diff --git a/src/cats/environment/environment.c b/src/cats/environment/environment.c
index 0f85e76c9623f18e51cbf92d2eea08cf7fbbb382..6b44fecde2b8128428bd8c73b29d3b3020e7947c 100644
--- a/src/cats/environment/environment.c
+++ b/src/cats/environment/environment.c
@@ -38,6 +38,7 @@
 #include "environment.h"
 #include "grids/gdal_load.h"
 #include "environment/environment_rasters.h"
+#include "grids/dimensions.h"
 
 #ifdef USEMPI
 #include "mpi/mpi_save.h"
@@ -69,10 +70,11 @@ void interpolate_environment(const struct cats_configuration *conf,
         const cats_dt_coord rows = environment->current.dimension.rows;
         const cats_dt_coord cols = environment->current.dimension.cols;
 
-        if (environment->start.dimension.rows != environment->end.dimension.rows
-            || environment->start.dimension.cols != environment->end.dimension.cols
-            || environment->start.dimension.rows != environment->current.dimension.rows
-            || environment->start.dimension.cols != environment->current.dimension.cols) {
+        bool matching_dimensions = cats_dimensions_match(&environment->start.dimension, &environment->end.dimension)
+                                   &&
+                                   cats_dimensions_match(&environment->start.dimension, &environment->current.dimension);
+
+        if (!matching_dimensions) {
                 log_message(LOG_ERROR, "%s: dimension mismatch", __func__);
                 log_message(LOG_ERROR, "environment (start):   %d x %d", environment->start.dimension.rows,
                             environment->start.dimension.cols);
@@ -149,8 +151,9 @@ load_environment_raster(struct cats_configuration *conf, struct cats_environment
         }
 
         unload_environment_raster(raster);
-        raster->dimension.rows = conf->geometry.dimension.rows;
-        raster->dimension.cols = conf->geometry.dimension.cols;
+
+        copy_cats_dimensions(&conf->geometry.dimension, &raster->dimension);
+
         raster->interpolation_type = type;
         raster->environment_type = environment_type;
         if (raster->values == NULL) {
diff --git a/src/cats/environment/environment_rasters.c b/src/cats/environment/environment_rasters.c
index e7a3a12f79f9c8ae006bda529ad47e709005c439..2c2f9025798c1bdd8ac77b452bfe29a128ce36d6 100644
--- a/src/cats/environment/environment_rasters.c
+++ b/src/cats/environment/environment_rasters.c
@@ -27,6 +27,7 @@
 #include "logging.h"
 #include "environment_rasters.h"
 #include "environment.h"
+#include "grids/dimensions.h"
 
 
 void print_raster_quick_info(struct cats_environment_raster *gr)
@@ -53,9 +54,8 @@ void create_raster_if_needed(struct cats_configuration *conf, struct cats_enviro
         log_message(LOG_INFO, "\tinitializing empty grid for <%s>", get_raster_type_name_specific(raster));
         log_message(LOG_DEBUG, "%s: ALLOCATING NEW GRID NOW", __func__);
         raster->values = new_raw_2d_array_from_dimension(conf->geometry.dimension, sizeof(cats_dt_environment));
-        raster->dimension.rows = conf->geometry.dimension.rows;
-        raster->dimension.cols = conf->geometry.dimension.cols;
 
+        copy_cats_dimensions(&conf->geometry.dimension, &raster->dimension);
 }
 
 
diff --git a/src/cats/grids/cats_grid.c b/src/cats/grids/cats_grid.c
index 8814d975d2f21948b7fa680b0318318436a7baee..b3edba612207830d1238ac09480daa84701def54 100644
--- a/src/cats/grids/cats_grid.c
+++ b/src/cats/grids/cats_grid.c
@@ -255,7 +255,7 @@ void cleanup_grid_seeds_and_juveniles(struct cats_grid *grid)
                         for (cats_dt_coord col = 0; col < grid->dimension.cols; col++) {
                                 destroy_seed_structure(grid, row, col);
                         }
-                        free(grid->seed_bank[row]);
+                        free(grid->seed_bank[row]);     // clean-up [cleanup_grid_seeds_and_juveniles]
                 }
         }
 
@@ -266,7 +266,7 @@ void cleanup_grid_seeds_and_juveniles(struct cats_grid *grid)
                                 destroy_juveniles(grid, row, col);
                         }
 
-                        free(grid->juveniles[row]);
+                        free(grid->juveniles[row]); // clean-up [cleanup_grid_seeds_and_juveniles]
                 }
        }
 
diff --git a/src/cats/grids/dimensions.c b/src/cats/grids/dimensions.c
new file mode 100644
index 0000000000000000000000000000000000000000..78f9dc6b1510f29877f762b6ef52b1fea2a1be89
--- /dev/null
+++ b/src/cats/grids/dimensions.c
@@ -0,0 +1,17 @@
+#include "dimensions.h"
+
+
+void copy_cats_dimensions(const struct cats_dimension *source, struct cats_dimension *destination)
+{
+        assert(source != NULL);
+        assert(destination != NULL);
+        destination->rows = source->rows;
+        destination->cols = source->cols;
+}
+
+
+bool cats_dimensions_match(const struct cats_dimension *dim1, const struct cats_dimension *dim2)
+{
+        if (dim1->rows == dim2->rows && dim1->cols == dim2->cols) return true;
+        return false;
+}
\ No newline at end of file
diff --git a/src/cats/grids/dimensions.h b/src/cats/grids/dimensions.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b62aaf503b5a7ea5445cb12b185ab6a4414198e
--- /dev/null
+++ b/src/cats/grids/dimensions.h
@@ -0,0 +1,23 @@
+#ifndef CATS_DIMENSIONS_H
+#define CATS_DIMENSIONS_H
+
+#include "memory/arrays.h"
+#include "assert.h"
+
+
+static inline bool valid_coordinates(const struct cats_dimension *dim, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(dim != NULL);
+        if (row < 0 || col < 0) return false;
+        if (row >= dim->rows || col >= dim->cols) return false;
+        return true;
+}
+
+
+void copy_cats_dimensions(const struct cats_dimension *source, struct cats_dimension *destination);
+
+bool cats_dimensions_match(const struct cats_dimension *dim1, const struct cats_dimension *dim2);
+
+bool valid_coordinates(const struct cats_dimension *dim, cats_dt_coord row, cats_dt_coord col);
+
+#endif //CATS_DIMENSIONS_H
diff --git a/src/cats/grids/direct_access.c b/src/cats/grids/direct_access.c
new file mode 100644
index 0000000000000000000000000000000000000000..cdb851962d4a98c16196a7e62f7767d1d8673b63
--- /dev/null
+++ b/src/cats/grids/direct_access.c
@@ -0,0 +1,28 @@
+#include <assert.h>
+#include "direct_access.h"
+#include "dimensions.h"
+
+
+double load_input_2d_array_double(const struct cats_2d_array_double *raster, cats_dt_coord row, cats_dt_coord col)
+{
+        valid_coordinates(&raster->dimension, row, col);
+        return raster->data[row][col];  // getter [load_input2d_array_double]
+}
+
+char load_input_2d_array_char(const struct cats_2d_array_char *raster, cats_dt_coord row, cats_dt_coord col)
+{
+        valid_coordinates(&raster->dimension, row, col);
+        return raster->data[row][col];  // getter [load_input_2d_array_char]
+}
+
+cats_dt_environment load_input_environment_raster(struct cats_environment_raster *raster, cats_dt_coord row, cats_dt_coord col)
+{
+        valid_coordinates(&raster->dimension, row, col);
+        return raster->values[row][col];  // getter [load_input_environment_raster]
+}
+
+void set_input_environment_raster(struct cats_environment_raster *raster, cats_dt_coord row, cats_dt_coord col, cats_dt_environment value)
+{
+        valid_coordinates(&raster->dimension, row, col);
+        raster->values[row][col] = value;  // getter [set_input_environment_raster]
+}
\ No newline at end of file
diff --git a/src/cats/grids/direct_access.h b/src/cats/grids/direct_access.h
new file mode 100644
index 0000000000000000000000000000000000000000..147dab25442a3ee11f9b7eebae28dd2cbee7f3b4
--- /dev/null
+++ b/src/cats/grids/direct_access.h
@@ -0,0 +1,10 @@
+#ifndef CATS_DIRECT_ACCESS_H
+#define CATS_DIRECT_ACCESS_H
+#include "memory/arrays.h"
+#include "environment/environment.h"
+
+double load_input_2d_array_double(const struct cats_2d_array_double *raster, cats_dt_coord row, cats_dt_coord col);
+cats_dt_environment load_input_environment_raster(struct cats_environment_raster *raster, cats_dt_coord row, cats_dt_coord col);
+void set_input_environment_raster(struct cats_environment_raster *raster, cats_dt_coord row, cats_dt_coord col, cats_dt_environment value);
+char load_input_2d_array_char(const struct cats_2d_array_char *raster, cats_dt_coord row, cats_dt_coord col);
+#endif //CATS_DIRECT_ACCESS_H
diff --git a/src/cats/grids/gdal_save.c b/src/cats/grids/gdal_save.c
index b6d25342bc7332ef4447fbbb0aa26d920a439d3b..6a2e0a244b11a08f903391cce702a10606134692 100644
--- a/src/cats/grids/gdal_save.c
+++ b/src/cats/grids/gdal_save.c
@@ -132,7 +132,7 @@ void *save_dispersed_seeds_to_gdal(struct cats_grid *grid, struct cats_configura
         const int32_t cols = grid->dimension.cols;
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
-                        seeds[row][col] = grid->dispersed_seeds[row][col];
+                        seeds[row][col] = get_dispersed_seeds(grid, row, col);
                 }
         }
 
@@ -173,13 +173,13 @@ void *save_seeds_to_gdal(struct cats_grid *grid, struct cats_configuration *conf
                         for (cats_dt_coord col = 0; col < cols; col++) {
                                 if (i > 0) {
                                         int year = i - 1;
-                                        if (grid->seed_bank[row][col]) {
-                                                seeds[row][col] = (int32_t) grid->seed_bank[row][col][year];
+                                        if (seed_bank_exists(grid, row, col)) {
+                                                seeds[row][col] = (int32_t) get_seed_bank_seeds(grid, row, col, year);
                                         } else {
                                                 seeds[row][col] = 0;
                                         }
                                 } else {
-                                        seeds[row][col] = (int32_t) grid->dispersed_seeds[row][col];
+                                        seeds[row][col] = (int32_t) get_dispersed_seeds(grid, row, col);
                                 }
                         }
                 }
@@ -221,11 +221,7 @@ void *save_juveniles_to_gdal(struct cats_grid *grid, struct cats_configuration *
                                                   sizeof(int32_t));//new_int32t_grid(grid->rows, grid->cols);
                 for (cats_dt_coord row = 0; row < rows; row++) {
                         for (cats_dt_coord col = 0; col < cols; col++) {
-                                if (grid->juveniles[row][col]) {
-                                        juvs[row][col] = grid->juveniles[row][col][i];
-                                } else {
-                                        juvs[row][col] = 0;
-                                }
+                                juvs[row][col] = get_juveniles(grid, row, col, i);
                         }
                 }
                 struct cats_dimension dim = {.rows = rows, .cols = cols};
diff --git a/src/cats/grids/grid_converters.c b/src/cats/grids/grid_converters.c
index b09dd2c32afda8bdbccf6599b83942e91f9db761..f76b82a9e0fc5f9b02fbfefe73d03246b10acdc9 100644
--- a/src/cats/grids/grid_converters.c
+++ b/src/cats/grids/grid_converters.c
@@ -33,6 +33,7 @@
 #include "populations/population.h"
 #include "inline_population.h"
 #include "dispersal/dispersal.h"
+#include "misc/cats_maths_inline.h"
 
 
 cats_dt_environment **convert_double_to_environment(const struct cats_2d_array_double *in_grid)
@@ -43,7 +44,7 @@ cats_dt_environment **convert_double_to_environment(const struct cats_2d_array_d
         const cats_dt_coord cols = in_grid->dimension.cols;
         for (int32_t r = 0; r < rows; r++) {
                 for (int32_t c = 0; c < cols; c++) {
-                        array[r][c] = (float) in_grid->data[r][c];
+                        array[r][c] = (float) in_grid->data[r][c]; // converter [convert_double_to_environment]
                 }
         }
 
diff --git a/src/cats/grids/grid_setup.c b/src/cats/grids/grid_setup.c
index e8b72b419bb9aae992449aa5422d05afa4e13941..3f879c20afa42ce1dc704d4a1c2a1870667337f9 100644
--- a/src/cats/grids/grid_setup.c
+++ b/src/cats/grids/grid_setup.c
@@ -53,10 +53,10 @@ void setup_grid_seed_structures(const struct cats_configuration *conf, struct ca
         grid->seed_bank = calloc_or_die(rows, sizeof(cats_dt_seeds **));
 
         for (cats_dt_coord row = 0; row < rows; row++) {
-                grid->seed_bank[row] = calloc_or_die(cols, sizeof(cats_dt_seeds *));
+                grid->seed_bank[row] = calloc_or_die(cols, sizeof(cats_dt_seeds *));  // initialisation [setup_grid_seed_structure]
 
                 for (cats_dt_coord col = 0; col < cols; col++) {
-                        grid->seed_bank[row][col] = NULL;
+                        grid->seed_bank[row][col] = NULL;  // initialisation [setup_grid_seed_structure]
                 }
         }
 }
@@ -98,10 +98,10 @@ void setup_grid_juvenile_structures_opt(struct cats_configuration *conf, struct
         grid->juveniles = calloc_or_die(grid->dimension.rows, sizeof(cats_dt_population **));
 
         for (cats_dt_coord row = 0; row < grid->dimension.rows; row++) {
-                grid->juveniles[row] = calloc_or_die(grid->dimension.cols, sizeof(cats_dt_population *));
+                grid->juveniles[row] = calloc_or_die(grid->dimension.cols, sizeof(cats_dt_population *)); // initialisation [setup_grid_juvenile_structures_opt]
 
                 for (cats_dt_coord col = 0; col < grid->dimension.cols; col++) {
-                        grid->juveniles[row][col] = NULL;
+                        grid->juveniles[row][col] = NULL;  // initialisation [setup_grid_juvenile_structures_opt]
                 }
         }
 }
diff --git a/src/cats/inline.h b/src/cats/inline.h
index da78d7702595de8e57ce90e6454941d9b4b5c172..cb0f3b5c0a46255c77760fd78e1753426867c5ce 100644
--- a/src/cats/inline.h
+++ b/src/cats/inline.h
@@ -42,6 +42,25 @@
 #include "inline_carrying_capacity.h"
 #include "inline_population.h"
 #include "inline_vital_ages.h"
+#include "grids/dimensions.h"
+
+static inline bool valid_dispersed_seeds_grid(const struct cats_grid *grid, cats_dt_coord row)
+{
+        if (grid == NULL) return false;
+        if (grid->dispersed_seeds == NULL) return false;
+        if (grid->dispersed_seeds[row] == NULL) return false;       // validator [valid_dispersed_seeds_grid]
+        return true;
+}
+
+
+static inline bool valid_produced_seed_grid(const struct cats_grid *grid, cats_dt_coord row)
+{
+        if (grid == NULL) return false;
+        if (grid->seeds_produced == NULL) return false;
+        if (grid->seeds_produced[row] == NULL) return false;       // validator [valid_produced_seed_grid]
+        return true;
+}
+
 
 
 static inline cats_dt_environment
@@ -49,11 +68,124 @@ get_suitability_from_env(const struct cats_environment *set, cats_dt_coord row,
 {
         assert(set->type == ENVIRONMENT_TYPE_SUITABILITY);
         assert(set->count == 1);
-        assert(row >= 0);
-        assert(col >= 0);
-        assert(row < set->environments[0]->current.dimension.rows);
-        assert(col < set->environments[0]->current.dimension.cols);
-        return set->environments[0]->current.values[row][col];
+        assert(valid_coordinates(&set->environments[0]->current.dimension, row, col));
+        return load_input_environment_raster(&set->environments[0]->current, row, col);
+}
+
+static inline cats_dt_seeds
+get_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_dispersed_seeds_grid(grid, row));
+        return grid->dispersed_seeds[row][col];  // getter [get_dispersed_seeds]
+}
+
+static inline void
+set_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds seeds)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_dispersed_seeds_grid(grid, row));
+        assert(seeds >= 0);
+        grid->dispersed_seeds[row][col] = seeds;  // setter [set_dispersed_seeds]
+}
+
+static inline void
+increase_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_dispersed_seeds_grid(grid, row));
+        assert(by >= 0);
+        grid->dispersed_seeds[row][col] += by;  // setter [increase_dispersed_seeds]
+}
+
+static inline void
+decrease_dispersed_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_dispersed_seeds_grid(grid, row));
+        assert(by >= 0);
+        grid->dispersed_seeds[row][col] -= by;  // setter [decrease_dispersed_seeds]
+        assert(grid->dispersed_seeds[row][col] >= 0); // setter [decrease_dispersed_seeds]
+}
+
+
+
+static inline cats_dt_seeds
+get_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_produced_seed_grid(grid, row));
+        return grid->seeds_produced[row][col];  // getter [get_produced_seeds]
+}
+
+static inline bool valid_seed_bank_grid(const struct cats_grid *grid, cats_dt_coord row)
+{
+        if (grid == NULL || grid->seed_bank == NULL || grid->seed_bank[row] == NULL) return false;  // validator [valid_seed_bank_grid]
+        return true;
+}
+
+static inline bool seed_bank_exists(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_seed_bank_grid(grid, row));
+        return grid->seed_bank[row][col] != NULL; // validator [seed_bank_exists]
+}
+
+static inline cats_dt_seeds get_seed_bank_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int32_t year)
+{
+        assert(seed_bank_exists(grid, row, col));
+        assert(year < get_vital_age(grid, VA_SEED_PERSISTENCE));
+        assert(year >= 0);
+        return grid->seed_bank[row][col][year]; // getter [get_seed_bank_seeds]
+}
+
+static inline void set_seed_bank_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int32_t year, cats_dt_seeds seeds)
+{
+        assert(seed_bank_exists(grid, row, col));
+        assert(year < get_vital_age(grid, VA_SEED_PERSISTENCE));
+        assert(seeds >= 0.0f);
+        grid->seed_bank[row][col][year] = seeds; // setter [set_seed_bank_seeds]
+}
+
+
+
+static inline void
+set_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds seeds)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_produced_seed_grid(grid, row));
+        assert(seeds >= 0);
+        grid->seeds_produced[row][col] = seeds;  // setter [set_produced_seeds]
+}
+
+static inline void
+increase_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_produced_seed_grid(grid, row));
+        assert(by > 0);
+        grid->seeds_produced[row][col] += by;  // setter [increase_produced_seeds]
+}
+
+
+static inline void
+decrease_produced_seeds(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_seeds by)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_produced_seed_grid(grid, row));
+        assert(by > 0);
+        grid->seeds_produced[row][col] -= by;  // setter [decrease_produced_seeds]
+        assert(grid->seeds_produced[row][col] >= 0); // setter [decrease_produced_seeds]
+}
+
+
+
+static inline void
+set_suitability(struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_environment value)
+{
+        assert(value >= 0.0f);
+        assert(value <= 1.0f);
+        set_input_environment_raster(&grid->suitability->environments[0]->current, row, col, value);
 }
 
 
@@ -171,13 +303,13 @@ static inline cats_dt_environment get_suitability(const struct cats_grid *grid,
 static inline double get_seed_sum(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
 {
         assert(grid != NULL && grid->juveniles != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
+        assert(valid_coordinates(&grid->dimension, row, col));
         const int32_t max_sp = get_vital_age(grid, VA_SEED_PERSISTENCE); //grid->param.seed_persistence;
-        double sum = grid->dispersed_seeds[row][col];
-        if (grid->seed_bank[row][col] == NULL) return sum;
+        double sum = get_dispersed_seeds(grid, row, col);
+
+        if (!seed_bank_exists(grid, row, col)) return sum;
         for (int32_t i = 0; i < max_sp; i++) {
-                sum += grid->seed_bank[row][col][i];
+                sum += get_seed_bank_seeds(grid, row, col, i);
         }
         return sum;
 }
@@ -187,20 +319,16 @@ static inline cats_dt_population_sum
 get_juvenile_sum(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
 {
         assert(grid != NULL && grid->juveniles != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
-        assert(grid->juveniles[row] != NULL);
+        if (!juveniles_exist(grid, row, col)) return 0;
 
-        const cats_dt_population *juveniles = grid->juveniles[row][col];
-        if (juveniles == NULL) return 0;
+        const cats_dt_population *juveniles = grid->juveniles[row][col];        // getter [get_juvenile_sum]
 
         cats_dt_population_sum juvenile_sum = 0;
-        const int32_t max_stage =
-                get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1; //grid->param.max_age_of_maturity + 1;
+        const int32_t max_stage = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1;
+
         for (int32_t i = 0; i < max_stage; i++) {
-                juvenile_sum += juveniles[i];
+                juvenile_sum += juveniles[i]; // getter [get_juvenile_sum]
         }
-
         return juvenile_sum;
 }
 
diff --git a/src/cats/inline_carrying_capacity.h b/src/cats/inline_carrying_capacity.h
index 9b4c42ceeed868d41220383216ec2fd98e1c70e0..c598758133c5d65cdfd8c5229bbe885ef724e512 100644
--- a/src/cats/inline_carrying_capacity.h
+++ b/src/cats/inline_carrying_capacity.h
@@ -36,6 +36,7 @@
 #include "configuration/configuration.h"
 #include "plants/juveniles.h"
 #include "inline_vital_ages.h"
+#include "inline_carrying_capacity.h"
 
 
 static inline cats_dt_rates juvenile_cc_multiplier(const struct cats_species_param *param, int32_t stage)
diff --git a/src/cats/inline_overlays.h b/src/cats/inline_overlays.h
index 519689e39cf39c53b519c1de0e5529f6948fc49e..5248ecb2a67bcae8df8a5badcd96b782e0b70df7 100644
--- a/src/cats/inline_overlays.h
+++ b/src/cats/inline_overlays.h
@@ -28,6 +28,7 @@
 #include "assert.h"
 #include "overlays/overlays.h"
 #include "configuration/configuration.h"
+#include "grids/direct_access.h"
 
 
 static inline bool
@@ -35,21 +36,20 @@ cell_excluded_by_habitat(const struct cats_configuration *config, cats_dt_coord
 {
         if (!config->overlays.have_overlays) return false;
         if (!config->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) return false;
-
-        return (config->overlays.habitat_cc->data[row][col] == 0.0);
+        return (load_input_2d_array_double(config->overlays.habitat_cc, row, col) == 0.0);
 }
 
-
 static inline bool
 cell_excluded_by_overlay(const struct cats_configuration *config, cats_dt_coord row, cats_dt_coord col)
 {
         assert(config != NULL);
 
-        if (config->overlays.have_overlays == false || config->overlays.overlay[OL_EXCLUSION].enabled == false) return false;
+        if (config->overlays.have_overlays == false || config->overlays.overlay[OL_EXCLUSION].enabled == false)
+                return false;
 
         assert(config->overlays.exclusion->data != NULL);
 
-        const char value = config->overlays.exclusion->data[row][col];
+        const char value = load_input_2d_array_char(config->overlays.exclusion, row, col);
 
         switch (value) { // NOLINT(hicpp-multiway-paths-covered)
                 case OL_EXCLUSION_NOT_EXCLUDED:
@@ -63,5 +63,17 @@ cell_excluded_by_overlay(const struct cats_configuration *config, cats_dt_coord
         exit_cats(EXIT_FAILURE);
 }
 
+static inline double get_overlay_habitat_cc_value(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled);
+        return conf->overlays.habitat_cc->data[row][col]; // getter [get_overlay_habitat_cc_value]
+}
+
+static inline double get_overlay_resource_value(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(conf->overlays.overlay[OL_RESOURCE].enabled);
+        return conf->overlays.resources->data[row][col]; // getter [get_overlay_resource_value]
+}
+
 
 #endif //CATS_INLINE_OVERLAYS_H
diff --git a/src/cats/inline_population.h b/src/cats/inline_population.h
index 933b3d0146be4077f0729cef783dc7e0df7a604b..f537dad855770c1e3312e9b06cdfee01d33cae7d 100644
--- a/src/cats/inline_population.h
+++ b/src/cats/inline_population.h
@@ -34,17 +34,56 @@
 #include "inline_overlays.h"
 #include "populations/carrying_capacity.h"
 #include "populations/plant_juveniles.h"
+#include "grids/dimensions.h"
+#include "inline_vital_ages.h"
+
+
+static inline bool valid_population_grid(const struct cats_grid *grid, cats_dt_coord row)
+{
+        if (grid && grid->population && grid->population[row]) return true; // validator [valid_population_grid]
+        return false;
+}
+
+static inline bool valid_juvenile_grid(const struct cats_grid *grid, cats_dt_coord row)
+{
+        if (grid == NULL) return false;
+        if (grid->juveniles == NULL) return false;
+        if (grid->juveniles[row] == NULL) return false;       // validator [valid_juvenile_grid]
+        return true;
+}
+
+
+static inline bool juveniles_exist(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
+{
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(valid_juvenile_grid(grid, row));
+        return grid->juveniles[row][col] != NULL; // validator [juveniles_exist]
+}
+
+static inline cats_dt_population get_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year)
+{
+        if (juveniles_exist(grid, row, col) == false) return 0;
+        assert(year <  get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1);
+        // FIXME check year
+        return grid->juveniles[row][col][year]; // getter [get_juveniles]
+}
+
+static inline void set_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year, cats_dt_population juv)
+{
+        assert(juveniles_exist(grid, row, col));
+        assert(year <  get_vital_age(grid, VA_AGE_OF_MATURITY_MAX) + 1);
+        assert(juv >= 0);
+        grid->juveniles[row][col][year] = juv; // setter [set_juveniles]
+}
 
 
 static inline cats_dt_population
 get_adult_population(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
 {
-        assert(grid != NULL && grid->population != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
-        assert(grid->population[row] != NULL);
-        assert(grid->population[row][col] >= 0);
-        return grid->population[row][col]; // getter
+        assert(valid_population_grid(grid, row));
+        assert(valid_coordinates(&grid->dimension, row, col));
+        assert(grid->population[row][col] >= 0);        // getter [get_adult_population]
+        return grid->population[row][col];              // getter [get_adult_population]
 }
 
 
@@ -81,20 +120,12 @@ static inline cats_dt_population
 reduce_population_by(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, cats_dt_population to_reduce)
 {
         assert(to_reduce >= 0);
-        assert(grid != NULL);
-        assert(grid->population != NULL);
-        assert(row < grid->dimension.rows);
-        assert(col < grid->dimension.cols);
-        assert(row >= 0);
-        assert(col >= 0);
-        assert(grid->population[row] != NULL);
-
-        //cats_dt_population cc = get_carrying_capacity(grid, row, col);
+        assert(valid_population_grid(grid, row));
+        assert(valid_coordinates(&grid->dimension, row, col));
+
         cats_dt_population pop = get_adult_population(grid, row, col);
         if (to_reduce > pop) { to_reduce = pop; }
-
-
-        grid->population[row][col] = pop - to_reduce;// setter;
+        grid->population[row][col] = pop - to_reduce;  // setter [reduce_population_by]
         return to_reduce;
 
 }
@@ -104,9 +135,8 @@ static inline void
 set_population_ignore_cc(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col,
                          const cats_dt_population pop)
 {
-        assert(grid != NULL && grid->population != NULL);
-        assert(row >= 0 && row < grid->dimension.rows && col >= 0 && col < grid->dimension.cols);
-        assert(grid->population[row] != NULL);
+        assert(valid_population_grid(grid, row));
+        assert(valid_coordinates(&grid->dimension, row, col));
 
         if (pop > CATS_MAX_POPULATION || pop < 0.0) {
                 log_message(LOG_ERROR, "%s: population %d out of allowed population range [0, %d].",
@@ -114,7 +144,7 @@ set_population_ignore_cc(const struct cats_grid *grid, const cats_dt_coord row,
                 exit(EXIT_FAILURE);
         }
 
-        if (pop >= 0) grid->population[row][col] = pop; // setter ignore cc;
+        if (pop >= 0) grid->population[row][col] = pop; // setter [set_population_ignore_cc]
 }
 
 
@@ -169,19 +199,14 @@ static inline cats_dt_population
 get_population_ts(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col, const int threshold,
                   int64_t *unfiltered)
 {
-        assert(grid != NULL);
-        assert(grid->population != NULL);
-        assert(row < grid->dimension.rows);
-        assert(col < grid->dimension.cols);
-        assert(row >= 0);
-        assert(col >= 0);
-        assert(grid->population[row] != NULL);
+        assert(valid_population_grid(grid, row));
+        assert(valid_coordinates(&grid->dimension, row, col));
 
-        cats_dt_population tmp = grid->population[row][col]; // getter
+        cats_dt_population tmp = grid->population[row][col];    // getter [get_population_ts]
 
         if (unfiltered) *unfiltered = tmp;
 
-        if (grid->population[row][col] >= threshold) {
+        if (grid->population[row][col] >= threshold) {          // getter [get_population_ts]
                 return tmp;
         } else {
                 return 0;
diff --git a/src/cats/inline_vital_rates.h b/src/cats/inline_vital_rates.h
index 65b7194198802dea774ea8fa429ac19e70888a20..38de70314b495f0347900c03817c55cf843e6f78 100644
--- a/src/cats/inline_vital_rates.h
+++ b/src/cats/inline_vital_rates.h
@@ -29,6 +29,7 @@
 #include "data/cats_grid.h"
 #include "vital_rates/glm_functions.h"
 #include "vital_rates/direct_functions.h"
+#include "inline.h"
 
 
 static inline cats_dt_rates get_vital_rate_maximum(const struct cats_vital_rate *vr)
diff --git a/src/cats/misc/debug.c b/src/cats/misc/debug.c
index 7141dd8bb5dce5a2f3dce4f2fd4a0490a789d67f..487140b58696b6feb281fcfc7984a82e1deeef61 100644
--- a/src/cats/misc/debug.c
+++ b/src/cats/misc/debug.c
@@ -28,6 +28,12 @@
 #include <memory/cats_memory.h>
 
 
+static inline cats_dt_population debug_get_juveniles(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col, int year)
+{
+        if (grid->juveniles[row][col] == NULL) return 0; // debug [debug_get_juveniles]
+        return grid->juveniles[row][col][year]; // debug [debug_get_juveniles]
+}
+
 void
 debug_juveniles(const struct cats_grid *grid, const struct cats_configuration *conf, cats_dt_coord row,
                 cats_dt_coord col, const char *action)
@@ -38,11 +44,7 @@ debug_juveniles(const struct cats_grid *grid, const struct cats_configuration *c
                 const int32_t max_age_of_maturity = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
 
                 for (int32_t i = 0; i < max_age_of_maturity + 1; i++) {
-                        if (grid->juveniles[row][col]) {
-                                fprintf(cats_debug.misc_debug_file, ",%d", grid->juveniles[row][col][i]);
-                        } else {
-                                fprintf(cats_debug.misc_debug_file, ",%d", 0);
-                        }
+                        fprintf(cats_debug.misc_debug_file, ",%d", debug_get_juveniles(grid, row, col, i));
                 }
 
                 fprintf(cats_debug.misc_debug_file, "\n");
@@ -55,11 +57,11 @@ void debug_seeds(struct cats_grid *grid, const struct cats_configuration *conf,
 {
         if (row == cats_debug.misc_debug_coords.row && col == cats_debug.misc_debug_coords.col) {
                 fprintf(cats_debug.misc_debug_file, "%d,%d,%s,seeds,%f", grid->id, conf->time.year_current, action,
-                        grid->dispersed_seeds[row][col]);
+                        get_dispersed_seeds(grid, row, col));
                 const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE);
                 for (int32_t i = 0; i < seed_persistence; i++) {
-                        if (grid->seed_bank[row][col]) {
-                                fprintf(cats_debug.misc_debug_file, ",%f", grid->seed_bank[row][col][i]);
+                        if (seed_bank_exists(grid, row, col)) {
+                                fprintf(cats_debug.misc_debug_file, ",%f", get_seed_bank_seeds(grid, row, col, i));
                         } else {
                                 fprintf(cats_debug.misc_debug_file, ",%d", 0);
                         }
diff --git a/src/cats/mpi/mpi_save.c b/src/cats/mpi/mpi_save.c
index 3af93daf2c104e5026338d21f5bfb548d758b1c2..c667d1e47b8900063762cf57f571997cbc9f466e 100644
--- a/src/cats/mpi/mpi_save.c
+++ b/src/cats/mpi/mpi_save.c
@@ -35,6 +35,7 @@
 #include "memory/cats_memory.h"
 #include "mpi/mpi_grid_helpers.h"
 #include "paths/output_paths.h"
+#include "inline.h"
 
 
 /*
@@ -80,7 +81,7 @@ void *save_seeds0_to_gdal_mpi(struct cats_grid *grid, struct cats_configuration
 
         for (int r = 0; r < grid->dimension.rows; r++) {
                 for (int c = 0; c < grid->dimension.cols; c++) {
-                        seeds0[r * grid->dimension.cols + c] = grid->dispersed_seeds[r][c];
+                        seeds0[r * grid->dimension.cols + c] = get_dispersed_seeds(grid, r, c);
                 }
         }
 
diff --git a/src/cats/mpi/mpi_seeds.c b/src/cats/mpi/mpi_seeds.c
index 9b3f1531155c10a551b73c13c1a92aec08a8f6ae..89bb25d4ec3abb6cc3cdc1fd4f1f5d5a4253ee6c 100644
--- a/src/cats/mpi/mpi_seeds.c
+++ b/src/cats/mpi/mpi_seeds.c
@@ -29,6 +29,7 @@
 #include "mpi_grid_helpers.h"
 #include "memory/raw_arrays.h"
 #include "mpi_seeds.h"
+#include "inline.h"
 
 
 void send_and_receive_dispersed_seeds_mpi(struct cats_grid *grid, struct cats_configuration *conf)
@@ -143,7 +144,7 @@ void add_seeds0_from_below(const struct cats_configuration *conf, struct cats_gr
 
         for (int r = 0; r < radius; r++) {
                 for (int c = 0; c < cols; c++) {
-                        grid->dispersed_seeds[start_row + r][c] += from_below[r * cols + c];
+                        increase_dispersed_seeds(grid, start_row + r, c, (cats_dt_seeds) from_below[r * cols + c]);
                 }
         }
 }
@@ -159,7 +160,7 @@ void add_seeds0_from_above(const struct cats_configuration *conf, struct cats_gr
 
         for (int r = 0; r < radius; r++) {
                 for (int c = 0; c < cols; c++) {
-                        grid->dispersed_seeds[r][c] += from_above[r * cols + c];
+                        increase_dispersed_seeds(grid, r, c, (cats_dt_seeds) from_above[r * cols + c]);
                 }
         }
 }
\ No newline at end of file
diff --git a/src/cats/overlays/overlay_exclusion.c b/src/cats/overlays/overlay_exclusion.c
index f68b8691b9e9215d4b0b9552f13962cffe458b2b..d54fafce3f3869a7f082efaf4822ecda36616377 100644
--- a/src/cats/overlays/overlay_exclusion.c
+++ b/src/cats/overlays/overlay_exclusion.c
@@ -110,17 +110,19 @@ struct cats_2d_array_char *translate_exclusion(const struct cats_2d_array_double
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
 
-                        const int32_t val = (int32_t) round(data->data[row][col]);
+                        const int32_t in_val = (int32_t) round(data->data[row][col]); // converter [translate_exclusion]
+                        char out_val;
 
-                        if (val == 0) {
-                                result->data[row][col] = OL_EXCLUSION_NOT_EXCLUDED;
+                        if (in_val == 0) {
+                                out_val = OL_EXCLUSION_NOT_EXCLUDED;
                         } else if (isnan(data->data[row][col])) {
-                                result->data[row][col] = OL_EXCLUSION_NAN;
+                                out_val = OL_EXCLUSION_NAN;
                                 count += 1;
                         } else {
-                                result->data[row][col] = OL_EXCLUSION_EXCLUDED;
+                                out_val = OL_EXCLUSION_EXCLUDED;
                                 count += 1;
                         }
+                        result->data[row][col]  = out_val; // converter [translate_exclusion]
                 }
         }
 
diff --git a/src/cats/overlays/overlay_habitat_type_cc.c b/src/cats/overlays/overlay_habitat_type_cc.c
index e98c258f98d2059292ecac0f7667e78c9d4697c2..d922c15bffc385f0262dcf03c88b1819023e1f76 100644
--- a/src/cats/overlays/overlay_habitat_type_cc.c
+++ b/src/cats/overlays/overlay_habitat_type_cc.c
@@ -30,6 +30,7 @@
 #include "cats_csv/cats_csv.h"
 #include "logging.h"
 #include "memory/cats_memory.h"
+#include "grids/direct_access.h"
 
 
 void cleanup_habitat_layer_cc_aux(void **data)
@@ -128,14 +129,31 @@ struct cats_2d_array_double *translate_habitat(const struct cats_2d_array_double
                         double value = data->data[row][col];
 
                         if (isnan(value)) {
-                                result->data[row][col] = 0.0;
+                                result->data[row][col] = 0.0;  // converter [translate_habitat]
                         } else {
                                 int32_t val = (int32_t) round(value);
                                 double multi = get_habitat_cc_multiplier(habitat_info, val);
-                                result->data[row][col] = multi;
+                                result->data[row][col] = multi;   // converter [translate_habitat]
                         }
                 }
         }
 
         return result;
 }
+
+
+double get_overlay_cc_multiplier(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
+{
+
+        if (!conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
+                return 1.0;
+        }
+
+        double multiplier = load_input_2d_array_double(conf->overlays.habitat_cc, row, col);
+
+        if (multiplier <= 0.0) {
+                return 0.0;
+        }
+
+        return multiplier;
+}
\ No newline at end of file
diff --git a/src/cats/overlays/overlay_habitat_type_cc.h b/src/cats/overlays/overlay_habitat_type_cc.h
index c355afb307db70983df92cf9dcddae94467986d7..89b2997ed9e4fff2e56c14fa9ab1472814ac8220 100644
--- a/src/cats/overlays/overlay_habitat_type_cc.h
+++ b/src/cats/overlays/overlay_habitat_type_cc.h
@@ -26,6 +26,7 @@
 
 #include <stdint.h>
 #include "../../memory/arrays.h"
+#include "configuration/configuration.h"
 
 #define MAX_HABITAT_TYPE_CODES 1024
 
@@ -43,4 +44,6 @@ struct cats_2d_array_double *translate_habitat(const struct cats_2d_array_double
 
 struct habitat_layer_cc_aux *load_habitat_layer_cc_aux(const char *csv_file, double default_value);
 
+double get_overlay_cc_multiplier(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col);
+
 #endif //CATS_OVERLAY_HABITAT_TYPE_CC_H
diff --git a/src/cats/overlays/overlay_resources.c b/src/cats/overlays/overlay_resources.c
index 64a171f856e369a527a9a5d3a804722574f8f4d9..63798ac18e2d2c03a0d4886178f06c05d7026f45 100644
--- a/src/cats/overlays/overlay_resources.c
+++ b/src/cats/overlays/overlay_resources.c
@@ -1,4 +1,3 @@
-#include <assert.h>
 #include <math.h>
 #include "overlay_resources.h"
 #include "memory/arrays.h"
@@ -14,15 +13,15 @@ struct cats_2d_array_double *translate_resources(const struct cats_2d_array_doub
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
 
-                        double value = data->data[row][col];
+                        double in_value = data->data[row][col];  // converter [translate_resources]
+                        double out_value;
 
-                        if (isnan(value)) {
-                                result->data[row][col] = 0.0;
+                        if (isnan(in_value)) {
+                                out_value = 0.0;
                         } else {
-
-                                if (value <0 ) value = 0;
-                                result->data[row][col] = value;
-                        }
+                                if (in_value < 0 ) in_value = 0;
+                                out_value = in_value;
+                        }                        result->data[row][col] = out_value;  // converter [translate_resources]
                 }
         }
 
diff --git a/src/cats/plants/inter_period.c b/src/cats/plants/inter_period.c
index 2c6ae48e2ed7137932db41b984ac1e986272d448..c8d4eeb68857495ce3e1593b777dd559e075f797 100644
--- a/src/cats/plants/inter_period.c
+++ b/src/cats/plants/inter_period.c
@@ -35,53 +35,63 @@ void inter_period_survival_seeds(struct cats_grid *grid, struct cats_configurati
                                  cats_dt_coord col, struct cats_thread_info *ts)
 {
         // if we have no seeds, we are done
-        if (grid->dispersed_seeds[row][col] == 0.0 && grid->seed_bank[row][col] == NULL) return;
+        cats_dt_seeds disp_seeds = get_dispersed_seeds(grid, row, col);
+        if (disp_seeds == 0.0 && seed_bank_exists(grid, row, col) == false) return;
 
         cats_dt_rates seed_survival_rate;
 
+        bool have_seed_bank = seed_bank_exists(grid, row, col);
 
         const struct cats_vital_rate *rate_link_surv = get_default_vital_rate(grid, VR_SEED_SURVIVAL);
         seed_survival_rate = calculate_rate(rate_link_surv, NAN, &grid->param, grid, row, col, NULL);
 
-        if (grid->dispersed_seeds[row][col] > 0) {
-                cats_dt_seeds dying_0 = poisson_seeds_capped(ts->rng, grid->dispersed_seeds[row][col] *
+        if (disp_seeds > 0) {
+                cats_dt_seeds dying_0 = poisson_seeds_capped(ts->rng, disp_seeds *
                                                                       (1.0 - seed_survival_rate),
-                                                             grid->dispersed_seeds[row][col]);
+                                                             disp_seeds);
 
-                grid->dispersed_seeds[row][col] = grid->dispersed_seeds[row][col] - dying_0;
+                disp_seeds = disp_seeds - dying_0;
+                set_dispersed_seeds(grid, row, col, disp_seeds);
 
-                if (grid->dispersed_seeds[row][col] > 0.0 && grid->seed_bank[row][col] == NULL) {
+
+                if (disp_seeds > 0.0 && have_seed_bank == false) {
                         create_seed_structure(grid, row, col);
                 }
         }
 
-        if (grid->dispersed_seeds[row][col] == 0.0 && grid->seed_bank[row][col] == NULL) return;
+
+        if (disp_seeds == 0.0 && have_seed_bank == false) return;
+
+        if (have_seed_bank == false) create_seed_structure(grid, row, col);
 
         const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE);
-        for (int32_t stage = 0; stage < seed_persistence - 0; stage++) { // -1
+        for (int32_t stage = 0; stage < seed_persistence; stage++) {
+                cats_dt_seeds seeds_i = get_seed_bank_seeds(grid, row, col, stage);
                 cats_dt_seeds dying = poisson_seeds_capped(ts->rng,
-                                                           grid->seed_bank[row][col][stage] *
+                                                           seeds_i *
                                                            (1.0 - seed_survival_rate),
-                                                           grid->seed_bank[row][col][stage]);
-                grid->seed_bank[row][col][stage] = grid->seed_bank[row][col][stage] - dying;
+                                                           seeds_i);
 
+                set_seed_bank_seeds(grid, row, col, stage, seeds_i - dying);
         }
 
-        for (int32_t k = seed_persistence - 1; k >= 1; k--) { // -2
-                grid->seed_bank[row][col][k] = grid->seed_bank[row][col][k - 1];
+        for (int32_t k = seed_persistence - 1; k >= 1; k--) {
+                cats_dt_seeds s = get_seed_bank_seeds(grid, row, col, k - 1);
+                set_seed_bank_seeds(grid, row, col, k, s);
         }
 
-        grid->seed_bank[row][col][0] = grid->dispersed_seeds[row][col];
-        assert(grid->seed_bank[row][col][0] >= 0.0);
-        grid->dispersed_seeds[row][col] = 0.0f;
+        set_seed_bank_seeds(grid, row, col, 0, get_dispersed_seeds(grid, row, col));
 
+        assert(get_seed_bank_seeds(grid, row, col, 0) >= 0);
+        set_dispersed_seeds(grid, row, col, 0.0f);
 }
 
 
 void inter_period_survival_juveniles(struct cats_grid *grid, struct cats_configuration *conf, cats_dt_coord row,
                                      cats_dt_coord col, struct cats_thread_info *ts)
 {
-        if (grid->juveniles[row][col] == NULL) return;
+        if (juveniles_exist(grid, row, col) == false) return;
+
         const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
         const int32_t mat_min = get_vital_age(grid, VA_AGE_OF_MATURITY_MIN);
 
@@ -94,30 +104,34 @@ void inter_period_survival_juveniles(struct cats_grid *grid, struct cats_configu
                 germination_to_adult_survival, &grid->param);
 
         for (int32_t i = 0; i <= mat_max; i++) {
+
                 cats_dt_rates modified_juvenile_transition_rate = age_modified_juvenile_survival_rate(
                         juvenile_transition_rate, i, mat_min, mat_max);
+
                 cats_dt_rates juvenile_mortality = (1.0 - modified_juvenile_transition_rate);
 
                 assert(juvenile_mortality >= 0 && juvenile_mortality <= 1.0);
-                assert(grid->juveniles[row][col][i] >= 0);
+                cats_dt_population juveniles_i = get_juveniles(grid, row, col, i);
+                assert(juveniles_i >= 0);
+
 
                 cats_dt_population dying = poisson_population_capped(ts->rng,
-                                                                     (cats_dt_rates) grid->juveniles[row][col][i] *
+                                                                     (cats_dt_rates) juveniles_i *
                                                                      juvenile_mortality,
-                                                                     grid->juveniles[row][col][i]);
+                                                                     juveniles_i);
+                set_juveniles(grid, row, col, i, juveniles_i - dying);
 
-                grid->juveniles[row][col][i] = grid->juveniles[row][col][i] - dying;
-                assert(grid->juveniles[row][col][i] >= 0);
+                assert(get_juveniles(grid, row, col, i) >= 0);
 
         }
         // advance juvenile stage (after transition rates have been applied)
         for (int32_t stage = mat_max; stage > 0; stage--) {
-                grid->juveniles[row][col][stage] = grid->juveniles[row][col][stage - 1];
+                cats_dt_population juveniles_younger = get_juveniles(grid, row, col, stage - 1);
+                set_juveniles(grid, row, col, stage, juveniles_younger);
         }
 
         // youngest stage now empty
-        grid->juveniles[row][col][0] = 0;
-
+        set_juveniles(grid, row, col, 0, 0);
 }
 
 
diff --git a/src/cats/plants/juveniles.c b/src/cats/plants/juveniles.c
index 010876337f050000f6bd887f89553e0c4cf72d7c..a83e1e6e88cf8b2e243cd0e5fe6014f8ef6bd162 100644
--- a/src/cats/plants/juveniles.c
+++ b/src/cats/plants/juveniles.c
@@ -54,21 +54,23 @@ juvenile_adult_transition(struct cats_grid *g, cats_dt_coord row, cats_dt_coord
         // once the cell is full, we stop and juveniles have to wait at least until
         // the next year to have a chance to mature
 
+        // FIXME check max age!
         for (int32_t age = mat_max; age >= mat_min; age--) {
-                cats_dt_population juveniles = g->juveniles[row][col][age];
+                cats_dt_population juveniles = get_juveniles(g, row, col, age);
 
                 if (juveniles == 0) continue;
                 // the cell_maturation rate depends on the age -- the older the juvenile, the higher the probability to mature
                 cats_dt_rates maturation_rate = age_specific_maturation_rate(age, juvenile_survival_rate, mat_min,
                                                                              mat_max);
+
                 cats_dt_population newly_matured = poisson_population_capped(ts->rng, (cats_dt_rates) juveniles *
                                                                                       maturation_rate,
                                                                              juveniles);
 
                 newly_matured = min_population_t(newly_matured, space_left);
+                set_juveniles(g, row, col, age, juveniles - newly_matured);
 
-                g->juveniles[row][col][age] = juveniles - newly_matured;
-                assert(g->juveniles[row][col][age] >= 0);
+                assert(get_juveniles(g, row, col, age) >= 0);
                 newly_matured_sum += newly_matured;
                 space_left -= newly_matured;
 
@@ -100,8 +102,7 @@ cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cats_dt_coo
 #else
         if (__builtin_expect(cell_excluded_by_overlay(conf, row, col), false)) { return 0; }
 #endif
-
-        if (grid->juveniles[row][col] == NULL) return 0;
+        if (juveniles_exist(grid, row, col) == false) return 0;
 
         const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
         const int32_t mat_min = get_vital_age(grid, VA_AGE_OF_MATURITY_MIN);
diff --git a/src/cats/plants/long_range_dispersal.c b/src/cats/plants/long_range_dispersal.c
index 61684296e691e5cb1bc273a2d496162d201c26de..eb6d86d0e93fc0db87c9400dcd74a3f5ba911b0d 100644
--- a/src/cats/plants/long_range_dispersal.c
+++ b/src/cats/plants/long_range_dispersal.c
@@ -87,7 +87,7 @@ void disperse_long_range(struct cats_grid *grid)
                                 }
 
                                 // disperse seeds and reduce number of local seeds
-                                grid->dispersed_seeds[trow][tcol] += (cats_dt_seeds) package;
+                                increase_dispersed_seeds(grid, trow, tcol, (cats_dt_seeds) package);
                                 grid->seeds_produced[row][col] -= (cats_dt_seeds) package;
 
                                 // stop if no more seeds are left to distribute
diff --git a/src/cats/plants/plant_rates.c b/src/cats/plants/plant_rates.c
index 4c4275395650d1410f9fdba9c37eed3708af74d5..16c881ea4f5d59aa207db297e161bf0669f0b600 100644
--- a/src/cats/plants/plant_rates.c
+++ b/src/cats/plants/plant_rates.c
@@ -29,6 +29,7 @@
 #include "data/cats_grid.h"
 #include "inline_population.h"
 #include "populations/population.h"
+#include "misc/cats_maths_inline.h"
 
 
 cats_dt_rates get_pollination_probability(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col,
diff --git a/src/cats/plants/plant_structures.c b/src/cats/plants/plant_structures.c
index d75d8f482c6ce09d617fcd346c464115bb2f1865..3218cdfcc5cdfe722403939b43b30984601f4316 100644
--- a/src/cats/plants/plant_structures.c
+++ b/src/cats/plants/plant_structures.c
@@ -29,6 +29,7 @@
 #include "seeds.h"
 #include "inline_population.h"
 #include "populations/population.h"
+#include "inline_vital_ages.h"
 #include <memory/cats_memory.h>
 
 
@@ -39,50 +40,42 @@ void destroy_plant_cell(struct cats_grid *grid, const cats_dt_coord row, const c
         assert(col >= 0 && col < grid->dimension.cols);
         destroy_juveniles(grid, row, col);
         destroy_seed_structure(grid, row, col);
-        grid->dispersed_seeds[row][col] = 0.0f;
-        grid->seeds_produced[row][col] = 0.0f;
+        set_dispersed_seeds(grid, row, col, 0.0f);
+        set_produced_seeds(grid, row, col, 0.0f);
         set_population_ignore_cc(grid, row, col, 0);
 }
 
 
 void create_seed_structure(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
 {
-        assert(grid != NULL);
-        if (grid->seed_bank[row][col] != NULL) return;
+
+        assert(valid_seed_bank_grid(grid, row));
+        if (seed_bank_exists(grid, row, col) == true) return;
         const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE);
-        const int32_t size = seed_persistence - 0; //  - 1);
+        const int32_t size = seed_persistence;
         if (size <= 0) return; // no seed persistence
 
-        assert(grid->seed_bank != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
-        assert(grid->seed_bank[row][col] == NULL);
-
-        grid->seed_bank[row][col] = calloc_or_die(size, sizeof(cats_dt_seeds));
-
-
+        grid->seed_bank[row][col] = calloc_or_die(size, sizeof(cats_dt_seeds)); // initialisation [create_seed_structure]
 }
 
 
 void destroy_seed_structure(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
 {
         assert(grid != NULL);
-        assert(grid->seed_bank != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
+
         const int32_t seed_persistence = get_vital_age(grid, VA_SEED_PERSISTENCE);
 
-        const int size = (seed_persistence - 0); // -1
+        const int size = (seed_persistence - 0);
 
         // do we actually have seeds in the ground?
-        if (size <= 0 || grid->seed_bank[row][col] == NULL) return;
+        if (size <= 0 || seed_bank_exists(grid, row, col) == false) return;
 
-        for (uint32_t i = 0; i < size; i++) {
-                grid->seed_bank[row][col][i] = 0.0f;
+        for (int32_t i = 0; i < size; i++) {
+                set_seed_bank_seeds(grid, row, col, i, 0.0f); // clean-up [destroy_seed_structure]
         }
 
-        free(grid->seed_bank[row][col]);
-        grid->seed_bank[row][col] = NULL;
+        free(grid->seed_bank[row][col]);  // clean-up [destroy_seed_structure]
+        grid->seed_bank[row][col] = NULL; // clean-up [destroy_seed_structure]
 }
 
 
@@ -92,19 +85,18 @@ inline
 void
 create_juvenile_structure_if_needed(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
 {
-        if (grid->juveniles[row][col]) return;
+        if (juveniles_exist(grid, row, col)) return;
         const int32_t max_age_of_maturity = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
-
-        grid->juveniles[row][col] = create_juvenile_structure(max_age_of_maturity);
+        grid->juveniles[row][col] = create_juvenile_structure(max_age_of_maturity); // initialisation [create_juvenile_structure_if_needed]
 
 }
 
 
 void destroy_juveniles(const struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col)
 {
-        assert(grid != NULL);
-        assert(row >= 0 && row < grid->dimension.rows);
-        assert(col >= 0 && col < grid->dimension.cols);
+        assert(grid != NULL); // clean-up [destroy_juveniles]
+        assert(row >= 0 && row < grid->dimension.rows); // clean-up [destroy_juveniles]
+        assert(col >= 0 && col < grid->dimension.cols); // clean-up [destroy_juveniles]
         assert(grid->juveniles != NULL);
 
 
@@ -113,10 +105,10 @@ void destroy_juveniles(const struct cats_grid *grid, const cats_dt_coord row, co
         const int32_t stages = max_age_of_maturity + 1;
         assert(stages >= 0);
 
-        if (grid->juveniles[row] && grid->juveniles[row][col]) {
-                memset(grid->juveniles[row][col], 0, stages * sizeof(cats_dt_population));
-                free(grid->juveniles[row][col]);
-                grid->juveniles[row][col] = NULL;
+        if (grid->juveniles[row] && grid->juveniles[row][col]) { // clean-up [destroy_juveniles]
+                memset(grid->juveniles[row][col], 0, stages * sizeof(cats_dt_population)); // clean-up [destroy_juveniles]
+                free(grid->juveniles[row][col]);  // clean-up [destroy_juveniles]
+                grid->juveniles[row][col] = NULL; // clean-up [destroy_juveniles]
         }
 }
 
diff --git a/src/cats/plants/seeds.c b/src/cats/plants/seeds.c
index 797e98fc5733883ff0b8a98f14a3b288d012d36f..0cd63b9ecbb845deea358249cdf1d8487261294d 100644
--- a/src/cats/plants/seeds.c
+++ b/src/cats/plants/seeds.c
@@ -33,6 +33,8 @@
 #include "inline_overlays.h"
 #include "inline_population.h"
 #include "populations/population.h"
+#include "misc/cats_maths_inline.h"
+#include "inline_vital_ages.h"
 
 #ifdef USEMPI
 #include "mpi/mpi_cats.h"
@@ -85,9 +87,8 @@ void cell_seed_production(struct cats_grid *grid, cats_dt_coord row, cats_dt_coo
 
         assert(grid->seeds_produced != NULL);
         // ensure that no seeds are left-over in the cell
-        assert(grid->seeds_produced[row][col] == 0.0);
-
-        grid->seeds_produced[row][col] = 0.0f;
+        assert(get_produced_seeds(grid, row, col) == 0.0f);
+        set_produced_seeds(grid, row, col, 0.0f);
 
         // no population -> no seeds
         cats_dt_rates N = get_adult_population(grid, row, col);
@@ -122,10 +123,11 @@ void cell_seed_production(struct cats_grid *grid, cats_dt_coord row, cats_dt_coo
 
         const cats_dt_rates total_seeds = N * flowering_frequency * seed_yield * pollination_rate;
         assert(total_seeds >= 0.0);
+        cats_dt_seeds seeds = poisson_seeds(ts->rng, total_seeds); // we don't cap
+        set_produced_seeds(grid, row, col, seeds);
 
-        grid->seeds_produced[row][col] = poisson_seeds(ts->rng, total_seeds); // we don't cap
 
-        if (grid->seeds_produced[row][col] > 0) ts->stats[grid->id].stats[CS_SEEDS_PRODUCED] += 1;
+        if (seeds > 0) ts->stats[grid->id].stats[CS_SEEDS_PRODUCED] += 1;
 
         cats_dt_rates hapaxanth = grid->param.hapaxanthy;
 
@@ -165,17 +167,19 @@ germinate_seeds_in_ground(struct cats_thread_info *ts, struct cats_grid *grid, c
 
         for (int32_t k = 0; k < max_k; k++) {
 
-                cats_dt_population germinated = poisson(ts->rng, grid->seed_bank[row][col][k] * germination_rate);
+                cats_dt_seeds seeds_k = get_seed_bank_seeds(grid, row, col, k);
+                cats_dt_population germinated = poisson(ts->rng, seeds_k * germination_rate);
 
                 if (germinated <= 0) continue;
 
                 add_germinated(ts, grid, row, col, germinated, K_class);
-                grid->seed_bank[row][col][k] = max_float(grid->seed_bank[row][col][k] - (float) germinated, 0.0f);
-
+                seeds_k = max_float(seeds_k - (float) germinated, 0.0f);
+                set_seed_bank_seeds(grid, row, col, k, seeds_k);
         }
 }
 
-
+/*
+// no longer used
 static inline void
 germinate_seeds0(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_coord col, struct cats_thread_info *ts,
                  const cats_dt_rates germination_rate)
@@ -195,16 +199,16 @@ germinate_seeds0(struct cats_grid *grid, const cats_dt_coord row, const cats_dt_
         grid->dispersed_seeds[row][col] = max_float(grid->dispersed_seeds[row][col] - (float) germinated,
                                                     0.0f); // fixme max_seeds
 }
-
+*/
 
 inline static bool
 have_seeds_in_cell(const struct cats_grid *grid, const struct cats_configuration *conf, cats_dt_coord row,
                    cats_dt_coord col, const struct cats_thread_info *ts)
 {
 
-        assert(grid->dispersed_seeds != NULL);
-        assert(grid->dispersed_seeds[row][col] >= 0);
-        return (grid->seed_bank[row][col] != NULL || grid->dispersed_seeds[row][col] > 0.5);
+        cats_dt_seeds d_seeds = get_dispersed_seeds(grid, row, col);
+        assert(d_seeds >= 0);
+        return (seed_bank_exists(grid, row, col) || d_seeds > 0.5);
 }
 
 
@@ -240,21 +244,22 @@ cell_post_process_seeds(struct cats_grid *grid, struct cats_configuration *conf,
                         struct cats_thread_info *ts)
 {
         assert(grid != NULL);
-        assert(grid->dispersed_seeds != NULL);
-        assert(grid->dispersed_seeds[row][col] >= 0);
+        assert(valid_dispersed_seeds_grid(grid, row));
+
+        cats_dt_seeds disp_seeds = get_dispersed_seeds(grid, row, col);
+        assert(disp_seeds >= 0);
+        if (disp_seeds == 0.0f) return;
 
         if (cell_excluded_by_overlay(conf, row, col)) {
-                grid->dispersed_seeds[row][col] = 0;
+                set_dispersed_seeds(grid, row, col, 0.0f);
                 return;
         }
 
-        if (grid->dispersed_seeds[row][col] == 0.0) return;
-
         const int32_t id = grid->id;
         ts->stats[id].stats[CS_SEEDS_BEFORE_POISSON] += 1;
 
         cats_dt_seeds seeds_after_poisson = poisson_seeds(ts->rng,
-                                                          grid->dispersed_seeds[row][col]); /* IMPORTANT stochasticity required */
-        grid->dispersed_seeds[row][col] = seeds_after_poisson;
+                                                          disp_seeds); /* IMPORTANT stochasticity required */
+        set_dispersed_seeds(grid, row, col, seeds_after_poisson);
         if (seeds_after_poisson > 0) ts->stats[id].stats[CS_SEEDS_AFTER_POISSON] += 1;
 }
diff --git a/src/cats/populations/carrying_capacity.c b/src/cats/populations/carrying_capacity.c
index a285ee516d61783de0b9c63054980ef7692b0f29..6d9ef8c8d30d7f7e4c5c38a82ea272a65ddf5dc4 100644
--- a/src/cats/populations/carrying_capacity.c
+++ b/src/cats/populations/carrying_capacity.c
@@ -28,6 +28,7 @@
 #include "plants/juveniles.h"
 #include "inline_overlays.h"
 #include "inline_population.h"
+#include "overlays/overlay_habitat_type_cc.h"
 
 
 void
@@ -50,22 +51,18 @@ get_carrying_capacity_all_classes(struct cats_grid **grids, cats_dt_coord row, c
 cats_dt_population
 get_carrying_capacity(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
 {
-        assert(grid->conf != NULL);
+        assert(grid != NULL && grid->conf != NULL);
 
         const struct cats_configuration *conf = grid->conf;
 
         // if we have an exclusion mask AND it is set the CC is 0
         if (cell_excluded_by_overlay(conf, row, col)) { return 0; }
 
-        double multiplier = 1.0;
+        double multiplier = get_overlay_cc_multiplier(conf, row, col);
+        if (multiplier <= 0.0) { return 0; }
 
-        if (conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
-                multiplier *= conf->overlays.habitat_cc->data[row][col];
-                if (multiplier <= 0.0) { return 0; }
-        }
 
         cats_dt_rates cc;
-
         const struct cats_vital_rate *link = &grid->param.carrying_capacity;
         cc = calculate_rate(link, NAN, &grid->param, grid, row, col, NULL);
 
@@ -91,7 +88,7 @@ cell_apply_carrying_capacity(struct cats_grid *grid, struct cats_thread_info *ts
         if (grid->param.default_demographics) {
                 cats_dt_population N = get_adult_population(grid, row, col);
 
-                if (N == 0 && grid->juveniles[row][col] == NULL) return;
+                if (N == 0 && juveniles_exist(grid, row, col) == false) return;
                 if (N > 0) ts->stats[grid_id].stats[CS_POPULATED_BEFORE_CC] += 1;
 
                 cats_dt_population K_A = get_adult_carrying_capacity_from_cc(grid, K_tot);
diff --git a/src/cats/populations/plant_juveniles.c b/src/cats/populations/plant_juveniles.c
index fd9e70975c8f4174b70fd27627fd40bc6c803922..1f41a8532394afe0aa5b3b2d9793a5c2f73ac687 100644
--- a/src/cats/populations/plant_juveniles.c
+++ b/src/cats/populations/plant_juveniles.c
@@ -29,6 +29,8 @@
 #include "data/cats_grid.h"
 #include "inline_vital_rates.h"
 #include "memory/cats_memory.h"
+#include "inline_vital_ages.h"
+#include "inline_carrying_capacity.h"
 
 
 void setup_plant_juvenile_weights(struct cats_species_param *param)
@@ -85,12 +87,12 @@ scale_down_juveniles2(struct cats_grid *grid, cats_dt_coord row, cats_dt_coord c
         assert(grid != NULL && grid->juveniles != NULL);
         assert(row >= 0 && row < grid->dimension.rows);
         assert(col >= 0 && col < grid->dimension.cols);
-        assert(grid->juveniles[row] != NULL);
+        assert(juveniles_exist(grid, row, col));
         assert(juvenile_cc > 0);
-        if (grid->juveniles[row][col] == NULL || weighted_juvenile_sum == 0) return;
+        if (juveniles_exist(grid, row, col) == false || weighted_juvenile_sum == 0) return;
         if (weighted_juvenile_sum < juvenile_cc) return;
 
-        const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX); // grid->param.max_age_of_maturity;
+        const int32_t mat_max = get_vital_age(grid, VA_AGE_OF_MATURITY_MAX);
 
         cats_dt_rates factor = 1.0;
         for (int32_t i = 0; i < mat_max + 1; i++) {
@@ -119,8 +121,8 @@ scale_down_juveniles2(struct cats_grid *grid, cats_dt_coord row, cats_dt_coord c
                 log_message(LOG_ERROR, "%s: weighted juvenile sum > juvenile CC", __func__);
                 log_message(LOG_RAW, "sum: %"PRId64", cc %"PRId64"\n", weighted_juvenile_sum, juvenile_cc);
                 log_message(LOG_RAW, "factor %f\n", (double) factor);
-                for (int32_t i = 0; i < mat_max + 1 - 1; i++) {
-                        log_message(LOG_RAW, "juvenile stage %d: %d - multiplier %f\n",  i,
+                for (int32_t i = 0; i < mat_max + 1; i++) {
+                        log_message(LOG_RAW, "juvenile stage %d: %d - multiplier %f\n", i,
                                     grid->juveniles[row][col][i],
                                     (double) juvenile_cc_multiplier(&grid->param, i));
                 }
@@ -135,7 +137,7 @@ void cell_apply_juvenile_cc(struct cats_grid *g, cats_dt_coord row,
                             cats_dt_coord col, cats_dt_population K_tot, cats_dt_population N)
 {
         if (g->juveniles == NULL) return;
-        if (g->juveniles[row][col] == NULL) return;
+        if (juveniles_exist(g, row, col) == false) return;
 
         cats_dt_population K_J = K_tot - N;
 
diff --git a/src/cats/populations/population.c b/src/cats/populations/population.c
index e5143ea6200926e355d00f7725c0ad969b6d75b9..c6509c1443e9b9ae74f228e48b4f8ae68d8843db 100644
--- a/src/cats/populations/population.c
+++ b/src/cats/populations/population.c
@@ -56,14 +56,15 @@ void adjust_juvenile_populations(struct cats_configuration *conf, struct cats_gr
                                 //cats_dt_rates w = juvenile_cc_multiplier(&grid->param, i);
                                 cats_dt_rates w = grid->param.juvenile_cc_weights[i];
                                 cats_dt_rates juv_pop = (cats_dt_rates) N * multi / w;
+
                                 if (juv_pop > CATS_MAX_POPULATION) {
                                         juv_pop = CATS_MAX_POPULATION / 2.0;
                                 }
-                                grid->juveniles[r][c][i] = round_population_safe(juv_pop);
+
+                                set_juveniles(grid, r, c, i, round_population_safe(juv_pop));
                         }
                 }
         }
-
 }
 
 
@@ -153,7 +154,8 @@ void prune_initial_population_under_threshold(struct cats_configuration *conf, s
                 }
         }
 
-        log_message(LOG_INFO, "Species '%s': pruned %"PRId64" of %"PRId64" initial populations (suitability < threshold), %"PRId64" remaining",
+        log_message(LOG_INFO,
+                    "Species '%s': pruned %"PRId64" of %"PRId64" initial populations (suitability < threshold), %"PRId64" remaining",
                     grid->param.species_name, destroyed, populated, populated - destroyed);
 }
 
diff --git a/src/cats/vital_rates/direct_functions.c b/src/cats/vital_rates/direct_functions.c
index a42104895c550d4012c0474668673a3686756d6f..1599ad06032ffd8999fc3961cf20062d57de502e 100644
--- a/src/cats/vital_rates/direct_functions.c
+++ b/src/cats/vital_rates/direct_functions.c
@@ -45,7 +45,8 @@ cats_dt_rates get_direct_rate(const struct cats_vital_rate *rate_info,
                 log_message(LOG_ERROR, "%s: wrong environment set type for set '%s'", __func__, set->name);
                 exit(EXIT_FAILURE);
         }
-        cats_dt_rates rate = set->environments[0]->current.values[row][col] * rate_info->environment_multiplier;
+        cats_dt_environment value = load_input_environment_raster(&set->environments[0]->current, row, col);
+        cats_dt_rates rate = value * rate_info->environment_multiplier;
         if (isnan(rate)) return 0.0f;
 
         cats_dt_rates dens_multiplier = density_multiplier(density_type, N, K, rate_info->density_ts);
diff --git a/src/cats/vital_rates/glm_functions.c b/src/cats/vital_rates/glm_functions.c
index 60a9c3eb41b65f7260eb928c1ed5748c584337a7..0be349a10ada9234c3265b03c01e19d4af8bd782 100644
--- a/src/cats/vital_rates/glm_functions.c
+++ b/src/cats/vital_rates/glm_functions.c
@@ -45,13 +45,13 @@ cats_dt_rates get_glm(const struct cats_vital_rate *rate_info,
 
         if (set->glm.type == GLM_QUADRATIC) {
                 for (int32_t i = 0; i < set->count; i++) {
-                        const cats_dt_rates predictor = set->environments[i]->current.values[row][col];
+                        const cats_dt_rates predictor = load_input_environment_raster(&set->environments[i]->current, row, col);
                         result += predictor * set->glm.linear[i] + predictor * predictor * set->glm.quadratic[i];
                 }
 
         } else if (set->glm.type == GLM_LINEAR) {
                 for (int32_t i = 0; i < set->count; i++) {
-                        const cats_dt_rates predictor = set->environments[i]->current.values[row][col];
+                        const cats_dt_rates predictor = load_input_environment_raster(&set->environments[i]->current, row, col);
                         result += predictor * set->glm.linear[i];
                 }
         } else {
diff --git a/src/cats_csv/cats_csv.c b/src/cats_csv/cats_csv.c
index 676cf3275f533ff6b74c9773cd751f49d1613eef..57b45d97b5cda9d96e3d36fca009a240739dfb12 100644
--- a/src/cats_csv/cats_csv.c
+++ b/src/cats_csv/cats_csv.c
@@ -89,8 +89,8 @@ void csv_free(struct cats_csv **csv)
                         if (this->data[row] == NULL) continue;
 
                         for (int32_t col = 0; col < this->column_count; col++) {
-                                free(this->data[row][col]);
-                                this->data[row][col] = NULL;
+                                free(this->data[row][col]);     // clean-up, non-spatial [csv_free]
+                                this->data[row][col] = NULL;    // clean-up, non-spatial [csv_free]
                         }
 
                         free(this->data[row]);
@@ -142,7 +142,7 @@ char *csv_get_value_field_name(struct cats_csv *csv, int32_t row, const char *fi
                 exit(EXIT_FAILURE);
         }
 
-        return csv->data[row][field_idx];
+        return csv->data[row][field_idx];  // getter, non-spatial [csv_get_value_field_name]
 }
 
 
@@ -164,7 +164,7 @@ char *csv_get_value_field_idx(struct cats_csv *csv, int32_t row, int32_t field_i
                 exit(EXIT_FAILURE);
         }
 
-        return csv->data[row][field_idx];
+        return csv->data[row][field_idx]; // getter, non-spatial [csv_get_value_field_idx]
 }
 
 
@@ -242,8 +242,7 @@ void csv_add_row(struct cats_csv *csv, char *line)
         csv->data[row] = malloc_or_die_trace(fields * sizeof(char *), __func__);
 
         for (int32_t i = 0; i < csv->column_count; i++) {
-                csv->data[row][i] = strdup(data->string[i]);
-
+                csv->data[row][i] = strdup(data->string[i]);  // initialisation, non-spatial [csv_add_row]
         }
 
         free_string_array(&data);
diff --git a/src/modules/butterflies/CMakeLists.txt b/src/modules/butterflies/CMakeLists.txt
index c20a250845e6cfd490a47a0312602fc2f7ded1c1..fd53b9a94562a0844d24faa61342b9b8a72b70f8 100644
--- a/src/modules/butterflies/CMakeLists.txt
+++ b/src/modules/butterflies/CMakeLists.txt
@@ -10,7 +10,7 @@ add_library(cats-butterflies SHARED ""
             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)
+            butterflies_actions_setup.h butterflies_initial_population.c butterflies_initial_population.h butterflies_scale.c butterflies_scale.h inline_butterflies.h)
 
 target_include_directories(cats-butterflies PUBLIC ".")
 
diff --git a/src/modules/butterflies/butterflies_dispersal.c b/src/modules/butterflies/butterflies_dispersal.c
index 7448a98e88ae635efa25c5f45229521b8a3bc69b..fd67848d076b8c0f7e8b9bcdcd9371a0b69604e8 100644
--- a/src/modules/butterflies/butterflies_dispersal.c
+++ b/src/modules/butterflies/butterflies_dispersal.c
@@ -10,6 +10,7 @@
 #include "butterflies_dispersal.h"
 #include "configuration/configuration.h"
 #include "modules/module_header.h"
+#include "inline_butterflies.h"
 
 const int N_DIRECTIONS = 9;
 /*
@@ -19,7 +20,7 @@ const int N_DIRECTIONS = 9;
  *   6  7  8
  */
 
-const cats_dt_coord DIRECTION_OFFSETS[9][2] = {
+const cats_dt_coord DIRECTION_OFFSETS[9][2] = { // initialisation, non-spatial
         {+0, +0},
         {+0, +1},
         {-1, +1},
@@ -38,7 +39,7 @@ static void inline single_random_walk(struct cats_thread_info *ts, struct cats_g
 {
 
         const int module_id = CATS_MODULE_ID;
-        const struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
+        struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
         const struct conf_data_butterflies *module_conf = CATS_MODULE_DATA;
         const bool debug_rw = module_conf->debug_rw;
         const int64_t stat_id_deposits = module_conf->stat_ids[BF_RANDOM_WALK_DEPOSIT_COUNT];
@@ -74,7 +75,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)) {
+                int32_t cell_info = butterflies_get_info_layer(data, row, col);
+                if (!(cell_info & 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,
@@ -93,8 +95,9 @@ static void inline single_random_walk(struct cats_thread_info *ts, struct cats_g
                 }
 
                 eggs_left -= eggs_to_deposit;
-                data->eggs[row][col] += (float) eggs_to_deposit;
+                butterflies_add_eggs(data, row, col, (float) eggs_to_deposit);
                 increase_custom_stat(ts->stats, stat_id_deposits, 1);
+
                 if (debug_rw) {
                         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, eggs_to_deposit, eggs_left);
@@ -175,7 +178,8 @@ 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);
 
-        data->eggs[row][col] += (float) ceill(source_cell_eggs);
+        butterflies_add_eggs(data, row, col, (float) ceill(source_cell_eggs));
+
 
 
         if (eggs_to_disperse_per_female == 0) {
diff --git a/src/modules/butterflies/butterflies_generations.c b/src/modules/butterflies/butterflies_generations.c
index f0fd931e1d6cd4581717cb8d16f4fe061e0e90ad..116c98f346888edeee7bf9787c2801524909afaf 100644
--- a/src/modules/butterflies/butterflies_generations.c
+++ b/src/modules/butterflies/butterflies_generations.c
@@ -5,6 +5,8 @@
 #include "actions/cats_actions.h"
 #include "butterflies_generations.h"
 #include "inline.h"
+#include "inline_butterflies.h"
+
 
 // only run at the start of the year
 void bf_area_generation_update(struct cats_grid *grid, struct cats_thread_info *ts)
@@ -32,36 +34,37 @@ 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++) {
 
+                        float eggs = butterflies_get_eggs(data, row, col);
+
                         if (get_suitability(grid, row, col) < suit_ts)
                         {
-                                if (data->eggs[row][col] > 0) cells_with_eggs_removed += 1;
-                                data->eggs[row][col] = 0.0f;
-                                data->generations[row][col] = 0.0f;
+                                if (eggs > 0) cells_with_eggs_removed += 1;
+                                butterflies_set_eggs(data, row, col, 0.0f);
+                                butterflies_set_generations(data, row, col, 0.0f);
                                 set_population_ignore_cc(grid, row, col, 0);
                                 continue;
                         }
 
                         if (cell_excluded_by_overlay(conf, row, col)) {
-                                if (data->eggs[row][col] > 0) cells_with_eggs_removed += 1;
-                                data->eggs[row][col] = 0.0f;
-                                data->generations[row][col] = 0.0f;
+                                if (eggs > 0) cells_with_eggs_removed += 1;
+                                butterflies_set_eggs(data, row, col, 0.0f);
+                                butterflies_set_generations(data, row, col, 0.0f);
                                 set_population_ignore_cc(grid, row, col, 0);
                                 continue;
                         }
 
-                        if ( ! (data->info_layer[row][col] & BF_CELL_VALID_DISPERSAL_TARGET)){
-                                if (data->eggs[row][col] > 0) cells_with_eggs_removed += 1;
-                                data->eggs[row][col] = 0.0f;
-                                data->generations[row][col] = 0.0f;
+                        int32_t cell_info = butterflies_get_info_layer(data, row, col);
+                        if ( ! (cell_info & BF_CELL_VALID_DISPERSAL_TARGET)){
+                                if (eggs > 0) cells_with_eggs_removed += 1;
+                                butterflies_set_eggs(data, row, col, 0.0f);
+                                butterflies_set_generations(data, row, col, 0.0f);
                                 set_population_ignore_cc(grid, row, col, 0);
                                 continue;
                         }
 
                         cats_dt_rates gen = calculate_rate(rate, 0, conf->param, grid, row, col, NULL);
-
-                        data->generations[row][col] = (float) gen;
-                        if (data->eggs[row][col] > 0) cells_with_eggs += 1;
-
+                        butterflies_set_generations(data, row, col, (float) gen);
+                        if (eggs > 0) cells_with_eggs += 1;
                 }
         }
 
diff --git a/src/modules/butterflies/butterflies_initial_population.c b/src/modules/butterflies/butterflies_initial_population.c
index cf0d8fc6f2cb2f74e58a4e5898da3eb9f922303a..9e8bc727191cd541e83307666282f894576711c4 100644
--- a/src/modules/butterflies/butterflies_initial_population.c
+++ b/src/modules/butterflies/butterflies_initial_population.c
@@ -14,6 +14,7 @@
 #include "modules/module_header.h"
 #include "actions/cats_actions.h"
 #include "butterflies_initial_population.h"
+#include "inline_butterflies.h"
 
 
 void bf_initial_population_adjustment(struct cats_configuration *conf, struct cats_grid *grid)
@@ -48,7 +49,7 @@ void bf_initial_population_adjustment(struct cats_configuration *conf, struct ca
                                 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];
+                                        multiplier *= get_overlay_habitat_cc_value(conf, 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);
@@ -92,12 +93,14 @@ void bf_initial_population_adjustment(struct cats_configuration *conf, struct ca
 
         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]) {
+                        float eggs = butterflies_get_eggs(data, row, col);
+                        if (get_adult_population(grid, row, col) || eggs) {
                                 printf(""
                                        "BFDBG::%s::initial adults -> eggs::%d,%d,%d,%f\n",
                                        __func__, row, col, get_adult_population(grid, row, col),
-                                       data->eggs[row][col]);
+                                       eggs);
                         }
 #endif
                         set_population_ignore_cc(grid, row, col, 0);
diff --git a/src/modules/butterflies/butterflies_inline.h b/src/modules/butterflies/butterflies_inline.h
index 2551ab7c3d6894228886493398ed61fdeb0c9482..31d2b6ee8ea847f34597bc1a5a31332cd5dc3bd9 100644
--- a/src/modules/butterflies/butterflies_inline.h
+++ b/src/modules/butterflies/butterflies_inline.h
@@ -6,13 +6,15 @@
 
 #include "butterflies_main.h"
 #include "modules/module_header.h"
+#include "inline_butterflies.h"
 
 
 static inline bool bf_cell_excluded_by_generation(const struct cats_grid *grid, cats_dt_coord row, cats_dt_coord col)
 {
         const int module_id = CATS_MODULE_ID;
         const struct grid_data_butterflies *data = grid->grid_modules[module_id].module_data;
-        if (data->generation_current == 0.0 || data->generation_current > (int32_t) ceilf(data->generations[row][col])) return true;
+        float generations = butterflies_get_generations(data, row, col);
+        if (data->generation_current == 0.0 || data->generation_current > (int32_t) ceilf(generations)) return true;
         return false;
 }
 
diff --git a/src/modules/butterflies/butterflies_overlays.c b/src/modules/butterflies/butterflies_overlays.c
index 704b4fb5a10c1c0b60c34bd24a5e5335ad2f190b..c040b0586caa965164e6b0b41323276c7b2d7f25 100644
--- a/src/modules/butterflies/butterflies_overlays.c
+++ b/src/modules/butterflies/butterflies_overlays.c
@@ -7,6 +7,38 @@
 #include "butterflies_main.h"
 #include "inline_overlays.h"
 #include "inline_population.h"
+#include "inline_butterflies.h"
+
+
+bool butterflies_habitat_ok(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
+{
+        // we have no habitat layer -> all cells have suitable habitat
+        if (conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled == false) {
+                return true;
+        }
+        // habitat layer exists and the carrying capacity is > 0 -> this cell's habitat is suitable
+        if (get_overlay_habitat_cc_value(conf, row, col) > 0) {
+                return true;
+        }
+
+        return false;
+}
+
+
+bool butterflies_resources_ok(const struct cats_configuration *conf, cats_dt_coord row, cats_dt_coord col)
+{
+        // we have no resource layer -> all cells have the resource available
+        if (conf->overlays.overlay[OL_RESOURCE].enabled == false) {
+                return true;
+        }
+
+        // resource layer exists and the resource is > 0 -> this cell's resource is available
+        if (get_overlay_resource_value(conf, row, col) > 0) {
+                return true;
+        }
+
+        return false;
+}
 
 
 enum action_status bf_grid_overlay_update(const struct cats_configuration *conf, struct cats_grid *grid)
@@ -30,49 +62,43 @@ enum action_status bf_grid_overlay_update(const struct cats_configuration *conf,
 
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
+                        int32_t cell_info = BF_CELL_CLEAR;
 
-                        data->info_layer[row][col] = BF_CELL_CLEAR;
-
+                        float eggs = butterflies_get_eggs(data, row, col);
                         if (cell_excluded_by_overlay(conf, row, col)) {
-                                data->info_layer[row][col] |= BF_CELL_EXCLUDED;
-                                if (data->eggs[row][col]) cells_eggs_removed += 1;
+                                cell_info |= BF_CELL_EXCLUDED;
+                                butterflies_set_info_layer(data, row, col, cell_info);
+                                if (eggs) cells_eggs_removed += 1;
                                 if (get_adult_population(grid, row, col)) cells_adults_removed += 1;
-                                data->eggs[row][col] = 0;
+                                butterflies_set_eggs(data, row, col, 0.0f);
                                 set_population_ignore_cc(grid, row, col, 0);
                                 cells_excluded += 1;
                                 continue;
                         }
 
-
-                        if (conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled &&
-                            conf->overlays.habitat_cc->data[row][col] > 0) {
-                                data->info_layer[row][col] |= BF_CELL_HABITAT_OK;
-                                cells_habitat_ok += 1;
-                        } else if (!conf->overlays.overlay[OL_HABITAT_TYPE_CC].enabled) {
-                                data->info_layer[row][col] |= BF_CELL_HABITAT_OK;
+                        if (butterflies_habitat_ok(conf, row, col)) {
+                                cell_info |= BF_CELL_HABITAT_OK;
                                 cells_habitat_ok += 1;
                         }
 
-                        if (conf->overlays.overlay[OL_RESOURCE].enabled &&
-                            conf->overlays.resources->data[row][col] > 0) {
-                                data->info_layer[row][col] |= BF_CELL_RESOURCE_AVAILABLE;
-                                cells_resource_ok += 1;
-                        } else if (!conf->overlays.overlay[OL_RESOURCE].enabled) {
-                                data->info_layer[row][col] |= BF_CELL_RESOURCE_AVAILABLE;
+                        if (butterflies_resources_ok(conf, row, col)) {
+                                cell_info |= BF_CELL_RESOURCE_AVAILABLE;
                                 cells_resource_ok += 1;
                         }
 
-                        if ((data->info_layer[row][col] & BF_CELL_HABITAT_OK) &&
-                            (data->info_layer[row][col] & BF_CELL_RESOURCE_AVAILABLE)) {
-                                data->info_layer[row][col] |= BF_CELL_VALID_DISPERSAL_TARGET;
+
+                        if ((cell_info & BF_CELL_HABITAT_OK) && (cell_info & BF_CELL_RESOURCE_AVAILABLE)) {
+                                cell_info |= BF_CELL_VALID_DISPERSAL_TARGET;
                                 cells_habitat_and_resource_ok += 1;
 
                         } else {
-                                if (data->eggs[row][col]) cells_eggs_removed += 1;
+                                if (eggs) cells_eggs_removed += 1;
                                 if (get_adult_population(grid, row, col)) cells_adults_removed += 1;
-                                data->eggs[row][col] = 0;
+                                butterflies_set_eggs(data, row, col, 0.0f);
                                 set_population_ignore_cc(grid, row, col, 0);
                         }
+
+                        butterflies_set_info_layer(data, row, col, cell_info);
                 }
         }
 
@@ -80,7 +106,7 @@ enum action_status bf_grid_overlay_update(const struct cats_configuration *conf,
         double total_eggs = 0;
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
-                        float eggs = data->eggs[row][col];
+                        float eggs = butterflies_get_eggs(data, row, col);
                         if (eggs > 0) {
                                 cells_with_eggs += 1;
                                 total_eggs += eggs;
diff --git a/src/modules/butterflies/butterflies_populations.c b/src/modules/butterflies/butterflies_populations.c
index f0e0690b6ba94ee09c85b27f24d36a23ebd88853..a2654ed81834797d52489fc246cc25b2a609063c 100644
--- a/src/modules/butterflies/butterflies_populations.c
+++ b/src/modules/butterflies/butterflies_populations.c
@@ -14,6 +14,8 @@
 #include "butterflies_inline.h"
 #include "inline.h"
 #include "populations/population.h"
+#include "inline_butterflies.h"
+
 
 int64_t count_populated_cells(const struct cats_grid *grid)
 {
@@ -43,8 +45,9 @@ int64_t butterflies_prune_invalid_cells(struct cats_grid *grid)
 
         for (cats_dt_coord row = 0; row < rows; row++) {
                 for (cats_dt_coord col = 0; col < cols; col++) {
+                        int32_t cell_info = butterflies_get_info_layer(data, row, col);
+                        if (!(cell_info & BF_CELL_VALID_DISPERSAL_TARGET)) {
 
-                        if (!(data->info_layer[row][col] & BF_CELL_VALID_DISPERSAL_TARGET)) {
                                 if(get_adult_population(grid, row, col)) {
                                         invalid_habitat += 1;
                                 }
@@ -71,7 +74,7 @@ float get_fractional_generation(struct cats_grid *grid, cats_dt_coord row, cats_
 
         float this_generation_fraction = 1.0f;
 
-        float local_generation = data->generations[row][col];
+        float local_generation = butterflies_get_generations(data,row,col);
         int32_t global_max_generation = module_conf->generations_max;
         int32_t local_max_generation = (int32_t) ceilf(local_generation);
         int32_t global_current_generation = data->generation_current;
@@ -107,10 +110,11 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
         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]);
+        
+        const float all_eggs = butterflies_get_eggs(data, row, col);
+        if (all_eggs == 0) return;
+        if (all_eggs < 0) {
+                log_message(LOG_ERROR, "Number of eggs < 0: row %d col %d: %f", row, col, all_eggs);
                 exit(EXIT_FAILURE);
         }
 
@@ -136,21 +140,20 @@ 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;
-        const float eggs = this_generation_fraction * data->eggs[row][col];
+        const float eggs = this_generation_fraction * all_eggs;
 #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);
+               __func__, row, col, local_generation, this_generation_fraction, all_eggs, 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],
+        if (eggs > all_eggs) {
+                log_message(LOG_ERROR, "Removing more eggs than present: %d %d: %f/%f", row, col, all_eggs,
                             eggs);
                 exit_cats(EXIT_FAILURE);
         }
+        butterflies_remove_eggs(data, row, col, eggs);
 
-        data->eggs[row][col] -= eggs;
-        assert(data->eggs[row][col] >= 0);
 
         // not capped, we can have more adults than CC
 
@@ -167,7 +170,7 @@ void bf_cell_maturation(struct cats_grid *grid, struct cats_thread_info *ts, cat
         //printf("row %d col %d: suitability: %f, eggs: %f, reproduction rate %Lf\n", row, col, suit, eggs, reproduction_rate);
 
         if (reproduction_rate == 0) {
-                data->eggs[row][col] = 0;
+                butterflies_set_eggs(data, row, col, 0.0f);
                 set_population_ignore_cc(grid, row, col, 0);
                 return;
         }
diff --git a/src/modules/butterflies/inline_butterflies.h b/src/modules/butterflies/inline_butterflies.h
new file mode 100644
index 0000000000000000000000000000000000000000..c56f01b55d15f8f577dc468be28ee58fe317feda
--- /dev/null
+++ b/src/modules/butterflies/inline_butterflies.h
@@ -0,0 +1,52 @@
+#ifndef CATS_INLINE_BUTTERFLIES_H
+#define CATS_INLINE_BUTTERFLIES_H
+
+#include "butterflies_main.h"
+
+static inline float butterflies_get_eggs(const struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col)
+{       assert(data->eggs[row][col] >= 0);  // setter [butterflies_get_eggs]
+        return data->eggs[row][col];        // setter [butterflies_get_eggs]
+}
+
+static inline void butterflies_set_eggs(struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col, float eggs)
+{
+        assert(eggs >= 0);
+        data->eggs[row][col] = eggs; // setter [butterflies_set_eggs]
+}
+
+static inline void butterflies_add_eggs(struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col, float by)
+{
+        assert(by >= 0);
+        data->eggs[row][col] += by; // setter [butterflies_add_eggs]
+}
+
+static inline void butterflies_remove_eggs(struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col, float by)
+{
+        assert(by >= 0);
+        data->eggs[row][col] -= by;         // setter [butterflies_remove_eggs]
+        assert(data->eggs[row][col] >= 0);  // setter [butterflies_remove_eggs]
+}
+
+static inline void butterflies_set_generations(struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col, float generations)
+{
+        assert(generations >= 0);                   // setter [butterflies_set_generations]
+        data->generations[row][col] = generations;  // setter [butterflies_set_generations]
+}
+
+static inline float butterflies_get_generations(const struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col)
+{
+        return data->generations[row][col]; // getter [butterflies_get_generations]
+}
+
+static inline void butterflies_set_info_layer(struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col, int32_t value)
+{
+        data->info_layer[row][col] = value;  // setter [butterflies_set_info_layer]
+}
+
+static inline int32_t butterflies_get_info_layer(const struct grid_data_butterflies *data, cats_dt_coord row, cats_dt_coord col)
+{
+        return data->info_layer[row][col];  // getter [butterflies_get_info_layer]
+}
+
+
+#endif //CATS_INLINE_BUTTERFLIES_H