From ab7bf5fdd952e4cb6491b7176688a9b15d196a1c Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Sat, 6 Feb 2021 21:11:02 +0000
Subject: [PATCH] added function to get the minimum period and sep for rlof.
 Next up is adding the wrapper functions and making tests, as well as doing
 max mass ratio api call

---
 include/binary_c_python.h |   8 +++
 src/binary_c_python.c     | 141 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/include/binary_c_python.h b/include/binary_c_python.h
index 333a5d303..c66ae41f2 100644
--- a/include/binary_c_python.h
+++ b/include/binary_c_python.h
@@ -39,6 +39,14 @@ int return_version_info(char ** const outstring,
                 char ** const errorstring,
                 size_t * const nbytes);
 
+
+int return_minimum_orbit_for_RLOF(char * argstring,
+                                   long int store_memaddr,
+                                    char ** const buffer,
+                                    char ** const error_buffer,
+                                    size_t * const nbytes);
+
+
 /* =================================================================== */
 /* Functions to handle memory                                          */
 /* =================================================================== */
diff --git a/src/binary_c_python.c b/src/binary_c_python.c
index 443f4cbe6..b3531727f 100644
--- a/src/binary_c_python.c
+++ b/src/binary_c_python.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <string.h>
 
 /*
  * binary_c/PYTHON API interface functions
@@ -81,6 +82,8 @@ 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";
+static char return_minimum_orbit_for_RLOF_docstring[] = 
+    "Returns a string containing the minimum orbit and separation for which a binary system does not RLOF at zams. Please use the wrapper functions in utils for this except when you know what you're doing";
 
 // other functionality
 static char return_store_memaddr_docstring[] = 
@@ -105,6 +108,7 @@ 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);
+static PyObject* binary_c_return_minimum_orbit_for_RLOF(PyObject *self, PyObject *args);
 
 // Other function headers
 static PyObject* binary_c_return_store_memaddr(PyObject *self, PyObject *args);
@@ -127,14 +131,17 @@ static PyMethodDef module_methods[] = {
     {"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_minimum_orbit_for_RLOF", binary_c_return_minimum_orbit_for_RLOF, METH_VARARGS, return_minimum_orbit_for_RLOF_docstring},
 
-    //
+    // memory
     {"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_NOARGS, return_persistent_data_memaddr_docstring},
 
-    //
+    // freeing
     {"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},
     {"free_store_memaddr", binary_c_free_store_memaddr, METH_VARARGS, free_store_memaddr_docstring},
+
+    // dummy function
     {"test_func", binary_c_test_func, METH_NOARGS, test_func_docstring},
 
     //
@@ -166,6 +173,7 @@ PyMODINIT_FUNC PyInit__binary_c_bindings(void)
 /* ============================================================================== */
 
 /*
+    TODO: update this list
     Below are the real functions:
     binary_c_run_population
     binary_c_run_system
@@ -351,6 +359,49 @@ static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args)
     return return_string;
 }
 
+static PyObject* binary_c_return_minimum_orbit_for_RLOF(PyObject *self, PyObject *args)
+{
+    /* set vars and default values for some */
+    char *argstring;
+    long int store_memaddr = -1;
+
+    // By using the keywords argument it scans over the given set of kwargs, but if they are not given then the default value is used
+    /* Parse the input tuple */
+    if(!PyArg_ParseTuple(args, "sl", &argstring, &store_memaddr))
+    {
+        return NULL;
+    }
+
+    // Setup buffers
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+
+    /* Call c-function */
+    int out MAYBE_UNUSED = return_minimum_orbit_for_RLOF(
+                                        argstring, // String containing the arguments for the system
+                                        store_memaddr, // value for 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 function: binary_c_return_minimum_orbit_for_RLOF): %s\n",
+                error_buffer);
+    }
+
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    return return_string;
+}
+
 /* ============================================================================== */
 /* Wrappers to functions that call other functionality */
 /* ============================================================================== */
@@ -375,6 +426,8 @@ static PyObject* binary_c_return_store_memaddr(PyObject *self, PyObject *args)
         fprintf(stderr,
                 "Error (in function: binary_c_return_store_memaddr): %s\n",
                 error_buffer);
+        printf("Error (in function: binary_c_return_store_memaddr): %s\n",
+                error_buffer);
     }
     
     Safe_free(buffer);
@@ -405,6 +458,8 @@ static PyObject* binary_c_return_persistent_data_memaddr(PyObject *self, PyObjec
         fprintf(stderr,
                 "Error (in function: binary_c_return_persistent_data_memaddr): %s\n",
                 error_buffer);
+        printf("Error (in function: binary_c_return_persistent_data_memaddr): %s\n",
+                error_buffer);
     }
     
     Safe_free(buffer);
@@ -444,6 +499,8 @@ static PyObject* binary_c_free_persistent_data_memaddr_and_return_json_output(Py
         fprintf(stderr,
                 "Error (in function: binary_c_free_persistent_data_memaddr_and_return_json_output): %s\n",
                 error_buffer);
+        printf("Error (in function: binary_c_free_persistent_data_memaddr_and_return_json_output): %s\n",
+                error_buffer);
     }
     
     Safe_free(buffer);
@@ -462,6 +519,7 @@ static PyObject* binary_c_free_store_memaddr(PyObject *self, PyObject *args)
     {
         fprintf(stderr,
                 "Error (in function: binary_c_free_store_memaddr): Got a bad input\n");
+        printf("Error (in function: binary_c_free_store_memaddr): Got a bad input\n");
         return NULL;
     }
 
@@ -483,6 +541,8 @@ static PyObject* binary_c_free_store_memaddr(PyObject *self, PyObject *args)
         fprintf(stderr,
                 "Error (in function: binary_c_free_store_memaddr): %s\n",
                 error_buffer);
+        printf("Error (in function: binary_c_free_store_memaddr): %s\n",
+                error_buffer);
     }
     
     Safe_free(buffer);
@@ -523,6 +583,7 @@ static PyObject* binary_c_test_func(PyObject *self, PyObject *args)
  * return_help_info
  * return_help_all_info
  * return_version_info
+ * return_minimum_orbit_for_RLOF
 
  * // memory allocating functions:
  * return_store_memaddr
@@ -857,6 +918,82 @@ int return_version_info(char ** const buffer,
     return 0;
 }
 
+int return_minimum_orbit_for_RLOF(char * argstring,
+                                   long int store_memaddr,
+                                   char ** buffer,
+                                   char ** error_buffer,
+                                   size_t * nbytes)
+{
+    /*
+     * Return the binary_c minimum orbit (separation or period)
+     * that leads to RLOF 
+     */
+
+    /* memory for system */
+    struct libbinary_c_stardata_t *stardata = NULL;
+
+    // Store:
+    /* Check the value of the store_memaddr */
+    struct libbinary_c_store_t *store;
+    if(store_memaddr != -1)
+    {
+        // load the store from the integer that has been passed
+        store = (void*)store_memaddr;
+    }
+    else
+    {
+        // struct libbinary_c_store_t * store = NULL;
+        store = NULL;
+    }
+        
+    binary_c_new_system(&stardata,
+                        NULL,
+                        NULL,
+                        &store,
+                        NULL,   
+                        &argstring,
+                        -1);
+
+    // Set preferences. 
+    stardata->preferences->show_minimum_separation_for_instant_RLOF = TRUE;
+    stardata->preferences->show_minimum_orbital_period_for_instant_RLOF = TRUE;
+    snprintf(stardata->preferences->log_filename,
+             STRING_LENGTH-1,"%s","/dev/null");
+    snprintf(stardata->preferences->api_log_filename_prefix,
+             STRING_LENGTH-1,"%s","/dev/null");
+    stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE;
+    stardata->preferences->batchmode = BATCHMODE_LIBRARY;
+
+    /* Actually show the instant_rlof */
+    binary_c_show_instant_RLOF(stardata); // prints to the buffer. 
+
+    /* put results in buffer */
+    binary_c_buffer_info(stardata, buffer, nbytes);
+
+    /* Put errors in error buffer */
+    binary_c_error_buffer(stardata, error_buffer);
+ 
+    /* Determine whether to free the store memory adress*/
+    Boolean free_store = FALSE;
+    if (store_memaddr == -1)
+    {
+        debug_printf("Decided to free the store memaddr\n");
+        free_store = TRUE;
+    }
+    Boolean free_persistent_data = FALSE;
+
+    /* free stardata (except the buffer) */
+    binary_c_free_memory(&stardata, // Stardata
+        TRUE,                       // free_preferences
+        TRUE,                       // free_stardata
+        free_store,                 // free_store
+        FALSE,                      // free_raw_buffer TODO: fix this
+        free_persistent_data        // free_persistent // TODO FIX THIS.
+    );
+
+    return 0;
+}
+
 /* =================================================================== */
 /* Functions to set up memory                                          */
 /* =================================================================== */
-- 
GitLab