diff --git a/.gitignore b/.gitignore
index fb6fe1a54857dc31d06c5c6993e83f8c6c7e674e..01bbdec15361e059fe5f09ff34d7811ab440355f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,7 @@ snippets/
 make_output.txt
 tests/population/scaling/scaling_plots/*
 tests/population/scaling/scaling_results/*
-
+tests/json*
 docs/build/*
 
 
diff --git a/include/binary_c_python.h b/include/binary_c_python.h
index d6dac96fbf9d7f74dd737294495f8abd182e89cf..99aeeeb371f12dbd69166455ec294e1a8b10ae5c 100644
--- a/include/binary_c_python.h
+++ b/include/binary_c_python.h
@@ -42,16 +42,19 @@ int return_version_info(char ** const outstring,
                 char ** const errorstring,
                 size_t * const nbytes);
 
-
 /* =================================================================== */
 /* Functions to call other functionality                               */
 /* =================================================================== */
-long int return_store_memaddr(char * argstring, // TODO can we do this without argstring?
-               char ** const buffer,
+
+long int return_store_memaddr(char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes);
+
+long int return_persistent_data_memaddr(char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes);
 
-long int return_persistent_data_memaddr(char * argstring, // TODO can we do this without argstring?
+int free_persistent_data_memaddr_and_return_json_output(long int persistent_data_memaddr,
                char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes);
diff --git a/src/binary_c_python.c b/src/binary_c_python.c
index ef19fdfd08cdaa24d7afb05b8e569e958a6ffd03..6a45e8db7c64c6bb7b2fe49d1b76aa72719037b9 100644
--- a/src/binary_c_python.c
+++ b/src/binary_c_python.c
@@ -61,6 +61,11 @@ static char return_store_memaddr_docstring[] =
 static char return_persistent_data_memaddr_docstring[] = 
     "Return the store memory adress that will be passed to run_population";
 
+static char free_persistent_data_memaddr_and_return_json_output_docstring[] = 
+    "Frees the persistent_data memory and returns the json output";
+
+
+
 static struct libbinary_c_store_t *store = NULL;
 
 /* Initialize pyobjects */
@@ -84,7 +89,8 @@ static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args);
 static PyObject* binary_c_return_store_memaddr(PyObject *self, PyObject *args);
 static PyObject* binary_c_return_persistent_data_memaddr(PyObject *self, PyObject *args);
 
-
+// Free functions
+static PyObject* binary_c_free_persistent_data_memaddr_and_return_json_output(PyObject *self, PyObject *args);
 
 /* Set the module functions */
 static PyMethodDef module_methods[] = {
@@ -107,7 +113,8 @@ static PyMethodDef module_methods[] = {
     {"return_version_info", binary_c_return_version_info, METH_VARARGS, return_version_info_docstring},
 
     {"return_store_memaddr", binary_c_return_store_memaddr, METH_VARARGS, return_store_memaddr_docstring},
-    {"return_persistent_data_memaddr", binary_c_return_persistent_data_memaddr, METH_VARARGS, return_persistent_data_memaddr_docstring},
+    {"return_persistent_data_memaddr", binary_c_return_persistent_data_memaddr, METH_NOARGS, return_persistent_data_memaddr_docstring},
+    {"free_persistent_data_memaddr_and_return_json_output", binary_c_free_persistent_data_memaddr_and_return_json_output, METH_VARARGS, free_persistent_data_memaddr_and_return_json_output_docstring},
 
     {NULL, NULL, 0, NULL}
 };
@@ -238,7 +245,7 @@ static PyObject* binary_c_run_system(PyObject *self, PyObject *args, PyObject *k
         return NULL;
     }
 
-    printf("Input persistent_Data_memaddr: %lu\n", persistent_data_memaddr);
+    // printf("Input persistent_Data_memaddr: %lu\n", persistent_data_memaddr);
 
     /* Call c-function */
     char * buffer;
@@ -398,19 +405,10 @@ static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args)
 
 static PyObject* binary_c_return_store_memaddr(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_memaddr(argstring,
-                                      &buffer,
+    long int out MAYBE_UNUSED = return_store_memaddr(&buffer,
                                       &error_buffer,
                                       &nbytes);
 
@@ -437,20 +435,10 @@ static PyObject* binary_c_return_store_memaddr(PyObject *self, PyObject *args)
 static PyObject* binary_c_return_persistent_data_memaddr(PyObject *self, PyObject *args)
 {
     /* Python binding that wraps the c function which calls the binary_c api endpoint. */
-
-    /* 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_persistent_data_memaddr(argstring,
-                                      &buffer,
+    long int out MAYBE_UNUSED = return_persistent_data_memaddr(&buffer,
                                       &error_buffer,
                                       &nbytes);
 
@@ -513,40 +501,42 @@ static PyObject* binary_c_return_persistent_data_memaddr(PyObject *self, PyObjec
 //     return 0;
 // }
 
-// static PyObject* binary_c_free_persistent_data_memaddr(PyObject *self, PyObject *args)
-// {
-//     /* Python binding that calls the c function that free's the store memory */
 
-//     /* Parse the input tuple */
-//     char *persistent_data_memaddr;
-    
-//     if(!PyArg_ParseTuple(args, "l", &persistent_data_memaddr))
-//     {
-//         return NULL;
-//     }
 
-//     char * buffer;
-//     char * error_buffer;
-//     size_t nbytes;
+static PyObject* binary_c_free_persistent_data_memaddr_and_return_json_output(PyObject *self, PyObject *args)
+{
+    /* Python binding that calls the c function that free's the store memory */
 
-//     long int out MAYBE_UNUSED = free_persistent_data_memaddr(persistent_data_memaddr,
-//                                       &buffer,
-//                                       &error_buffer,
-//                                       &nbytes);
+    /* Parse the input tuple */
+    long int persistent_data_memaddr = -1;
 
-//     /* copy the buffer to a python string */
-//     PyObject * return_string MAYBE_UNUSED = Py_BuildValue("s", buffer);
-//     PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
+    if(!PyArg_ParseTuple(args, "l", &persistent_data_memaddr))
+    {
+        return NULL;
+    }
 
-//     if(error_buffer != NULL && strlen(error_buffer)>0)
-//     {
-//         fprintf(stderr,
-//                 "Error in binary_c run : %s\n",
-//                 error_buffer);
-//     }
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+
+    long int out MAYBE_UNUSED = free_persistent_data_memaddr_and_return_json_output(persistent_data_memaddr,
+                                      &buffer,
+                                      &error_buffer,
+                                      &nbytes);
+
+    /* copy the buffer to a python string */
+    PyObject * return_string MAYBE_UNUSED = 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);
+    Safe_free(buffer);
+    Safe_free(error_buffer);
 
-//     return 0;
-// }
+    return return_string;
+}
diff --git a/src/binary_c_python_api.c b/src/binary_c_python_api.c
index 0b62a67d824810fc1070132efdbf26a6cee67553..50b9f2fdeb1f4d0840222761b9966f48fbc92ff3 100644
--- a/src/binary_c_python_api.c
+++ b/src/binary_c_python_api.c
@@ -57,11 +57,11 @@ int run_system(char * argstring,
                size_t * const nbytes)
 {
     /* memory for system */
-    struct libbinary_c_stardata_t *stardata;
+    struct libbinary_c_stardata_t *stardata = NULL;
 
     // Store:
     /* Check the value of the store_memaddr */
-    struct libbinary_c_store_t * store;
+    struct libbinary_c_store_t *store;
     if(store_memaddr != -1)
     {
         // load the store from the integer that has been passed
@@ -79,14 +79,15 @@ int run_system(char * argstring,
     {
         // load the persistent data from the long int that has been passed
         persistent_data = (void*)persistent_data_memaddr;
+        printf("Took long int memaddr %ld and loaded it to %p\n", persistent_data_memaddr, (void*)&persistent_data);
     }
     else
     {
+        printf("persistent_data memory adress was -1, now setting it to NULL\n");
         persistent_data = NULL;
     }
 
-    /* make new stardata */
-    stardata = NULL;
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
@@ -125,10 +126,10 @@ int run_system(char * argstring,
                            stardata->model.max_evolution_time);
         
     /* get buffer pointer */
-    binary_c_buffer_info(stardata,buffer,nbytes);
+    binary_c_buffer_info(stardata, buffer, nbytes);
     
     /* get error buffer pointer */
-    binary_c_error_buffer(stardata,error_buffer);
+    binary_c_error_buffer(stardata, error_buffer);
 
     /* Determine whether to free the store memory adress*/
     Boolean free_store = FALSE;
@@ -141,6 +142,7 @@ int run_system(char * argstring,
     Boolean free_persistent_data = FALSE;
     if (persistent_data_memaddr == -1)
     {
+        printf("Decided to free the persistent_data memaddr\n");
         Boolean free_persistent_data = TRUE;
     }
 
@@ -150,7 +152,7 @@ int run_system(char * argstring,
         TRUE,                       // free_stardata
         free_store,                 // free_store
         FALSE,                      // free_raw_buffer
-        free_persistent_data        // free_persistent TODO: check if this is correct here
+        free_persistent_data        // free_persistent
     );
 
     return 0;
@@ -165,12 +167,11 @@ int return_arglines(char ** const buffer,
                size_t * const nbytes)
 {
     /* memory for N binary systems */
-    struct libbinary_c_stardata_t *stardata;
-    struct libbinary_c_store_t * store = NULL;
+    struct libbinary_c_stardata_t *stardata = NULL;
+    struct libbinary_c_store_t *store = NULL;
+    char *empty_str = "";
 
-    /* make new stardata */
-    stardata = NULL;
-    char * empty_str = "";
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
@@ -180,7 +181,6 @@ int return_arglines(char ** const buffer,
                         -1                  // argc
     );
 
-
     /* disable logging */
     snprintf(stardata->preferences->log_filename,
              STRING_LENGTH-1,
@@ -210,7 +210,7 @@ int return_arglines(char ** const buffer,
         TRUE,                       // free_stardata
         TRUE,                       // free_store
         FALSE,                      // free_raw_buffer
-        TRUE                        // free_persistent TODO: check if this is correct here
+        TRUE                        // free_persistent
     );
     
     return 0;
@@ -222,12 +222,10 @@ int return_help_info(char * argstring,
                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;
+    struct libbinary_c_stardata_t *stardata = NULL;
+    struct libbinary_c_store_t *store = NULL;
 
-    /* make new stardata */
-    stardata = NULL;
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
@@ -254,9 +252,9 @@ int return_help_info(char * argstring,
     binary_c_free_memory(&stardata, // Stardata
         TRUE,                       // free_preferences
         TRUE,                       // free_stardata
-        TRUE,                      // free_store
+        TRUE,                       // free_store
         FALSE,                      // free_raw_buffer
-        TRUE                        // free_persistent TODO: check if this is correct here
+        TRUE                        // free_persistent
     );
 
     return 0;
@@ -267,13 +265,11 @@ int return_help_all_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;
+    struct libbinary_c_stardata_t *stardata = NULL;
+    struct libbinary_c_store_t *store = NULL;
     char * empty_str = "";
+
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
@@ -300,9 +296,9 @@ int return_help_all_info(char ** const buffer,
     binary_c_free_memory(&stardata, // Stardata
         TRUE,                       // free_preferences
         TRUE,                       // free_stardata
-        TRUE,                      // free_store
+        TRUE,                       // free_store
         FALSE,                      // free_raw_buffer
-        TRUE                        // free_persistent TODO: check if this is correct here
+        TRUE                        // free_persistent
     );
 
     return 0;
@@ -313,13 +309,11 @@ 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_stardata_t *stardata = NULL;
     struct libbinary_c_store_t * store = NULL;
-
-    /* make new stardata */
-    stardata = NULL;
     char * empty_str = "";
+
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
@@ -358,27 +352,24 @@ int return_version_info(char ** const buffer,
 /* Functions to call other functionality                               */
 /* =================================================================== */
 
-long int return_store_memaddr(char * argstring,
-               char ** const buffer,
+long int return_store_memaddr(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_stardata_t * stardata = NULL;
     struct libbinary_c_store_t * store = NULL;
+    char * empty_str = "";
 
-    /* make new stardata */
-    stardata = NULL;
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
                         &store,             // store
                         NULL,               // persistent_data
-                        &argstring,         // argv
+                        &empty_str,         // argv
                         -1                  // argc
     );
 
-
     /* output to strings */
     // stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
     // stardata->preferences->batchmode = BATCHMODE_LIBRARY;
@@ -394,13 +385,13 @@ long int return_store_memaddr(char * argstring,
         TRUE,                       // free_preferences
         TRUE,                       // free_stardata
         FALSE,                      // free_store
-        FALSE,                      // free_raw_buffer: TODO: possibly we have to do this yes
-        TRUE                       // free_persistent
+        FALSE,                      // free_raw_buffer
+        TRUE                        // free_persistent
     );
 
     /* convert the pointer */ 
     uintptr_t store_memaddr_int = (uintptr_t)store; // C Version converting ptr to int
-    // printf("store is at address: %p\n", (void*)&store);
+    // printf("store is at address: %p \n", (void*)&store);
     // printf("store_memaddr_int: %ld\n", store_memaddr_int);
 
     /* Return the memaddr as an int */
@@ -408,25 +399,23 @@ long int return_store_memaddr(char * argstring,
 }
 
 
-long int return_persistent_data_memaddr(char * argstring,
-               char ** const buffer,
+long int return_persistent_data_memaddr(char ** const buffer,
                char ** const error_buffer,
                size_t * const nbytes)
 {
     /* Function to allocate the persistent_data_memaddr */
-
     struct libbinary_c_stardata_t *stardata = NULL;
     struct libbinary_c_store_t * store = NULL;
     struct libbinary_c_persistent_data_t * persistent_data = NULL; 
+    char * empty_str = "";
 
-    /* make new stardata */
-    stardata = NULL;
+    /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
                         NULL,               // preferences
                         &store,             // store
                         &persistent_data,   // persistent_data
-                        &argstring,         // argv
+                        &empty_str,         // argv
                         -1                  // argc
     );
 
@@ -438,15 +427,14 @@ long int return_persistent_data_memaddr(char * argstring,
         
     /* convert the pointer */
     uintptr_t persistent_data_memaddr_int = (uintptr_t)stardata->persistent_data; // C Version converting ptr to int
-    // printf("persistent_data is at address: %p\n", (void*)stardata->persistent_data);
-    // printf("persistent_data_memaddr_int: %lu\n", persistent_data_memaddr_int);
+    printf("persistent_data is at address: %p persistent_data_memaddr_int: %ld\n", (void*)&stardata->persistent_data, persistent_data_memaddr_int);
     
     /* free stardata (except the buffer) */
     binary_c_free_memory(&stardata, // Stardata
         TRUE,                       // free_preferences
         TRUE,                       // free_stardata
         TRUE,                       // free_store
-        FALSE,                      // free_raw_buffer: TODO: possibly we have to do this yes
+        FALSE,                      // free_raw_buffer
         FALSE                       // free_persistent
     );
 
@@ -454,19 +442,61 @@ long int return_persistent_data_memaddr(char * argstring,
     return persistent_data_memaddr_int;
 }
 
-// /* Memory freeing functions */
-// int free_store_memaddr(long int * store_memaddr,
-//                char ** const buffer,
-//                char ** const error_buffer,
-//                size_t * const nbytes)
-// {
+int free_persistent_data_memaddr_and_return_json_output(long int persistent_data_memaddr,
+               char ** const buffer,
+               char ** const error_buffer,
+               size_t * const nbytes)
+{
+    struct libbinary_c_store_t *store = NULL;
+    struct libbinary_c_stardata_t *stardata = NULL;
+    char * empty_str = "";
 
+    // persistent_data:
+    struct libbinary_c_persistent_data_t *persistent_data;
+    if(persistent_data_memaddr != -1)
+    {
+        // load the persistent data from the long int that has been passed
+        persistent_data = (void*)persistent_data_memaddr;
+        printf("Took long int memaddr %ld and loaded it to %p\n", persistent_data_memaddr, (void*)&persistent_data);
+    }
+    else
+    {
+        printf("ERROR: this function needs a valid persistent_data_memaddr value. not -1\n");
+        // persistent_data = NULL;
+        // TODO: put break in the function here. 
+    }
 
+    /* Set up new system */
+    binary_c_new_system(&stardata,          // stardata
+                        NULL,               // previous_stardatas
+                        NULL,               // preferences
+                        &store,             // store
+                        &persistent_data,   // persistent_data
+                        &empty_str,         // argv
+                        -1                  // argc
+    );
+
+    /* output to strings */
+    stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
+    stardata->preferences->batchmode = BATCHMODE_LIBRARY;
 
-//     return 0;
-// }
+    /* get output and free memory */
+    binary_c_output_to_json(stardata);
+
+    /* get buffer pointer */
+    binary_c_buffer_info(stardata, buffer, nbytes);
+    
+    /* get error buffer pointer */
+    binary_c_error_buffer(stardata, error_buffer);
 
-// int free_persistent_data_memaddr
-// {
+    /* free the reststardata (except the buffer) */
+    binary_c_free_memory(&stardata, // Stardata
+        TRUE,                       // free_preferences
+        TRUE,                       // free_stardata
+        TRUE,                       // free_store
+        FALSE,                      // free_raw_buffer
+        FALSE                       // free_persistent
+    );
 
-// }
+    return 0;
+}
diff --git a/tests/test_return_persistent_data_memaddr.py b/tests/test_return_persistent_data_memaddr.py
index cf0db984e0d59ec1c1013cf770d81c31888264db..ddd2adfaaf325e84c81305db42740c6effd6fa3b 100644
--- a/tests/test_return_persistent_data_memaddr.py
+++ b/tests/test_return_persistent_data_memaddr.py
@@ -1,7 +1,51 @@
-import binary_c_python_api
-import textwrap
+"""
+Module containing tests regarding the persistent_data memory and the ensemble output
+"""
+
+import time
+
 import json
+import textwrap
+import binary_c_python_api
+
+
+
+
+from mergedict import ConfigDict
+
+# import unicode
+
+class Decoder(json.JSONDecoder):
+    """
+    Custom decoder to transform the numbers that are strings to actual floats
+    """
+
+    def decode(self, s):
+        result = super().decode(s)  # result = super(Decoder, self).decode(s) for Python 2.x
+        return self._decode(result)
+
+    def _decode(self, o):
+        """
+        Depending on the type of object is will determine whether to loop over the elements,
+        or try to change the type of the object from string to float
 
+        The try except might be a somewhat rough solution but it catches all cases.
+        """
+
+
+        # Check if we can turn it into a float
+        # if isinstance(o, str) or isinstance(o, unicode):
+        if isinstance(o, str):
+            try:
+                return float(o)
+            except ValueError:
+                return o
+        elif isinstance(o, dict):
+            return {k: self._decode(v) for k, v in o.items()}
+        elif isinstance(o, list):
+            return [self._decode(v) for v in o]
+        else:
+            return o
 
 # Evolution functions
 def test_return_persistent_data_memaddr():
@@ -15,6 +59,7 @@ def test_passing_persistent_data_to_run_system():
     # Function to test the passing of the persistent data memoery adress, and having ensemble_defer = True
     # We should see that the results of multiple systems have been added to the one output json
 
+    # Some values
     m1 = 15.0  # Msun
     m2 = 14.0  # Msun
     separation = 0  # 0 = ignored, use period
@@ -23,37 +68,17 @@ def test_passing_persistent_data_to_run_system():
     metallicity = 0.02
     max_evolution_time = 15000
 
-    argstring_1 = "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} ensemble 1 ensemble_filters_off 1 ensemble_filter_SUPERNOVAE 1".format(
-        m1,
-        m2,
-        separation,
-        orbital_period,
-        eccentricity,
-        metallicity,
-        max_evolution_time,
-    )
+    # Make the argstrings
+    argstring_template = "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} ensemble 1 ensemble_defer {7}\
+    ensemble_filters_off 1 ensemble_filter_SUPERNOVAE 1 probability 0.1"
 
-    argstring_1_deferred = "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} ensemble 1 ensemble_defer 1 ensemble_filters_off 1 ensemble_filter_SUPERNOVAE 1".format(
-        m1,
-        m2,
-        separation,
-        orbital_period,
-        eccentricity,
-        metallicity,
-        max_evolution_time,
-    )
-    argstring2 = "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} ensemble 1 ensemble_filters_off 1 ensemble_filter_SUPERNOVAE 1".format(
-        m1+10,
-        m2,
-        separation,
-        orbital_period,
-        eccentricity,
-        metallicity,
-        max_evolution_time,
-    )
+    argstring_1 = argstring_template.format(m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "0")
+    argstring_1_deferred = argstring_template.format(m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "1")
+    argstring_2 = argstring_template.format(m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "0")
 
-    persistent_data_memaddr = binary_c_python_api.return_persistent_data_memaddr("")
-    # print(persistent_data_memaddr)
+    # 
+    persistent_data_memaddr = binary_c_python_api.return_persistent_data_memaddr()
 
     output_1 = binary_c_python_api.run_system(argstring=argstring_1)
     ensemble_jsons_1 = [line for line in output_1.splitlines() if line.startswith("ENSEMBLE_JSON")]
@@ -61,7 +86,7 @@ def test_passing_persistent_data_to_run_system():
 
     # Doing 2 systems in a row.
     output_1_deferred = binary_c_python_api.run_system(argstring=argstring_1_deferred, persistent_data_memaddr=persistent_data_memaddr)
-    output_2 = binary_c_python_api.run_system(argstring=argstring2, persistent_data_memaddr=persistent_data_memaddr)
+    output_2 = binary_c_python_api.run_system(argstring=argstring_2, persistent_data_memaddr=persistent_data_memaddr)
     ensemble_jsons_2 = [line for line in output_2.splitlines() if line.startswith("ENSEMBLE_JSON")]
     json_2 = json.loads(ensemble_jsons_2[0][len("ENSEMBLE_JSON "):])
 
@@ -78,9 +103,166 @@ def test_passing_persistent_data_to_run_system():
 
     # printf("combined double system vs deferred double system?:")
 
+def ensemble_output():
+
+    m1 = 15.0  # Msun
+    m2 = 14.0  # Msun
+    separation = 0  # 0 = ignored, use period
+    orbital_period = 453000000000.0  # days
+    eccentricity = 0.0
+    metallicity = 0.02
+    max_evolution_time = 15000
+
+    argstring_1 = "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} ensemble 1 ensemble_defer 0 ensemble_filters_off 1 ensemble_filter_SUPERNOVAE 1".format(
+        m1,
+        m2,
+        separation,
+        orbital_period,
+        eccentricity,
+        metallicity,
+        max_evolution_time,
+    )
+    output_1 = binary_c_python_api.run_system(argstring=argstring_1)
+    ensemble_jsons_1 = [line for line in output_1.splitlines() if line.startswith("ENSEMBLE_JSON")]
+
+    start = time.time()
+    json_1 = json.loads(ensemble_jsons_1[0][len("ENSEMBLE_JSON "):], cls=Decoder)
+    stop = time.time()
+
+    print(json.dumps(json_1, indent=4))
+    print("took {}s to decode".format(stop-start))
+
+def adding_ensemble_output():
+    m1 = 2  # Msun
+    m2 = 0.1  # Msun
+    separation = 0  # 0 = ignored, use period
+    orbital_period = 453000000.0  # days
+    eccentricity = 0.0
+    metallicity = 0.02
+    max_evolution_time = 15000
+
+    # Set up argstrings
+    argstring_template = "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} ensemble 1 ensemble_defer {7}\
+    ensemble_filters_off 1 ensemble_filter_STELLAR_TYPE_COUNTS 1 probability 0.1"
+
+    #############################################################################################
+    # The 2 runs below use the ensemble but do not defer the output to anything else, so that the
+    # results are returned directly after the run
+
+    # Direct output commands
+    argstring_1 = argstring_template.format(
+        m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "0")
+    argstring_2 = argstring_template.format(
+        m1+1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "0")
+
+    # Get outputs
+    output_1 = binary_c_python_api.run_system(argstring=argstring_1)
+    output_2 = binary_c_python_api.run_system(argstring=argstring_2)
+
+    ensemble_jsons_1 = [line for line in output_1.splitlines() if line.startswith("ENSEMBLE_JSON")]
+    ensemble_jsons_2 = [line for line in output_2.splitlines() if line.startswith("ENSEMBLE_JSON")]
+
+    json_1 = json.loads(ensemble_jsons_1[0][len("ENSEMBLE_JSON "):], cls=Decoder)
+    json_2 = json.loads(ensemble_jsons_2[0][len("ENSEMBLE_JSON "):], cls=Decoder)
+
+    with open("json_1.json", 'w') as f:
+        f.write(json.dumps(json_1, indent=4))
+    with open("json_2.json", 'w') as f:
+        f.write(json.dumps(json_2, indent=4))
+
+    print("Single runs done\n")
+
+    #############################################################################################
+    # The 2 runs below use the ensemble and both defer the output so that after they are finished
+    # nothing is printed. After that we explicitly free the memory of the persistent_data and 
+    # have the output returned in that way
+
+    # Deferred commands
+    argstring_1_deferred = argstring_template.format(
+        m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "1")
+    argstring_2_deferred = argstring_template.format(
+        m1+1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "1")
+
+    # Get a memory location
+    persistent_data_memaddr = binary_c_python_api.return_persistent_data_memaddr()
+
+    # Run the systems and defer the output each time
+    output_1_deferred = binary_c_python_api.run_system(argstring=argstring_1_deferred, persistent_data_memaddr=persistent_data_memaddr)
+    output_2_deferred = binary_c_python_api.run_system(argstring=argstring_2_deferred, persistent_data_memaddr=persistent_data_memaddr)
+
+    # Have the persistent_memory adress be released and have the json outputted
+    output_total_deferred = binary_c_python_api.free_persistent_data_memaddr_and_return_json_output(persistent_data_memaddr)
+
+    ensemble_jsons_deferred = [line for line in output_total_deferred.splitlines() if line.startswith("ENSEMBLE_JSON")]
+
+    json_deferred = json.loads(ensemble_jsons_deferred[0][len("ENSEMBLE_JSON "):], cls=Decoder)
+
+    with open("json_deferred.json", 'w') as f:
+        f.write(json.dumps(json_deferred, indent=4))
+
+    print("Double deferred done\n")
+
+    #############################################################################################
+    # The 2 runs below use the ensemble and the first one defers the output to the memory,
+    # Then the second one uses that memory to combine its results with, but doesn't defer the 
+    # data after that, so it will print it after the second run is done
+
+    persistent_data_memaddr_2 = binary_c_python_api.return_persistent_data_memaddr()
+
+    # Run the systems and defer the output once and the second time not, so that the second run automatically prints out the results
+    output_1_deferred = binary_c_python_api.run_system(argstring=argstring_1_deferred, persistent_data_memaddr=persistent_data_memaddr_2)
+    output_2_deferred_and_output = binary_c_python_api.run_system(argstring=argstring_2, persistent_data_memaddr=persistent_data_memaddr_2)
+
+    ensemble_jsons_deferred_and_output = [line for line in output_2_deferred_and_output.splitlines() if line.startswith("ENSEMBLE_JSON")]
+
+    json_deferred_and_output = json.loads(ensemble_jsons_deferred_and_output[0][len("ENSEMBLE_JSON "):], cls=Decoder)
+
+    with open("json_deferred_and_output.json", 'w') as f:
+        f.write(json.dumps(json_deferred_and_output, indent=4))
+
+    print("Single deferred done\n")
+
+def test_free_and_json_output():
+    m1 = 2  # Msun
+    m2 = 0.1  # Msun
+    separation = 0  # 0 = ignored, use period
+    orbital_period = 453000000000.0  # days
+    eccentricity = 0.0
+    metallicity = 0.02
+    max_evolution_time = 15000
+
+    # Get a memory adress:
+    persistent_data_memaddr = binary_c_python_api.return_persistent_data_memaddr("")
+
+    # Set up argstrings
+    argstring_template = "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} ensemble 1 ensemble_defer {7}\
+    ensemble_filters_off 1 ensemble_filter_STELLAR_TYPE_COUNTS 1 probability 0.1"
+    argstring_1 = argstring_template.format(
+        m1, m2, separation, orbital_period, eccentricity, metallicity, max_evolution_time, "1")
+
+    print("evolving")
+    output_1_deferred = binary_c_python_api.run_system(argstring=argstring_1, persistent_data_memaddr=persistent_data_memaddr)
+    print("Evolved")
+    print("Output:")
+    print(textwrap.indent(str(output_1_deferred), "\t"))
+
+    print("freeing")
+    json_output_by_freeing = binary_c_python_api.free_persistent_data_memaddr_and_return_json_output(persistent_data_memaddr)
+    print("Freed")
+    print("Output:")
+    print(textwrap.indent(str(json_output_by_freeing), "\t"))
 
 
 ####
 if __name__ == "__main__":
-    test_return_persistent_data_memaddr()
-    test_passing_persistent_data_to_run_system()
+    # test_return_persistent_data_memaddr()
+    # test_passing_persistent_data_to_run_system()
+    # ensemble_output()
+    adding_ensemble_output()
+
+
+
+
+    # test_free_and_json_output()
\ No newline at end of file