From ab3c5d045045678075a8acbbb3e6ea4da362ce43 Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Wed, 5 May 2021 02:09:33 +0100
Subject: [PATCH] Added maximm mass ratio for rlof function

---
 include/binary_c_python.h |   5 ++
 src/binary_c_python.c     | 125 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/include/binary_c_python.h b/include/binary_c_python.h
index 8d0cfec88..be717c3b9 100644
--- a/include/binary_c_python.h
+++ b/include/binary_c_python.h
@@ -46,6 +46,11 @@ int return_minimum_orbit_for_RLOF(char * argstring,
                                     char ** const error_buffer,
                                     size_t * const nbytes);
 
+int return_maximum_mass_ratio_for_RLOF(char * argstring,
+                                   struct libbinary_c_store_t * store,
+                                   char ** buffer,
+                                   char ** error_buffer,
+                                   size_t * nbytes);
 
 /* =================================================================== */
 /* Functions to handle memory                                          */
diff --git a/src/binary_c_python.c b/src/binary_c_python.c
index a3d045e5b..c4df7d76b 100644
--- a/src/binary_c_python.c
+++ b/src/binary_c_python.c
@@ -84,6 +84,8 @@ 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";
+static char return_maximum_mass_ratio_for_RLOF_docstring[] = 
+    "Returns a string containing the maximum mass ratio for which a binary system does not RLOF at zams. Optionally accepts a store_capsule. 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[] = 
@@ -109,6 +111,7 @@ static PyObject* python_return_help_info(PyObject *self, PyObject *args);
 static PyObject* python_return_help_all_info(PyObject *self, PyObject *args);
 static PyObject* python_return_version_info(PyObject *self, PyObject *args);
 static PyObject* python_return_minimum_orbit_for_RLOF(PyObject *self, PyObject *args);
+static PyObject* python_return_maximum_mass_ratio_for_RLOF(PyObject *self, PyObject *args, PyObject *kwargs);
 
 // Other function headers
 static PyObject* python_return_store_memaddr(PyObject *self, PyObject *args);
@@ -119,8 +122,6 @@ static PyObject* python_free_persistent_data_memaddr_and_return_json_output(PyOb
 static PyObject* python_free_store_memaddr(PyObject *self, PyObject *args);
 static PyObject* python_test_func(PyObject *self, PyObject *args);
 
-
-
 /* Set the module functions */
 static PyMethodDef module_methods[] = {
     // Wierdly, this casting to a PyCFunction, which usually takes only 2 args, now works when giving keywords. See https://stackoverflow.com/q/10264080
@@ -132,6 +133,7 @@ static PyMethodDef module_methods[] = {
     {"return_help_all", python_return_help_all_info, METH_VARARGS, return_help_all_info_docstring},
     {"return_version_info", python_return_version_info, METH_VARARGS, return_version_info_docstring},
     {"return_minimum_orbit_for_RLOF", python_return_minimum_orbit_for_RLOF, METH_VARARGS, return_minimum_orbit_for_RLOF_docstring},
+    {"return_maximum_mass_ratio_for_RLOF", (PyCFunction)python_return_maximum_mass_ratio_for_RLOF, METH_VARARGS|METH_KEYWORDS, return_maximum_mass_ratio_for_RLOF_docstring},
 
     // memory
     {"return_store_memaddr", python_return_store_memaddr, METH_VARARGS, return_store_memaddr_docstring},
@@ -427,6 +429,124 @@ static PyObject* python_return_minimum_orbit_for_RLOF(PyObject *self, PyObject *
     return return_string;
 }
 
+static PyObject* python_return_maximum_mass_ratio_for_RLOF(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char* keywords[] = {"argstring", "store_capsule", NULL};
+
+    /* set vars and default values for some*/
+    char *argstring;
+    PyObject *  store_capsule = NULL;
+
+    /* Parse the input tuple */
+    // 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
+    if(!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O", keywords, &argstring, &store_capsule))
+    {
+        return NULL;
+    }
+
+    // Store
+    struct libbinary_c_store_t * store = NULL;
+    if (store_capsule != NULL)
+    {
+        if (PyCapsule_IsValid(store_capsule, "STORE"))
+        {
+            if (!(store = (struct libbinary_c_store_t *) PyCapsule_GetPointer(store_capsule, "STORE")))
+                return NULL;   
+            debug_printf("Unpacked store pointer %p from capsule\n", store_capsule);            
+        }
+    }
+
+    // Setup buffers
+    char * buffer;
+    char * error_buffer;
+    size_t nbytes;
+
+    /* Call c-function */
+    int out MAYBE_UNUSED = return_maximum_mass_ratio_for_RLOF(
+                                        argstring, // String containing the arguments for the system
+                                        store, // 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: python_return_maximum_mass_ratio_for_RLOF): %s\n",
+                error_buffer);
+    }
+
+    Safe_free(buffer);
+    Safe_free(error_buffer);
+
+    return return_string;
+}
+
+
+int return_maximum_mass_ratio_for_RLOF(char * argstring,
+                                   struct libbinary_c_store_t * store,
+                                   char ** buffer,
+                                   char ** error_buffer,
+                                   size_t * nbytes)
+{
+    /*
+     * Return the maximum mass ratio for RLOF given M1 and period
+     * If a valid store is passed in then we use it. otherwise a new store is made and released
+     */
+    struct libbinary_c_stardata_t *stardata = NULL;
+
+    /* Determine whether to free the store memory adress*/
+    Boolean free_store = FALSE;
+    if (store==NULL)
+    {
+        debug_printf("Decided to free the store memaddr\n");
+        free_store = TRUE;
+    }
+
+    binary_c_new_system(&stardata,
+                        NULL,
+                        NULL,
+                        &store,
+                        NULL,   
+                        &argstring,
+                        -1);
+
+    // Set preferences. 
+    stardata->preferences->show_maximum_mass_ratio_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);
+ 
+    Boolean free_persistent_data = TRUE;
+
+    /* 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
+    );
+
+    return 0;
+}
+
 /* ============================================================================== */
 /* Wrappers to functions that call other functionality */
 /* ============================================================================== */
@@ -685,7 +805,6 @@ int run_system(char * argstring,
         free_persistent_data = TRUE;
     }
 
-
     /* Set up new system */
     binary_c_new_system(&stardata,          // stardata
                         NULL,               // previous_stardatas
-- 
GitLab