diff --git a/binarycpython/utils/functions.py b/binarycpython/utils/functions.py
index c65ca92db015fcacef934a4e1a67a28a69caa6a2..df087d4e2c09c857d1c99ef74546f08191c079db 100644
--- a/binarycpython/utils/functions.py
+++ b/binarycpython/utils/functions.py
@@ -1,3 +1,5 @@
+import copy
+import json
 from collections import defaultdict
 
 import binary_c_python_api
@@ -5,6 +7,110 @@ from binarycpython.utils.custom_logging_functions import (
     create_and_load_logging_function,
 )
 
+def get_help_all(print_help=True, return_dict=False):
+    """
+    Function that reads out the output of the help_all api call to binary_c
+
+    prints all the parameters and their descriptions.
+
+    return_dict:  returns a dictionary
+    """
+
+    # Call function
+    help_all = binary_c_python_api.return_help_all()
+
+    # String manipulation
+    split = help_all.split(
+        "############################################################\n"
+    )
+    cleaned = [el for el in split if not el == "\n"]
+
+    section_nums = [i for i in range(len(cleaned)) if cleaned[i].startswith("#####")]
+
+    # Create dicts
+    help_all_dict = {}
+
+    # Select the section name and the contents of that section. Note, not all sections have content!
+    for i in range(len(section_nums)):
+        if not i == len(section_nums) - 1:
+            params = cleaned[section_nums[i] + 1 : section_nums[i + 1]]
+        else:
+            params = cleaned[section_nums[i] + 1 : len(cleaned)]
+        section_name = (
+            cleaned[section_nums[i]]
+            .lstrip("#####")
+            .strip()
+            .replace("Section ", "")
+            .lower()
+        )
+
+        #
+        params_dict = {}
+
+        if params:
+
+            # Clean it, replace in-text newlines with a space and then split on newlines.
+            split_params = params[0].strip().replace("\n ", " ").split("\n")
+
+            # Process params and descriptions per section
+            for el in split_params:
+                split_param_info = el.split(" : ")
+                if not len(split_param_info) == 3:
+                    # there are ocassions where the semicolon is used in the description text itself.
+                    if len(split_param_info) == 4:
+                        split_param_info = [
+                            split_param_info[0],
+                            ": ".join([split_param_info[1], split_param_info[2]]),
+                            split_param_info[3],
+                        ]
+
+                    # other occassions?
+
+                # Put the information in a dict
+                param_name = split_param_info[0]
+                param_description = split_param_info[1]
+                rest = split_param_info[2]
+
+                params_dict[param_name] = {
+                    "param_name": param_name,
+                    "description": param_description,
+                    "rest": rest,
+                }
+
+            # make section_dict
+            section_dict = {"section_name": section_name, "parameters": params_dict.copy()}
+
+            # Put in the total dict
+            help_all_dict[section_name] = section_dict.copy()
+
+    # Print things
+    if print_help:
+        for section in sorted(help_all_dict.keys()):
+            print(
+                "##################\n###### Section {}\n##################".format(
+                    section
+                )
+            )
+            section_dict = help_all_dict[section]
+            for param_name in sorted(section_dict["parameters"].keys()):
+                param = section_dict["parameters"][param_name]
+                print(
+                    "\n{}:\n\t{}: {}".format(
+                        param["param_name"], param["description"], param["rest"]
+                    )
+                )
+
+    # Loop over all the parameters an call the help() function on it. Takes a long time but this is for testing
+    # for section in help_all_dict.keys():
+    #     section_dict = help_all_dict[section]
+    #     for param in section_dict['parameters'].keys():
+    #         get_help(param)
+
+    if return_dict:
+        return help_all_dict
+    else:
+        return None
+
 
 def create_arg_string(arg_dict):
     """
@@ -17,11 +123,14 @@ def create_arg_string(arg_dict):
     return arg_string
 
 
-def get_defaults():
+def get_defaults(filter_values=False):
     """
     Function that calls the binaryc get args function and cast it into a dictionary
     All the values are strings
+    
+    filter_values: whether to filter out NULL and Function defaults.
     """
+
     default_output = binary_c_python_api.return_arglines()
     default_dict = {}
 
@@ -30,9 +139,15 @@ def get_defaults():
             key, value = default.split(" = ")
 
             # Filter out NULLS (not compiled anyway)
-            if not value in ["NULL", "Function"]:
-                if not value == "":
-                    default_dict[key] = value
+            if filter_values:
+                if not value in ["NULL", "Function"]:
+                    if not value == "":
+                        default_dict[key] = value
+
+            # On default, just show everything
+            else:
+                default_dict[key] = value
+
     return default_dict
 
 
@@ -118,8 +233,8 @@ 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]))
+        # for key in help_info_dict.keys():
+        #     print("{}:\n\t{}".format(key, help_info_dict[key]))
 
         if return_dict:
             return help_info_dict
@@ -133,7 +248,7 @@ def get_help(param_name, return_dict=False):
         return None
 
 
-get_help("RLOF_method")
+# get_help("RLOF_method")
 
 
 def run_system(**kwargs):
@@ -223,7 +338,7 @@ def run_system_with_log(**kwargs):
     output = binary_c_python_api.run_binary_with_logfile(arg_string)
 
     return output
-
+# run_system_with_log()
 
 def parse_output(output, selected_header):
     """
@@ -323,3 +438,4 @@ def load_logfile(logfile):
         event_list.append(" ".join(split_line[9:]))
 
     print(event_list)
+# load_logfile()
\ No newline at end of file
diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py
new file mode 100644
index 0000000000000000000000000000000000000000..57937bb401206325fe63905e21837f3c38db35a8
--- /dev/null
+++ b/binarycpython/utils/grid.py
@@ -0,0 +1,41 @@
+import binary_c_python_api
+
+from binarycpython.utils.functions import (
+    get_defaults,
+)
+
+import binarycpython
+
+
+class Population(object):
+    def __init__(self):
+        """
+        Lots of initialisation
+        """ 
+
+        self.defaults = get_defaults()
+        pass
+
+    def evolve(self):
+        pass
+
+    def evolve_single(self):
+        arg_string = "binary_c "
+        for param in self.defaults.keys():
+            print(param, self.defaults[param])
+            if self.defaults[param]=='':
+                print(self.defaults[param])
+
+            # arg_string += "{} {} ".format(param, self.defaults[param])
+
+        # arg_string = arg_string.strip()
+        out = binary_c_python_api.run_binary(arg_string)
+        print(out)
+        # print(  arg_string)
+
+
+test_pop = Population()
+
+# print(test_pop.defaults)
+
+test_pop.evolve_single()
\ No newline at end of file
diff --git a/examples/example_run_binary_with_custom_logging.py b/examples/example_run_binary_with_custom_logging.py
index 83ab013a0f8d5ac071eda126dfdabfa6b6cc3e9f..ac6cfc7b91f586f5528461c56b5202ca63691269 100644
--- a/examples/example_run_binary_with_custom_logging.py
+++ b/examples/example_run_binary_with_custom_logging.py
@@ -2,14 +2,14 @@ import ctypes
 import tempfile
 import os
 
-from binaryc_python_utils.custom_logging_functions import (
+from binarycpython.utils.custom_logging_functions import (
     autogen_C_logging_code,
     binary_c_log_code,
     compile_shared_lib,
     temp_custom_logging_dir,
     create_and_load_logging_function,
 )
-import binary_c
+import binary_c_python_api
 
 # generate logging lines
 logging_line = autogen_C_logging_code(
@@ -36,5 +36,5 @@ max_evolution_time = 15000
 argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g}".format(
     m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time
 )
-output = binary_c.run_binary_custom_logging(argstring, func_memaddr)
+output = binary_c_python_api.run_binary_custom_logging(argstring, func_memaddr)
 print(output)
diff --git a/include/binary_c_python.h b/include/binary_c_python.h
index e2a48e16ff80da443fec1cc16d992058306a888d..01aca72eac4bb71c4e0abfcb8ba4c4fa9c0cd61d 100644
--- a/include/binary_c_python.h
+++ b/include/binary_c_python.h
@@ -34,7 +34,9 @@ int return_help_info(char * argstring,
                 char ** const errorstring,
                 size_t * const nbytes);
 
-
+int return_help_all_info(char ** const outstring,
+                char ** const errorstring,
+                size_t * const nbytes);
 
 /* C macros */
 #define BINARY_C_APITEST_VERSION 0.1
diff --git a/src/binary_c_python.c b/src/binary_c_python.c
index bd0ffd741eb1dc558a9118a1b58333a705becd9c..726752d979131dbe451f28f51d71a8fdddebcf90 100644
--- a/src/binary_c_python.c
+++ b/src/binary_c_python.c
@@ -29,20 +29,26 @@ static char module_docstring[] MAYBE_UNUSED =
 static char create_binary_docstring[] =
     "Allocate memory for a binary";
 #endif
+static char function_prototype_docstring[] =
+    "The prototype for a binary_c python function";
+static char new_binary_system_docstring[] =
+    "Return an object containing a binary, ready for evolution";
+
+// Evolution function docstrings
 static char run_binary_docstring[] =
     "Run one binary using binary_c";
 static char run_binary_with_logdocstring[] =
     "Run one binary using binary_c and allow the logfile to be written. Do not use for populations!";
 static char run_binary_custom_loggingdocstring[] =
     "TODO";
-static char new_binary_system_docstring[] =
-    "Return an object containing a binary, ready for evolution";
-static char function_prototype_docstring[] =
-    "The prototype for a binary_c python function";
+
+// Utility function docstrings
 static char return_arglines_docstring[] =
     "Return the default args for a binary_c system";
 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 struct libbinary_c_store_t *store = NULL;
 
@@ -50,14 +56,18 @@ static struct libbinary_c_store_t *store = NULL;
 #ifdef __DEPRECATED
 static PyObject* binary_c_create_binary(PyObject *self, PyObject *args);
 #endif
+static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args);
+static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args);
+
+// Evolution function headers
 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_function_prototype(PyObject *self, PyObject *args);
-static PyObject* binary_c_new_binary_system(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);
 
 /*
  * Python 3 interface is described at
@@ -80,8 +90,10 @@ static PyMethodDef module_methods[] = {
     {"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},
+
     {"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},
     
     {NULL, NULL, 0, NULL}
 };
@@ -92,8 +104,8 @@ static PyMethodDef module_methods[] = {
 static struct PyModuleDef Py_binary_c_python_api =
 {
     PyModuleDef_HEAD_INIT,
-    "binary_c", /* name of module */
-    "binary_c docs",          /* module documentation, may be NULL */
+    "binary_c_python_api", /* name of module */
+    "binary_c_python_api docs",          /* module documentation, may be NULL */
     -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
     module_methods
 };
@@ -187,6 +199,22 @@ 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
+
+
+*/
+
+/* Wrappers to functions that evolve binary systems. */
+
 static PyObject* binary_c_run_binary(PyObject *self, PyObject *args)
 {
     /* Parse the input tuple */
@@ -310,6 +338,8 @@ static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args
     }
 }
 
+/* Wrappers to functions that call other API functionality like help and arglines*/
+
 static PyObject* binary_c_return_arglines(PyObject *self, PyObject *args)
 {
     char * buffer;
@@ -375,4 +405,40 @@ static PyObject* binary_c_return_help_info(PyObject *self, PyObject *args)
 
         return return_string;
     }
+}
+
+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;
+    int out MAYBE_UNUSED = return_help_all_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;
+    // }
 }
\ No newline at end of file
diff --git a/src/binary_c_python_api.c b/src/binary_c_python_api.c
index f8e1d11bfbee3350d982c320ab20a701a5871d08..10ab6147a27f35286c4c795f70b9aa3345cb51ab 100644
--- a/src/binary_c_python_api.c
+++ b/src/binary_c_python_api.c
@@ -45,6 +45,23 @@ static void capture_stdout(void);
 int out_pipe[2];
 int stdoutwas;
 
+/*
+Below are the real calls to the API of binary_c. Currently these are the functions:
+
+run_binary
+run_binary_custom_logging
+return_arglines
+run_binary_with_logfile
+return_help_info
+return_help_all_info
+
+
+*/
+
+
+
+/* Functions to evolve binary systems */
+
 int run_binary(char * argstring,
                char ** const buffer,
                char ** const error_buffer,
@@ -149,6 +166,48 @@ int run_binary_custom_logging(char * argstring,
     return 0;
 }
 
+int run_binary_with_logfile(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;
+
+    /* 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);
+    binary_c_free_store_contents(store);
+    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)
@@ -200,7 +259,8 @@ int return_arglines(char ** const buffer,
     return 0;
 }
 
-int run_binary_with_logfile(char * argstring,
+
+int return_help_info(char * argstring,
                char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes)
@@ -222,9 +282,8 @@ int run_binary_with_logfile(char * argstring,
     stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
     stardata->preferences->batchmode = BATCHMODE_LIBRARY;
 
-    /* do binary evolution */
-    binary_c_evolve_for_dt(stardata,
-                           stardata->model.max_evolution_time);
+    /* Ask the help api */
+    binary_c_help(stardata, argstring);
         
     /* get buffer pointer */
     binary_c_buffer_info(stardata,buffer,nbytes);
@@ -241,9 +300,7 @@ int run_binary_with_logfile(char * argstring,
     return 0;
 }
 
-
-int return_help_info(char * argstring,
-               char ** const buffer,
+int return_help_all_info(char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes)
 {
@@ -253,11 +310,12 @@ int return_help_info(char * argstring,
 
     /* make new stardata */
     stardata = NULL;
+    char * empty_str = "";
     binary_c_new_system(&stardata,
                         NULL,
                         NULL,
                         &store,
-                        &argstring,
+                        &empty_str,
                         -1);
 
     /* output to strings */
@@ -265,7 +323,7 @@ int return_help_info(char * argstring,
     stardata->preferences->batchmode = BATCHMODE_LIBRARY;
 
     /* Ask the help api */
-    binary_c_help(stardata, argstring);
+    binary_c_help_all(stardata);
         
     /* get buffer pointer */
     binary_c_buffer_info(stardata,buffer,nbytes);
diff --git a/tests/python_API_test.py b/tests/python_API_test.py
index e24a7906ee2bf516bd3d953d0969689b369ec8be..cc373d2a47be50c6583b7a521204c0ad372abf61 100755
--- a/tests/python_API_test.py
+++ b/tests/python_API_test.py
@@ -117,13 +117,21 @@ def test_run_binary_with_custom_logging():
     print(out)
 
 
+def test_return_help_all():
+    out = binary_c_python_api.return_help_all("M_1")
+    print(out)
+
+
 ####
-# test_run_binary()
+if __name__ == "__main__":
+    test_run_binary()
+
+    test_run_binary_with_log()
 
-# test_run_binary_with_log()
+    test_run_binary_with_custom_logging()
 
-# test_return_help()
+    test_return_help()
 
-# test_return_arglines()
+    test_return_arglines()
 
-# test_run_binary_with_custom_logging()
+    test_return_help_all()