diff --git a/binarycpython/utils/custom_logging_functions.py b/binarycpython/utils/custom_logging_functions.py
index 9f58b705a291e39df188765ba9b286a3b27bddff..b966f6eaed6417cd87e8246c112f57abc8cb767a 100644
--- a/binarycpython/utils/custom_logging_functions.py
+++ b/binarycpython/utils/custom_logging_functions.py
@@ -5,7 +5,6 @@ import socket
 import tempfile
 import ctypes
 
-
 def autogen_C_logging_code(logging_dict):
     """
     Function that autogenerates PRINTF statements for binaryc. intput is a dictionary where the key is the header of that logging line and items which are lists of parameters\
@@ -221,7 +220,6 @@ def return_compilation_dict(verbose=False):
 
     return {"cc": cc, "ld": ld, "ccflags": ccflags, "libs": libs, "inc": inc}
 
-
 def compile_shared_lib(code, sourcefile_name, outfile_name, verbose=False):
     """
     Function to write the custom logging code to a file and then compile it.
diff --git a/binarycpython/utils/functions.py b/binarycpython/utils/functions.py
index f6ed5c1c5f2245ceb592a420fdaab4bafa282ddf..fa525601be2710abc0f02b85a64ab047ec76ffb1 100644
--- a/binarycpython/utils/functions.py
+++ b/binarycpython/utils/functions.py
@@ -163,7 +163,7 @@ def get_arg_keys():
     return get_defaults().keys()
 
 
-def get_help(param_name, return_dict=False):
+def get_help(param_name, print_help=True, return_dict=False):
     """
     Function that returns the help info for a given parameter. 
 
@@ -237,8 +237,9 @@ def get_help(param_name, return_dict=False):
             macros = cleaned[macros_line_nr[0] + 1 :]
             help_info_dict["macros"] = macros
 
-        # for key in help_info_dict.keys():
-        #     print("{}:\n\t{}".format(key, help_info_dict[key]))
+        if print_help:
+            for key in help_info_dict.keys():
+                print("{}:\n\t{}".format(key, help_info_dict[key]))
 
         if return_dict:
             return help_info_dict
@@ -412,6 +413,10 @@ def parse_output(output, selected_header):
 
 
 def load_logfile(logfile):
+    """
+    Function that parses the generated logfile of binary_c
+    """
+
     with open(logfile, "r") as f:
         logfile_data = f.readlines()
 
diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py
index 0980dd3ab6790d404c0790f0a294a3b75d94a437..c846fcbd2d8266cabce747340f1e7c4647545a21 100644
--- a/binarycpython/utils/grid.py
+++ b/binarycpython/utils/grid.py
@@ -5,20 +5,18 @@ import sys
 
 import binary_c_python_api
 
-from binarycpython.utils.functions import get_defaults
-
 import binarycpython
+from binarycpython.utils.grid_options_defaults import grid_options_defaults_dict
+from binarycpython.utils.custom_logging_functions import autogen_C_logging_code, binary_c_log_code, create_and_load_logging_function
+from binarycpython.utils.functions import get_defaults
 
-from grid_options_defaults import grid_options_defaults_dict
-
-from custom_logging_functions import autogen_C_logging_code, binary_c_log_code, create_and_load_logging_function
 
 
+# TODO list
 # TODO: add functionality to parse cmdline args
 # TODO: add functionality to 'on-init' set arguments
 # DONE: add functionality to export the arg string.
-# TODO: add functionality to export all the options
-# TODO: add functionality to create the dict that goes into the arg line. 
+# DONE: add functionality to export all the options
 
 # TODO: add functionality to return the initial_abundance_hash
 # TODO: add functionality to return the isotope_hash
@@ -28,28 +26,97 @@ from custom_logging_functions import autogen_C_logging_code, binary_c_log_code,
 # TODO: add functionality to return the source_list
 # TODO: add functionality to return the ensemble_list
 
-# TODO: add functionality to return the evcode_version_string
+# DONE: add functionality to return the evcode_version_string
     # Make this function also an API call. Doest seem to get written to a buffer that is stored into a python object. rather its just written to stdout
-# TODO: add functionality to return the evcode_args_list
+# DONE: add functionality to return the evcode_args_list
+
 
 
 class Population(object):
     def __init__(self):
         """
-        Lots of initialisation
+        Initialisation function of the population class
         """
 
         self.defaults = get_defaults()
 
         # Different sections of options
-        self.bse_options = self.defaults.copy()
+        self.bse_options = {} # bse_options is just empty. Setting stuff will check against the defaults to see if the input is correct. 
         self.grid_options = grid_options_defaults_dict.copy()
         self.custom_options = {}
 
         # Argline dict
         self.argline_dict = {}
 
-    def return_options(self):
+
+    ###################################################
+    # Argument functions
+    ###################################################
+
+    # General flow of generating the arguments for the binary_c call:
+    # - user provides parameter and value via set (or manually but that is risky)
+    # - The parameter names of these input get compared to the parameter names in the self.defaults; with this, we know that its a valid 
+    # parameter to give to binary_c. 
+    # - For a single system, the bse_options will be written as a arg line
+    # - For a population the bse_options will get copied to a temp_bse_options file and updated with all the parameters generated by the grid
+
+
+    # I will NOT create the argument line by fully writing ALL the defaults and overriding user input, that seems not necessary 
+    # because by using the get_defaults() function we already know for sure which parameter names are valid for the binary_c version
+    # And because binary_c uses internal defaults, its not necessary to explicitly pass them
+    # I do however suggest everyone to export the binary_c defaults to a file, so that you know exactly which values were the defaults
+
+    def set(self, **kwargs):
+        """
+        Function to set the values of the population. This is the preferred method to set values of functions, as it 
+        provides checks on the input. 
+
+        the bse_options will get populated with all the those that have a key that is present in the self.defaults
+        the grid_options will get updated with all the those that have a key that is present in the self.grid_options
+        
+        If neither of above is met; the key and the value get stored in a custom_options dict.
+        """
+
+        for key in kwargs.keys():
+            # Filter out keys for the bse_options
+            if key in self.defaults.keys():
+                print('adding: {}={} to BSE_options'.format(key,kwargs[key]))
+                self.bse_options[key] = kwargs[key]
+
+            # Filter out keys for the grid_options
+            elif key in self.grid_options.keys():
+                self.grid_options[key] = kwargs[key]
+            # The of the keys go into a custom_options dict
+            else:
+                self.custom_options[key] = kwargs[key]
+
+    def return_argline(self, parameter_dict=None):
+        """
+        Function to create the string for the arg line from a parameter dict
+        """
+
+        if not parameter_dict:
+            parameter_dict = self.bse_options
+
+        argline = "binary_c "
+        for param_name in sorted(parameter_dict):
+            argline += "{} {} ".format(param_name, parameter_dict[param_name])
+        argline = argline.strip()
+        return argline
+
+    def generate_population_arglines_file(self, output_file):
+        """
+        Function to generate a file that contains all the argument lines that would be given to binary_c if the population had been run
+        """
+
+        pass
+
+
+    ###################################################
+    # Return functions
+    ###################################################
+
+    def return_population_settings(self):
         """
         Function that returns all the options that have been set.
 
@@ -64,93 +131,73 @@ class Population(object):
 
         return options
 
-
-    def create_argline_dict(self, print_excluded=False):
+    def return_binary_c_version_info(self):
         """
-        Function to prepare the dictionary of options that go into the argument line for the binary_c call.
-
-        This function 
+        Function that returns the version information of binary_c
+    
+        TODO: Put in a nice dict. 
         """
 
-        self.argline_dict = {}
-
-        # Lists to store indices of parameters that have been included and excluded. 
-        included, excluded = [], []
+        version_info = binary_c_python_api.return_version_info()
 
-        # Go over the parameters.    
-        for i, param_name in enumerate(sorted(self.bse_options)):
-            # We need to filter out some parameters:
-            # Filter out those that have an literal empty value. The argument parser of binary_c doesnt work properly with that.
-            # Filter out those that have value Function. adding these to the argument will execute the function instead of evolving the system
-            # Filter out those that have value NULL. In general these only come from the defaults of binary_c itself. 
-            #   What I do here is comparing whether the value of the bse_option is NULL currently AND as a default. In that way one could set some other part to NULL (don't know what situation that would be tho..) 
+        return version_info.strip()
 
+    def return_binary_c_defaults(self):
+        """
+        Function that returns the defaults of the binary_c version that is used.
+        """
 
-            if (not ((self.bse_options[param_name] == 'NULL') and (self.bse_options[param_name] == self.defaults[param_name]))) \
-            and (not self.bse_options[param_name] == "") and (not self.bse_options[param_name] == "Function"):
-                self.argline_dict[param_name] = self.bse_options[param_name]
-                # print("{} {} ".format(param_name, self.bse_options[param_name]))
-                included.append(i)
-            else:
-                # print("{} {} ".format(param_name, repr(self.bse_options[param_name])))
-                excluded.append(i)
+        return self.defaults
 
-        common = set(included).intersection(excluded)
-        combined = set(included).union(excluded)
+    def return_all_info(self):
+        """
+        Function that returns all the information about the population and binary_c
+        """
 
-        if print_excluded:
-            print("Total parameters included in the argument: {}. Total excluded: {}. ".format(len(included), len(excluded)))
-            print([sorted(self.bse_options)[i] for i in excluded])
+        from binarycpython.utils.functions import get_help_all
 
+        population_settings = self.return_population_settings()
+        binary_c_defaults = self.return_binary_c_defaults()
+        binary_c_version_info = self.return_binary_c_version_info()
+        binary_c_help_all_info = get_help_all(print_help=False, return_dict=True)
 
-    def create_argline(self, option_dict):
-        """
-        Function to create the string for the arg line
-        """
+        all_info = {}
+        all_info['population_settings'] = population_settings
+        all_info['binary_c_defaults'] = binary_c_defaults
+        all_info['binary_c_version_info'] = binary_c_version_info
+        all_info['binary_c_help_all'] = binary_c_help_all_info
 
-        argline = "binary_c "
-        for param_name in sorted(option_dict):
-            argline += "{} {} ".format(param_name, self.argline_dict[param_name])
-        argline = argline.strip()
-        return argline
+        return all_info
 
-    def return_argline(self, print_excluded=False):
+    def export_all_info(self, outfile):
         """
-        Function to return the argline that is used in the binary_c api call:
-        be aware that some of the parameters vary: M1 M2 period etc because these are set by distributions.
+        Function that exports the all_info to a json file
 
+        TODO: if any of the values in the dicts here is of a not-serializable form, then we need to change that to a string or something
+        so, use a recursive function that goes over the all_info dict and finds those that fit
         """
 
-        self.create_argline_dict(print_excluded)
+        all_info = self.return_all_info()
 
-        argline = "binary_c "
-        for param_name in sorted(self.argline_dict.keys()):
-            argline += "{} {} ".format(param_name, self.argline_dict[param_name])
+        # if not outfile.endswith('json'):
+        with open(outfile, 'w') as f:
+            f.write(json.dumps(all_info, indent=4))
 
-        argline = argline.strip()
-        return argline
+    ###################################################
+    # Evolution functions
+    ###################################################
 
-    def set(self, **kwargs):
+    def evolve_single(self):
         """
-        Function to set the values of the population
-
-        The input (as kwargs) is checked compared to the available bse_options and grid options.
-        if the parameter name is not included in either of those, then it will be stored in an custom_options dict.
+        Function to run a single system
         """
 
-        print(self.grid_options.keys())
 
-
-        for key in kwargs.keys():
-            # Filter out keys for the bse_options
-            if key in self.bse_options.keys():
-                self.bse_options[key] = kwargs[key]
-            # Filter out keys for the grid_options
-            elif key in self.grid_options.keys():
-                self.grid_options[key] = kwargs[key]
-            # The of the keys go into a custom_options dict
-            else:
-                self.custom_options[key] = kwargs[key]
+        argline = self.return_argline(self.bse_options)
+return_binary_c_version_info
+        out = binary_c_python_api.run_binary(argline)
+        # out = binary_c_python_api.run_binary('binary_c M_1 15 M_2 14 separation 0 orbital_period 4530 eccentricity 0 metallicity 0.02 max_evolution_time 15000')
+        return out
 
     def evolve_population(self, custom_arg_file=None):
         """
@@ -179,9 +226,6 @@ class Population(object):
             self.grid_options['custom_logging_func_memaddr'] = create_and_load_logging_function(custom_logging_code)
         ###
 
-
-
-
         ### Arguments 
         # If user inputs a file containing arg lines then use that
         if custom_arg_file:
@@ -197,6 +241,11 @@ class Population(object):
 
         else:
             # generate population from options 
+
+
+
+            print('ho')
+
             pass
 
         #######
@@ -210,35 +259,9 @@ class Population(object):
         pass
 
 
-    def generate_population_arglines_file(self, output_file):
-        """
-        Function to generate a file that contains all the argument lines that would be given to binary_c if the population had been run
-        """
-
-
-
-    def evolve_single(self):
-        """
-        Function to run a single system
-        """
-
-        self.create_argline_dict()        
-
-        argline = self.create_argline(self.argline_dict)
-
-        out = binary_c_python_api.run_binary(argline)
-        # out = binary_c_python_api.run_binary('binary_c M_1 15 M_2 14 separation 0 orbital_period 4530 eccentricity 0 metallicity 0.02 max_evolution_time 15000')
-        # print(out)
-        return out
-
-    def return_binary_c_version_info(self):
-        """
-        Function that returns the version information of binary_c
-        """
-
-        out = binary_c_python_api.run_binary('binary_c version')
-        # out = binary_c_python_api.run_binary('binary_c M_1 15 M_2 14 separation 0 orbital_period 4530 eccentricity 0 metallicity 0.02 max_evolution_time 15000')
-        return out
+    ###################################################
+    # Testing functions
+    ###################################################
 
     def test_evolve_single(self):
         m1 = 15.0  # Msun
@@ -264,52 +287,4 @@ class Population(object):
         print(output)
 
 
-
-
-
 ################################################################################################ 
-test_pop = Population()
-
-# Setting values
-# print(test_pop.bse_options['M_1'])
-# print(test_pop.bse_options['M_2'])
-# test_pop.set(M_1=10, M_2=500)
-# print(test_pop.bse_options['M_1'])
-# print(test_pop.bse_options['M_2'])
-test_pop.set(M_1=10, separation=0, orbital_period=4580, max_evolution_time=15000, eccentricity=0.02, )
-
-
-## Testing single evolution
-# test_pop.evolve_single()
-# test_pop.test_evolve_single()
-
-## Setting custom value
-# test_pop.set(data_dir=os.path.join(os.environ['BINARYC_DATA_ROOT'], 'development_example'))
-# print(test_pop.custom_options['data_dir'])
-
-
-## printing all options
-# print(json.dumps(test_pop.return_options(), indent=4))
-
-## return arglines:
-# test_pop.set(M_1=10, M_2=500)
-# print(test_pop.return_argline())
-# test_pop.return_argline(print_excluded=True)
-
-#print(test_pop.bse_options)
-
-## return version info
-# a = test_pop.return_binary_c_version_info()
-# print(a)
-
-## Use custom arg file
-# test_pop.evolve_population(custom_arg_file='/home/david/projects/binary_c_root/binary_c-python/tests/population/custom_arg_file.txt')
-
-
-
-## Custom logging:
-# test_pop.set(C_auto_logging={'MY_HEADER_LINE': ['star[0].mass', 'star[1].mass', 'model.probability']})
-# test_pop.set(C_logging_code='Printf("MY_STELLAR_DATA time=%g mass=%g\\n", stardata->model.time, stardata->star[0].mass);')
-# test_pop.set(C_logging_code='Printf("MY_HEADER_LINE %g %g %g\\n",((double)stardata->star[0].mass),((double)stardata->star[1].mass),((double)stardata->model.probability));')
-# test_pop.evolve_population()
-
diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py
index f635578f9909022d131051f20b0132b21a3d8df6..d45f0a53b0246816fd76c2995ed1cd134e454cdf 100644
--- a/binarycpython/utils/grid_options_defaults.py
+++ b/binarycpython/utils/grid_options_defaults.py
@@ -1,13 +1,25 @@
 grid_options_defaults_dict = {
-    'custom_logging_function': None, # This will hold the custom logging mem addr
+    # 
     'amt_cores': 1, # total amount of cores used to evolve the population
     'verbose': 0, # Level of verbosity of the simulation
 
-
     # Custom logging
     'C_auto_logging': None, # Should contain a dictionary where the kes are they headers and the values are lists of parameters that should be logged. This will get parsed by autogen_C_logging_code in custom_loggion_functions.py
     'C_logging_code': None, # Should contain a string which holds the logging code.
     'custom_logging_func_memaddr': -1, # Contains the custom_logging functions memory address
+
+    # Log args: logging of arguments 
+    'log_args': 0, #
+    'log_args_dir': '/tmp/',
+
     
-    
+    # return_array_refs=>1, # quicker data parsing mode
+    # sort_args=>1,
+    # save_args=>1,
+    # nice=>'nice -n +20',  # nice command e.g. 'nice -n +10' or '' 
+    # timeout=>15, # seconds until timeout
+    # log_filename=>"/scratch/davidh/results_simulations/tmp/log.txt",
+    # # current_log_filename=>"/scratch/davidh/results_simulations/tmp/grid_errors.log",
+        
 }
+
diff --git a/include/binary_c_python.h b/include/binary_c_python.h
index 01aca72eac4bb71c4e0abfcb8ba4c4fa9c0cd61d..fe229b9b2f003775ebab00743eb0e4f392cf1bfa 100644
--- a/include/binary_c_python.h
+++ b/include/binary_c_python.h
@@ -9,6 +9,9 @@
 #include "binary_c_API_prototypes.h"
 
 /* Binary_c's python API prototypes */
+
+
+
 int run_binary(char * argstring,
                 char ** const outstring,
                 char ** const errorstring,
@@ -20,11 +23,23 @@ int run_binary_with_logfile(char * argstring,
                 size_t * const nbytes);
 
 int run_binary_custom_logging(char * argstring,
-               long int func_memaddr,
+               long int custom_logging_func_memaddr,
                char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes);
 
+int run_population(char * argstring,
+               long int custom_logging_func_memaddr,
+               long int store_memaddr,
+               char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes);
+
+
+/* =================================================================== */
+/* Functions to call other API functionality like help and arglines    */
+/* =================================================================== */
+
 int return_arglines(char ** const outstring,
                 char ** const errorstring,  
                 size_t * const nbytes);
@@ -38,6 +53,20 @@ int return_help_all_info(char ** const outstring,
                 char ** const errorstring,
                 size_t * const nbytes);
 
+int return_version_info(char ** const outstring,
+                char ** const errorstring,
+                size_t * const nbytes);
+
+
+/* =================================================================== */
+/* Functions to call other functionality                               */
+/* =================================================================== */
+long int return_store(char * argstring, // can we do this without argstring?
+               char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes);
+
+
 /* C macros */
 #define BINARY_C_APITEST_VERSION 0.1
 #define APIprint(...) APIprintf(__VA_ARGS__);
diff --git a/src/binary_c_python.c b/src/binary_c_python.c
index 726752d979131dbe451f28f51d71a8fdddebcf90..1c9d589fea7ff72be94a7fcf86f762068df42ffd 100644
--- a/src/binary_c_python.c
+++ b/src/binary_c_python.c
@@ -37,10 +37,12 @@ static char new_binary_system_docstring[] =
 // Evolution function docstrings
 static char run_binary_docstring[] =
     "Run one binary using binary_c";
-static char run_binary_with_logdocstring[] =
+static char run_binary_with_log_docstring[] =
     "Run one binary using binary_c and allow the logfile to be written. Do not use for populations!";
-static char run_binary_custom_loggingdocstring[] =
+static char run_binary_custom_logging_docstring[] =
     "TODO";
+static char run_population_docstring[] = 
+    "Run population of systems";
 
 // Utility function docstrings
 static char return_arglines_docstring[] =
@@ -49,6 +51,13 @@ static char return_help_info_docstring[] =
     "Return the help info for a given parameter";
 static char return_help_all_info_docstring[] = 
     "Return an overview of all the parameters, their description, categorized in sections";
+static char return_version_info_docstring[] = 
+    "Return the version information of the used binary_c build";
+
+// other functionality
+static char return_store_docstring[] = 
+    "Return the store memory adress that will be passed to run_population";
+
 
 static struct libbinary_c_store_t *store = NULL;
 
@@ -63,11 +72,16 @@ static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args);
 static PyObject* binary_c_run_binary(PyObject *self, PyObject *args);
 static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args);
 static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *args);
+static PyObject* binary_c_run_population(PyObject *self, PyObject *args);
 
 // Utility function headers
 static PyObject* binary_c_return_arglines(PyObject *self, PyObject *args);
 static PyObject* binary_c_return_help_info(PyObject *self, PyObject *args);
 static PyObject* binary_c_return_help_all_info(PyObject *self, PyObject *args);
+static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args);
+
+// Other function headers
+static PyObject* binary_c_return_store(PyObject *self, PyObject *args);
 
 /*
  * Python 3 interface is described at
@@ -88,13 +102,17 @@ static PyMethodDef module_methods[] = {
     {"new_system", binary_c_new_binary_system, METH_VARARGS, new_binary_system_docstring},
 
     {"run_binary", binary_c_run_binary, METH_VARARGS, run_binary_docstring},
-    {"run_binary_with_logfile", binary_c_run_binary_with_logfile, METH_VARARGS, run_binary_with_logdocstring},
-    {"run_binary_custom_logging", binary_c_run_binary_custom_logging, METH_VARARGS, run_binary_custom_loggingdocstring},
+    {"run_binary_with_logfile", binary_c_run_binary_with_logfile, METH_VARARGS, run_binary_with_log_docstring},
+    {"run_binary_custom_logging", binary_c_run_binary_custom_logging, METH_VARARGS, run_binary_custom_logging_docstring},
+    {"run_population", binary_c_run_population, METH_VARARGS, run_population_docstring},
 
     {"return_arglines", binary_c_return_arglines, METH_VARARGS, return_arglines_docstring},
     {"return_help", binary_c_return_help_info, METH_VARARGS, return_help_info_docstring},
     {"return_help_all", binary_c_return_help_all_info, METH_VARARGS, return_help_all_info_docstring},
-    
+    {"return_version_info", binary_c_return_version_info, METH_VARARGS, return_version_info_docstring},
+
+    {"return_store", binary_c_return_store, METH_VARARGS, return_store_docstring},
+
     {NULL, NULL, 0, NULL}
 };
 
@@ -200,59 +218,59 @@ static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args)
 }
 
 /*
-
-Below are the real funtions:
-binary_c_run_binary
-binary_c_run_binary_custom_logging
-binary_c_run_binary_with_logfile
-
-binary_c_return_arglines
-binary_c_return_help_info
-binary_c_return_help_all_info
-
-
+    Below are the real funtions:
+    binary_c_run_binary
+    binary_c_run_binary_custom_logging
+    binary_c_run_binary_with_logfile
+    binary_c_run_population
+
+    binary_c_return_arglines
+    binary_c_return_help_info
+    binary_c_return_help_all_info
+    binary_c_return_version_info
 */
 
-/* Wrappers to functions that evolve binary systems. */
+/* ============================================================================== */
+/* Wrappers to functions that evolve binary systems.                              */
+/* ============================================================================== */
+
 
 static PyObject* binary_c_run_binary(PyObject *self, PyObject *args)
 {
     /* Parse the input tuple */
     char *argstring;
     
+    /* Parse the input tuple */
     if(!PyArg_ParseTuple(args, "s", &argstring))
-    {
+
         return NULL;
-    }
-    else
-    {
-        char * buffer;
-        char * error_buffer;
-        size_t nbytes;
-        int out MAYBE_UNUSED = run_binary(argstring,
-                                          &buffer,
-                                          &error_buffer,
-                                          &nbytes);
-        /* copy the buffer to a python string */
-        PyObject * return_string = Py_BuildValue("s", buffer);
-        PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
 
-        if(error_buffer != NULL && strlen(error_buffer)>0)
-        {
-            fprintf(stderr,
-                    "Error in binary_c run : %s\n",
-                    error_buffer);
-        }
-        
-        Safe_free(buffer);
-        Safe_free(error_buffer);
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    int out MAYBE_UNUSED = run_binary(argstring,
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
 
-        /* 
-         * TODO
-         * return the return_error_string as well!
-         */
-        return return_string;
+    if(error_buffer != NULL && strlen(error_buffer)>0)
+    {
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
     }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    /* 
+     * TODO
+     * return the return_error_string as well!
+     */
+    return return_string;
 }
 
 static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *args)
@@ -265,36 +283,34 @@ static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *ar
     {
         return NULL;
     }
-    else
-    {
-        char * buffer;
-        char * error_buffer;
-        size_t nbytes;
-        int out MAYBE_UNUSED = run_binary_custom_logging(argstring,
-                                          func_memaddr, 
-                                          &buffer,
-                                          &error_buffer,
-                                          &nbytes);
-        /* copy the buffer to a python string */
-        PyObject * return_string = Py_BuildValue("s", buffer);
-        PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
 
-        if(error_buffer != NULL && strlen(error_buffer)>0)
-        {
-            fprintf(stderr,
-                    "Error in binary_c run : %s\n",
-                    error_buffer);
-        }
-        
-        Safe_free(buffer);
-        Safe_free(error_buffer);
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    int out MAYBE_UNUSED = run_binary_custom_logging(argstring,
+                                      func_memaddr, 
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
 
-        /* 
-         * TODO
-         * return the return_error_string as well!
-         */
-        return return_string;
+    if(error_buffer != NULL && strlen(error_buffer)>0)
+    {
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
     }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    /* 
+     * TODO
+     * return the return_error_string as well!
+     */
+    return return_string;
 }
 
 static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args)
@@ -306,39 +322,84 @@ static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args
     {
         return NULL;
     }
-    else
+
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    int out MAYBE_UNUSED = run_binary_with_logfile(argstring,
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+
+    if(error_buffer != NULL && strlen(error_buffer)>0)
     {
-        char * buffer;
-        char * error_buffer;
-        size_t nbytes;
-        int out MAYBE_UNUSED = run_binary_with_logfile(argstring,
-                                          &buffer,
-                                          &error_buffer,
-                                          &nbytes);
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
+    }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
 
-        /* copy the buffer to a python string */
-        PyObject * return_string = Py_BuildValue("s", buffer);
-        PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+    /* 
+     * TODO
+     * return the return_error_string as well!
+     */
+    return return_string;
+}
 
-        if(error_buffer != NULL && strlen(error_buffer)>0)
-        {
-            fprintf(stderr,
-                    "Error in binary_c run : %s\n",
-                    error_buffer);
-        }
-        
-        Safe_free(buffer);
-        Safe_free(error_buffer);
+static PyObject* binary_c_run_population(PyObject *self, PyObject *args)
+{
+    /* Parse the input tuple */
+    char *argstring;
+    long int custom_logging_func_memaddr;
+    long int store_memaddr;
 
-        /* 
-         * TODO
-         * return the return_error_string as well!
-         */
-        return return_string;
+
+    if(!PyArg_ParseTuple(args, "sll", &argstring, &custom_logging_func_memaddr, &store_memaddr))
+    {
+        return NULL;
     }
+
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    int out MAYBE_UNUSED = run_population(argstring,
+                                      custom_logging_func_memaddr, 
+                                      store_memaddr,
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+
+    if(error_buffer != NULL && strlen(error_buffer)>0)
+    {
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
+    }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    /* 
+     * TODO
+     * return the return_error_string as well!
+     */
+    return return_string;
 }
 
-/* Wrappers to functions that call other API functionality like help and arglines*/
+
+/* ============================================================================== */
+/* Wrappers to functions that call other API functionality like help and arglines */
+/* ============================================================================== */
 
 static PyObject* binary_c_return_arglines(PyObject *self, PyObject *args)
 {
@@ -409,15 +470,6 @@ static PyObject* binary_c_return_help_info(PyObject *self, PyObject *args)
 
 static PyObject* binary_c_return_help_all_info(PyObject *self, PyObject *args)
 {
-    /* Parse the input tuple */
-    // char *argstring;
-    
-    // if(!PyArg_ParseTuple(args, "s", &argstring))
-    // {
-    //     return NULL;
-    // }
-    // else
-    // {
     char * buffer;
     char * error_buffer;
     size_t nbytes;
@@ -440,5 +492,75 @@ static PyObject* binary_c_return_help_all_info(PyObject *self, PyObject *args)
     Safe_free(error_buffer);
 
     return return_string;
-    // }
+}
+
+static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args)
+{
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    int out MAYBE_UNUSED = return_version_info(&buffer,
+                                          &error_buffer,
+                                          &nbytes);
+
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+
+    if(error_buffer != NULL && strlen(error_buffer)>0)
+    {
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
+    }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    return return_string;
+}
+
+/* ============================================================================== */
+/* Wrappers to functions that call other functionality */
+/* ============================================================================== */
+
+static PyObject* binary_c_return_store(PyObject *self, PyObject *args)
+{
+    /* Parse the input tuple */
+    char *argstring;
+    
+    if(!PyArg_ParseTuple(args, "s", &argstring))
+    {
+        return NULL;
+    }
+
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+    long int out MAYBE_UNUSED = return_store(argstring,
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+
+    /* copy the buffer to a python string */
+    PyObject * return_string = Py_BuildValue("s", buffer);
+    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+
+    PyObject * return_store_memaddr = Py_BuildValue("l", out);
+
+    if(error_buffer != NULL && strlen(error_buffer)>0)
+    {
+        fprintf(stderr,
+                "Error in binary_c run : %s\n",
+                error_buffer);
+    }
+    
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    /* 
+     * TODO
+     * return the return_error_string as well!
+     */
+    return return_store_memaddr;
 }
\ No newline at end of file
diff --git a/src/binary_c_python_api.c b/src/binary_c_python_api.c
index 10ab6147a27f35286c4c795f70b9aa3345cb51ab..e8922c589214df74c3d917389eebb027eacb62d7 100644
--- a/src/binary_c_python_api.c
+++ b/src/binary_c_python_api.c
@@ -48,19 +48,29 @@ int stdoutwas;
 /*
 Below are the real calls to the API of binary_c. Currently these are the functions:
 
+// evolution
 run_binary
 run_binary_custom_logging
-return_arglines
 run_binary_with_logfile
+run_population
+
+
+// utility
+return_arglines
 return_help_info
 return_help_all_info
+return_version_info
 
+// other
+create_store
 
 */
 
 
+/* =================================================================== */
+/* Functions to evolve systems                                         */
+/* =================================================================== */
 
-/* Functions to evolve binary systems */
 
 int run_binary(char * argstring,
                char ** const buffer,
@@ -96,7 +106,7 @@ int run_binary(char * argstring,
     /* do binary evolution */
     binary_c_evolve_for_dt(stardata,
                            stardata->model.max_evolution_time);
-        
+
     /* get buffer pointer */
     binary_c_buffer_info(stardata,buffer,nbytes);
     
@@ -114,7 +124,7 @@ int run_binary(char * argstring,
 }
 
 int run_binary_custom_logging(char * argstring,
-               long int func_memaddr,
+               long int custom_logging_func_memaddr,
                char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes)
@@ -144,7 +154,7 @@ int run_binary_custom_logging(char * argstring,
     /* output to strings */
     stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
     stardata->preferences->batchmode = BATCHMODE_LIBRARY;
-    stardata->preferences->custom_output_function = (void*)(struct stardata_t *)func_memaddr;
+    stardata->preferences->custom_output_function = (void*)(struct stardata_t *)custom_logging_func_memaddr;
 
     /* do binary evolution */
     binary_c_evolve_for_dt(stardata,
@@ -207,7 +217,69 @@ int run_binary_with_logfile(char * argstring,
     return 0;
 }
 
-/* Functions to call other API functionality like help and arglines */
+int run_population(char * argstring,
+               long int custom_logging_func_memaddr,
+               long int store_memaddr,
+               char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes)
+{
+    /* memory for N binary systems */
+    struct libbinary_c_stardata_t *stardata;
+
+    // load the store
+    // struct libbinary_c_store_t * store = (void*)store_memaddr;
+    struct libbinary_c_store_t * store = NULL;
+
+    /* make new stardata */
+    stardata = NULL;
+    binary_c_new_system(&stardata,
+                        NULL,
+                        NULL,
+                        &store,
+                        &argstring,
+                        -1);
+    
+    /* disable logging */
+    snprintf(stardata->preferences->log_filename,
+             STRING_LENGTH-1,
+             "%s",
+             "/dev/null");
+    snprintf(stardata->preferences->api_log_filename_prefix,
+             STRING_LENGTH-1,
+             "%s",
+             "/dev/null");
+
+    /* output to strings */
+    stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
+    stardata->preferences->batchmode = BATCHMODE_LIBRARY;
+    stardata->preferences->custom_output_function = (void*)(struct stardata_t *)custom_logging_func_memaddr;
+
+    /* do binary evolution */
+    binary_c_evolve_for_dt(stardata,
+                           stardata->model.max_evolution_time);
+        
+    /* get buffer pointer */
+    binary_c_buffer_info(stardata,buffer,nbytes);
+    
+    /* get error buffer pointer */
+    binary_c_error_buffer(stardata,error_buffer);
+    
+    /* set raw_buffer_size = -1 to prevent it being freed */
+    stardata->tmpstore->raw_buffer_size = -1;
+    
+    /* free stardata (except the buffer) */
+    binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE);
+        
+    // Ask rob whether to free the memory here or not? or to free it manually.
+
+    return 0;
+}
+
+/* =================================================================== */
+/* Functions to call other API functionality like help and arglines    */
+/* =================================================================== */
+
 int return_arglines(char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes)
@@ -338,4 +410,87 @@ int return_help_all_info(char ** const buffer,
     binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE);
     binary_c_free_store_contents(store);
     return 0;
+}
+
+int return_version_info(char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes)
+{
+    /* memory for N binary systems */
+    struct libbinary_c_stardata_t *stardata;
+    struct libbinary_c_store_t * store = NULL;
+
+    /* make new stardata */
+    stardata = NULL;
+    char * empty_str = "";
+    binary_c_new_system(&stardata,
+                        NULL,
+                        NULL,
+                        &store,
+                        &empty_str,
+                        -1);
+
+    /* output to strings */
+    stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
+    stardata->preferences->batchmode = BATCHMODE_LIBRARY;
+
+    /* Ask the help api */
+    binary_c_version(stardata);
+        
+    /* get buffer pointer */
+    binary_c_buffer_info(stardata,buffer,nbytes);
+    
+    /* get error buffer pointer */
+    binary_c_error_buffer(stardata,error_buffer);
+    
+    /* set raw_buffer_size = -1 to prevent it being freed */
+    stardata->tmpstore->raw_buffer_size = -1;
+    
+    /* free stardata (except the buffer) */
+    binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE);
+    binary_c_free_store_contents(store);
+    return 0;
+}
+
+/* =================================================================== */
+/* Functions to call other functionality                               */
+/* =================================================================== */
+
+
+long int return_store(char * argstring,
+               char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes)
+{
+    /* memory for N binary systems */
+    struct libbinary_c_stardata_t *stardata;
+    struct libbinary_c_store_t * store = NULL;
+
+    /* make new stardata */
+    stardata = NULL;
+    binary_c_new_system(&stardata,
+                        NULL,
+                        NULL,
+                        &store,
+                        &argstring,
+                        -1);
+
+    /* output to strings */
+    // stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
+    // stardata->preferences->batchmode = BATCHMODE_LIBRARY;
+
+    /* get buffer pointer */
+    binary_c_buffer_info(stardata, buffer, nbytes);
+    
+    /* get error buffer pointer */
+    binary_c_error_buffer(stardata, error_buffer);
+    
+    /* set raw_buffer_size = -1 to prevent it being freed */
+    stardata->tmpstore->raw_buffer_size = -1;
+    
+    /* free stardata (except the buffer) */
+    binary_c_free_memory(&stardata, TRUE, TRUE, FALSE, FALSE);
+
+    // binary_c_free_store_contents(store);
+    return store;
 }
\ No newline at end of file
diff --git a/tests/population/grid_tests.py b/tests/population/grid_tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8d8ec1e8ce718598644900338c7cbbc7beb56bd
--- /dev/null
+++ b/tests/population/grid_tests.py
@@ -0,0 +1,61 @@
+import os
+import json
+
+from binarycpython.utils.grid import Population
+from binarycpython.utils.functions import get_help_all, get_help
+
+
+test_pop = Population()
+
+## Setting values
+# print(test_pop.bse_options['M_1'])
+# print(test_pop.bse_options['M_2'])
+# test_pop.set(M_1=10, M_2=500)
+# print(test_pop.bse_options['M_1'])
+# print(test_pop.bse_options['M_2'])
+test_pop.set(M_1=10, separation=0, orbital_period=4580, max_evolution_time=15000, eccentricity=0.02, )
+# print(test_pop.bse_options)
+
+## Testing single evolution
+# test_pop.evolve_single()
+# test_pop.test_evolve_single()
+
+## Setting custom value
+# test_pop.set(data_dir=os.path.join(os.environ['BINARYC_DATA_ROOT'], 'development_example'))
+# print(test_pop.custom_options['data_dir'])
+
+## printing all options
+# print(json.dumps(test_pop.return_population_settings(), indent=4))
+
+## return arglines:
+# test_pop.set(M_1=10, M_2=500)
+# print(test_pop.return_argline())
+# test_pop.return_argline()
+
+## return version info
+# version_info = test_pop.return_binary_c_version_info()
+# print(version_info)
+
+## Use custom arg file
+# test_pop.evolve_population(custom_arg_file='/home/david/projects/binary_c_root/binary_c-python/tests/population/custom_arg_file.txt')
+
+## Custom logging:
+# test_pop.set(C_auto_logging={'MY_HEADER_LINE': ['star[0].mass', 'star[1].mass', 'model.probability']})
+# test_pop.set(C_logging_code='Printf("MY_STELLAR_DATA time=%g mass=%g\\n", stardata->model.time, stardata->star[0].mass);')
+# test_pop.set(C_logging_code='Printf("MY_HEADER_LINE %g %g %g\\n",((double)stardata->star[0].mass),((double)stardata->star[1].mass),((double)stardata->model.probability));')
+
+# test_pop.evolve_population()
+
+## Help all
+# print(get_help_all(return_dict=True))
+
+# get_help_all()
+# print(get_help('M_1', print_help=False, return_dict=True))
+
+
+# return all info:
+# print(json.dumps(test_pop.return_all_info(), indent=4))
+test_pop.export_all_info(outfile=os.path.join(os.getcwd(), 'test_output.txt'))
+
+
+
diff --git a/tests/python_API_test.py b/tests/python_API_test.py
index cc373d2a47be50c6583b7a521204c0ad372abf61..8d295b57f2e595830749d0832e2b48dad7e1f2f7 100755
--- a/tests/python_API_test.py
+++ b/tests/python_API_test.py
@@ -121,6 +121,15 @@ def test_return_help_all():
     out = binary_c_python_api.return_help_all("M_1")
     print(out)
 
+def test_return_version_info():
+    out = binary_c_python_api.return_version_info()
+    print(out)
+
+
+def test_return_store():
+    out = binary_c_python_api.return_store("binary_c M_1 10")
+    print(out)
+
 
 ####
 if __name__ == "__main__":
@@ -135,3 +144,7 @@ if __name__ == "__main__":
     test_return_arglines()
 
     test_return_help_all()
+
+    test_return_version_info()
+
+    test_return_store()