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