From 0b646fdfa9a45b4a707344eab1a63451d24680be Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Sun, 8 Aug 2021 18:19:09 +0100
Subject: [PATCH] updated notebook for population

---
 binarycpython/utils/grid.py        |  41 ++-
 examples/notebook_population.ipynb | 535 ++++++++++-------------------
 2 files changed, 196 insertions(+), 380 deletions(-)

diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py
index 0d35b58d5..42ef3cd49 100644
--- a/binarycpython/utils/grid.py
+++ b/binarycpython/utils/grid.py
@@ -240,6 +240,7 @@ class Population:
                     1,
                 )
                 self.custom_options[key] = kwargs[key]
+
     def parse_cmdline(self) -> None:
         """
         Function to handle settings values via the command line.
@@ -347,7 +348,7 @@ class Population:
         argline = argline.strip()
         return argline
 
-    def last_grid_variable(self):
+    def _last_grid_variable(self):
         """
         Function that returns the last grid variable
         (i.e. the one with the highest grid_variable_number)
@@ -362,6 +363,7 @@ class Population:
                 == number - 1
             ):
                 return grid_variable
+
     def add_grid_variable(
         self,
         name: str,
@@ -498,7 +500,7 @@ class Population:
 
         return options
 
-    def _return_binary_c_version_info(self, parsed=False):
+    def return_binary_c_version_info(self, parsed=False):
         """
         Function that returns the version information of binary_c
         """
@@ -507,7 +509,7 @@ class Population:
 
         return version_info
 
-    def _return_binary_c_defaults(self):
+    def return_binary_c_defaults(self):
         """
         Function that returns the defaults of the binary_c version that is used.
         """
@@ -551,7 +553,7 @@ class Population:
 
         #
         if include_binary_c_defaults:
-            binary_c_defaults = self._return_binary_c_defaults()
+            binary_c_defaults = self.return_binary_c_defaults()
             all_info["binary_c_defaults"] = binary_c_defaults
 
         if include_binary_c_version_info:
@@ -765,7 +767,7 @@ class Population:
             self._condor_grid()
         else:
             # Execute population evolution subroutines
-            self.evolve_population()
+            self._evolve_population()
 
         # Put all interesting stuff in a variable and output that afterwards, as analytics of the run.
         analytics_dict = {
@@ -796,7 +798,7 @@ class Population:
 
         return analytics_dict
 
-    def evolve_population(self):
+    def _evolve_population(self):
         """
         Function to evolve populations. This handles the setting up, evolving
         and cleaning up of a population of stars.
@@ -887,7 +889,7 @@ class Population:
                 0,
             )
 
-    def get_stream_logger(self, level=logging.DEBUG):
+    def _get_stream_logger(self, level=logging.DEBUG):
         """Return logger with configured StreamHandler."""
         stream_logger = logging.getLogger("stream_logger")
         stream_logger.handlers = []
@@ -901,7 +903,7 @@ class Population:
 
         return stream_logger
 
-    def system_queue_filler(self, job_queue, amt_cores):
+    def _system_queue_filler(self, job_queue, amt_cores):
         """
         Function that is responsible for keeping the queue filled.
 
@@ -909,7 +911,7 @@ class Population:
         Will have to play with the size of this.
         """
 
-        stream_logger = self.get_stream_logger()
+        stream_logger = self._get_stream_logger()
         if self.grid_options['verbosity'] >= _LOGGER_VERBOSITY_LEVEL:
             stream_logger.debug(f"setting up the system_queue_filler now")
 
@@ -1025,7 +1027,7 @@ class Population:
             p.start()
 
         # Set up the system_queue
-        self.system_queue_filler(job_queue, amt_cores=self.grid_options["amt_cores"])
+        self._system_queue_filler(job_queue, amt_cores=self.grid_options["amt_cores"])
 
         # Join the processes
         for p in processes:
@@ -1095,6 +1097,7 @@ class Population:
             "_total_probability_weighted_mass_run"
         ] = combined_output_dict["_total_probability_weighted_mass_run"]
         self.grid_options['_zero_prob_stars_skipped'] = combined_output_dict['_zero_prob_stars_skipped']
+
     def _evolve_system_mp(self, full_system_dict):
         """
         Function that the multiprocessing evolution method calls to evolve a system
@@ -1147,7 +1150,7 @@ class Population:
             ID  # Store the ID as a object property again, lets see if that works.
         )
 
-        stream_logger = self.get_stream_logger()
+        stream_logger = self._get_stream_logger()
         if self.grid_options['verbosity'] >= _LOGGER_VERBOSITY_LEVEL:
             stream_logger.debug(f"Setting up processor: process-{self.process_ID}")
 
@@ -3015,6 +3018,9 @@ class Population:
             output_dir: (optional, default = None) directory where to write the file to. If custom_options['data_dir'] is present, then that one will be used first, and then the output_dir
             output_filename: (optional, default = None) filename of the output. If not set it will be called "binary_c_calls.txt"
             include_defaults: (optional, default = None) whether to include the defaults of binary_c in the lines that are written. Beware that this will result in very long lines, and it might be better to just export the binary_c defaults and keep them in a separate file.
+
+        Returns:
+            filename: filename that was used to write the calls to
         """
 
         # Check if there is no compiled grid yet. If not, lets try to build it first.
@@ -3089,6 +3095,10 @@ class Population:
             print("Error. No grid function found!")
             raise ValueError
 
+
+        return binary_c_calls_full_filename
+
+
     def _cleanup_defaults(self):
         """
         Function to clean up the default values:
@@ -3103,7 +3113,7 @@ class Population:
         TODO: Rethink this functionality. seems a bit double, could also be just outside of the class
         """
 
-        binary_c_defaults = self._return_binary_c_defaults().copy()
+        binary_c_defaults = self.return_binary_c_defaults().copy()
         cleaned_dict = filter_arg_dict(binary_c_defaults)
 
         return cleaned_dict
@@ -3901,15 +3911,10 @@ eccentricity3=0
         )
 
         # and finally the probability calculator
-        self.grid_options["_grid_variables"][self.last_grid_variable()][
+        self.grid_options["_grid_variables"][self._last_grid_variable()][
             "probdist"
         ] = probdist_addition
 
-        # Add the options to the grid
-        # self.grid_options["_grid_variables"][self.last_grid_variable()][
-        #     "precode"
-        # ] += "; self.grid_options['m&s_ensemble_options'] = {}".format(o)
-
         verbose_print(
             "\tMoe_di_Stefano_2017: Added final call to the pdf function",
             self.grid_options["verbosity"],
diff --git a/examples/notebook_population.ipynb b/examples/notebook_population.ipynb
index 1e21fe3a8..47a43d442 100644
--- a/examples/notebook_population.ipynb
+++ b/examples/notebook_population.ipynb
@@ -15,7 +15,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 1,
    "id": "bf6b8673-a2b5-4b50-ad1b-e90671f57470",
    "metadata": {},
    "outputs": [],
@@ -32,9 +32,6 @@
    "id": "a081ab23-7822-4971-aa82-991548534714",
    "metadata": {},
    "source": [
-    "- adding custom logging\n",
-    "- setting up a parse function\n",
-    "\n",
     "- running ensemble\n",
     "- using the output\n",
     "- using M&S grid"
@@ -49,16 +46,16 @@
     "To set up and configure the population object we need to make an object instance of the `Population` object, and add configuration via the `.set()` function.\n",
     "\n",
     "There are three categories of options that the Population object can set:\n",
-    "- BSE options: these options will be used for the binary_c calls, and are recognized by comparing the arguments to a known list of available arguments of binary_c. To see which options are available, see section `binary_c parameters` in the documentation. You can access these through `population.bse_options['<bse option name>']` after you have set them. \n",
+    "- BSE options: these options will be used for the binary_c calls, and are recognized by comparing the arguments to a known list of available arguments of binary_c. To see which options are available, see section [`binary_c parameters` in the documentation](https://ri0005.pages.surrey.ac.uk/binary_c-python/binary_c_parameters.html). You can access these through `population.bse_options['<bse option name>']` after you have set them. \n",
     "\n",
-    "- Grid options: these options will be used to configure the behaviour of the Population object. To see which options are available, see section `Population grid code options` in the documentation. They can be accessed via `population.grid_options['<grid option name>']` after you have set them. \n",
+    "- Grid options: these options will be used to configure the behaviour of the Population object. To see which options are available, see section [`Population grid code options` in the documentation](https://ri0005.pages.surrey.ac.uk/binary_c-python/grid_options_descriptions.html). They can be accessed via `population.grid_options['<grid option name>']` after you have set them. \n",
     "\n",
     "- Custom options: these options are not recognized as either of the above, so they will be stored in the custom_options, and can be accessed via `population.custom_options['<custom option name>']`"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 2,
    "id": "79ab50b7-591f-4883-af09-116d1835a751",
    "metadata": {},
    "outputs": [
@@ -136,7 +133,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 3,
    "id": "b9c2471a-a5b0-48b7-a50b-2f0d22100926",
    "metadata": {},
    "outputs": [
@@ -153,7 +150,7 @@
        "'/tmp/binary_c_python/example_python_population_result/example_pop_settings.json'"
       ]
      },
-     "execution_count": 38,
+     "execution_count": 3,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -182,7 +179,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": 4,
    "id": "68c84521-9ae8-4020-af7a-5334173db969",
    "metadata": {},
    "outputs": [
@@ -280,7 +277,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 5,
    "id": "47979841-2c26-4b26-8945-603d013dc93a",
    "metadata": {},
    "outputs": [
@@ -373,7 +370,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 6,
    "id": "0c986215-93b1-4e30-ad79-f7c397e9ff7d",
    "metadata": {},
    "outputs": [
@@ -438,7 +435,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 42,
+   "execution_count": 7,
    "id": "fd197154-a8ce-4865-8929-008d3483101a",
    "metadata": {},
    "outputs": [
@@ -446,7 +443,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "adding: parse_function=<function parse_function at 0x7f1ef99d1f28> to grid_options\n"
+      "adding: parse_function=<function parse_function at 0x7f54b3a21a60> to grid_options\n"
      ]
     }
    ],
@@ -471,7 +468,7 @@
     "    parameters = [\"time\", \"mass\", \"zams_mass\", \"probability\", \"stellar_type\"]\n",
     "\n",
     "    # Go over the output.\n",
-    "    for line in output_lines(output):\n",
+    "    for line in output.splitlines():\n",
     "        headerline = line.split()[0]\n",
     "\n",
     "        # CHeck the header and act accordingly\n",
@@ -504,12 +501,14 @@
     "## Evolving the grid\n",
     "Now that we configured all the main parts of the population object, we can actually run the population! Doing this is straightforward: `example_pop.evolve()`\n",
     "\n",
-    "This will start up the processing of all the systems. We can control how many cores are used by settings `amt_cores`. By setting the `verbosity` of the population object to a higher value we can get a lot of verbose information about the run, but for now we will set it to 0."
+    "This will start up the processing of all the systems. We can control how many cores are used by settings `amt_cores`. By setting the `verbosity` of the population object to a higher value we can get a lot of verbose information about the run, but for now we will set it to 0.\n",
+    "\n",
+    "There are many grid_options that can lead to different behaviour of the evolution of the grid. Please do have a look at those: [grid options docs](https://ri0005.pages.surrey.ac.uk/binary_c-python/grid_options_descriptions.html), and try  "
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 8,
    "id": "8ea376c1-1e92-45af-8cab-9d7fdca564eb",
    "metadata": {
     "tags": []
@@ -524,25 +523,7 @@
       "Constructing/adding: lnm1\n",
       "Grid has handled 20 stars\n",
       "with a total probability of 0.05150046619238192\n",
-      "Total starcount for this run will be: 20\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[2021-08-08 17:48:00,496 DEBUG    MainProcess] --- setting up the system_queue_filler now\n",
-      "[2021-08-08 17:48:00,498 DEBUG    Process-38] --- Setting up processor: process-0[2021-08-08 17:48:00,499 DEBUG    Process-39] --- Setting up processor: process-1\n",
-      "[2021-08-08 17:48:00,505 DEBUG    MainProcess] --- Signaling stop to processes\n",
-      "\n"
-     ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Process 1 started at 2021-08-08T17:48:00.506077.\tUsing store memaddr <capsule object \"STORE\" at 0x7f1efb31cd20>\n",
-      "Process 0 started at 2021-08-08T17:48:00.516098.\tUsing store memaddr <capsule object \"STORE\" at 0x7f1efb31ce70>\n",
+      "Total starcount for this run will be: 20\n",
       "Generating grid code\n",
       "Constructing/adding: lnm1\n",
       "EXAMPLE_COMPACT_OBJECT             2.867655467480e+01 1.33079 9.81391 0.00167028 13\n",
@@ -557,71 +538,9 @@
       "EXAMPLE_COMPACT_OBJECT             4.337250536639e+00 2.35209 60.4424 0.000157195 14\n",
       "EXAMPLE_COMPACT_OBJECT             3.862081089332e+00 2.56776 75.8628 0.000116989 14\n",
       "EXAMPLE_COMPACT_OBJECT             3.449960890183e+00 2.80457 95.2174 8.70668e-05 14\n",
-      "EXAMPLE_COMPACT_OBJECT             3.172196856333e+00 3.05193 119.51 6.47976e-05 14\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[2021-08-08 17:48:01,097 DEBUG    Process-39] --- Process-1 is finishing.\n"
-     ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Process 1 finished:\n",
-      "\tgenerator started at 2021-08-08T17:48:00.499672, done at 2021-08-08T17:48:01.114081 (total: 0.614409s of which 0.5701460838317871s interfacing with binary_c).\n",
-      "\tRan 10 systems with a total probability of 0.026044641717704063.\n",
-      "\tThis thread had 0 failing systems with a total probability of 0.\n",
-      "\tSkipped a total of 0 systems because they had 0 probability\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[2021-08-08 17:48:01,127 DEBUG    Process-39] --- Process-1 is finished.\n"
-     ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "EXAMPLE_COMPACT_OBJECT             3.069627290216e+00 3.27563 150 4.82242e-05 14\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[2021-08-08 17:48:01,152 DEBUG    Process-38] --- Process-0 is finishing.\n"
-     ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Process 0 finished:\n",
-      "\tgenerator started at 2021-08-08T17:48:00.498331, done at 2021-08-08T17:48:01.161255 (total: 0.662924s of which 0.6246497631072998s interfacing with binary_c).\n",
-      "\tRan 10 systems with a total probability of 0.025455824474677844.\n",
-      "\tThis thread had 0 failing systems with a total probability of 0.\n",
-      "\tSkipped a total of 0 systems because they had 0 probability\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "[2021-08-08 17:48:01,170 DEBUG    Process-38] --- Process-0 is finished.\n"
-     ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Population-4f23670fd94b48cbb6590a4e503782ca finished! The total probability was: 0.05150046619238191. It took a total of 0.864509105682373s to run 20 systems on 2 cores\n",
+      "EXAMPLE_COMPACT_OBJECT             3.172196856333e+00 3.05193 119.51 6.47976e-05 14\n",
+      "EXAMPLE_COMPACT_OBJECT             3.069627290216e+00 3.27563 150 4.82242e-05 14\n",
+      "Population-c8a5c8285f6047bfa420a68ccc89a04f finished! The total probability was: 0.05150046619238191. It took a total of 0.8319869041442871s to run 20 systems on 2 cores\n",
       "There were no errors found in this run.\n"
      ]
     }
@@ -645,7 +564,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 44,
+   "execution_count": 9,
    "id": "e1f0464b-0424-4022-b34b-5b744bc2c59d",
    "metadata": {},
    "outputs": [
@@ -653,7 +572,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "{'population_name': '4f23670fd94b48cbb6590a4e503782ca', 'evolution_type': 'grid', 'failed_count': 0, 'failed_prob': 0, 'failed_systems_error_codes': [], 'errors_exceeded': False, 'errors_found': False, 'total_probability': 0.05150046619238191, 'total_count': 20, 'start_timestamp': 1628441280.4808269, 'end_timestamp': 1628441281.345336, 'total_mass_run': 730.1048014407227, 'total_probability_weighted_mass_run': 0.2983275843337705, 'zero_prob_stars_skipped': 0}\n"
+      "{'population_name': 'c8a5c8285f6047bfa420a68ccc89a04f', 'evolution_type': 'grid', 'failed_count': 0, 'failed_prob': 0, 'failed_systems_error_codes': [], 'errors_exceeded': False, 'errors_found': False, 'total_probability': 0.05150046619238191, 'total_count': 20, 'start_timestamp': 1628442540.4302576, 'end_timestamp': 1628442541.2622445, 'total_mass_run': 730.1048014407228, 'total_probability_weighted_mass_run': 0.2983275843337705, 'zero_prob_stars_skipped': 0}\n"
      ]
     }
    ],
@@ -661,286 +580,107 @@
     "print(analytics)"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1a10760f-f94e-496f-923c-89dbd450b65c",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a6108170-2055-48ba-9732-d39f46baf16a",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "348ba1d2-4cea-47b8-a94c-677e43c9247a",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
   {
    "cell_type": "markdown",
-   "id": "ce937b07-7292-4bb1-b2e7-d69e51bdff6e",
-   "metadata": {
-    "tags": []
-   },
+   "id": "6460df56-9fba-4817-9a1e-593ef15d98c1",
+   "metadata": {},
    "source": [
-    "Wrapping up the results to an hdf5 file can be done by using the create_hdf5\n",
-    "(<directory containing data and settings>) This function takes the settings file\n",
-    "(ending in _settings.json) and the data files (ending in .dat) from the data_dir\n",
-    "and packing them into an hdf5 file, which is then written into the same data_dir directory"
+    "## Noteworthy functionality\n",
+    "Some extra features that are available from via the population object are:\n",
+    "- write_binary_c_calls_to_file: Function to write the calls that would be passed to binary_c to a file"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
-   "id": "ad444138-f854-4fdb-8e18-49e35ac9c7e2",
+   "execution_count": 10,
+   "id": "83f8e519-4f7c-474a-ad95-f175a34fae81",
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Creating /tmp/binary_c_python/example_python_population_result/example_pop.hdf5\n",
-      "Adding settings to HDF5 file\n",
-      "Adding data to HDF5 file\n"
-     ]
-    },
-    {
-     "ename": "ValueError",
-     "evalue": "Wrong number of columns at line 17",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-45-9734fbb7432e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcreate_hdf5\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata_dir\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mexample_pop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcustom_options\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"data_dir\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"example_pop.hdf5\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
-      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/functions.py\u001b[0m in \u001b[0;36mcreate_hdf5\u001b[0;34m(data_dir, name)\u001b[0m\n\u001b[1;32m    482\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    483\u001b[0m             \u001b[0;31m# Add data\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 484\u001b[0;31m             \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloadtxt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfull_path\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mskiprows\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    485\u001b[0m             \u001b[0mdata_grp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_dataset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbase_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    486\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mloadtxt\u001b[0;34m(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows)\u001b[0m\n\u001b[1;32m   1137\u001b[0m         \u001b[0;31m# converting the data\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1138\u001b[0m         \u001b[0mX\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1139\u001b[0;31m         \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mread_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_loadtxt_chunksize\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1140\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mX\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1141\u001b[0m                 \u001b[0mX\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/numpy/lib/npyio.py\u001b[0m in \u001b[0;36mread_data\u001b[0;34m(chunk_size)\u001b[0m\n\u001b[1;32m   1062\u001b[0m                 \u001b[0mline_num\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mskiprows\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1063\u001b[0m                 raise ValueError(\"Wrong number of columns at line %d\"\n\u001b[0;32m-> 1064\u001b[0;31m                                  % line_num)\n\u001b[0m\u001b[1;32m   1065\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1066\u001b[0m             \u001b[0;31m# Convert each value according to its column and store\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mValueError\u001b[0m: Wrong number of columns at line 17"
+      "Help on method write_binary_c_calls_to_file in module binarycpython.utils.grid:\n",
+      "\n",
+      "write_binary_c_calls_to_file(output_dir:Union[str, NoneType]=None, output_filename:Union[str, NoneType]=None, include_defaults:bool=False) -> None method of binarycpython.utils.grid.Population instance\n",
+      "    Function that loops over the grid code and writes the generated parameters to a file.\n",
+      "    In the form of a command line call\n",
+      "    \n",
+      "    Only useful when you have a variable grid as system_generator. MC wouldn't be that useful\n",
+      "    \n",
+      "    Also, make sure that in this export there are the basic parameters\n",
+      "    like m1,m2,sep, orb-per, ecc, probability etc.\n",
+      "    \n",
+      "    On default this will write to the datadir, if it exists\n",
+      "    \n",
+      "    Tasks:\n",
+      "        - TODO: test this function\n",
+      "        - TODO: make sure the binary_c_python .. output file has a unique name\n",
+      "    \n",
+      "    Args:\n",
+      "        output_dir: (optional, default = None) directory where to write the file to. If custom_options['data_dir'] is present, then that one will be used first, and then the output_dir\n",
+      "        output_filename: (optional, default = None) filename of the output. If not set it will be called \"binary_c_calls.txt\"\n",
+      "        include_defaults: (optional, default = None) whether to include the defaults of binary_c in the lines that are written. Beware that this will result in very long lines, and it might be better to just export the binary_c defaults and keep them in a separate file.\n",
+      "    \n",
+      "    Returns:\n",
+      "        filename: filename that was used to write the calls to\n",
+      "\n"
      ]
     }
    ],
    "source": [
-    "create_hdf5(data_dir=example_pop.custom_options[\"data_dir\"], name=\"example_pop.hdf5\")"
+    "help(example_pop.write_binary_c_calls_to_file)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "id": "34da69bc-fe60-4a9d-b07a-f6cd2f216964",
+   "execution_count": 16,
+   "id": "dacfed75-dfe3-4afd-a0ff-a4be17746021",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "adding: verbosity=10 to grid_options\n",
+      "Writing binary_c calls to /tmp/binary_c_python/example_python_population_result/binary_c_calls.txt\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "_calculate_multiplicity_fraction: Chosen not to use any multiplicity fraction.\n",
+      "Grid has handled 20 stars\n",
+      "with a total probability of 0.25750233096190955\n",
+      "/tmp/binary_c_python/example_python_population_result/binary_c_calls.txt\n",
+      "binary_c M_1 2.0 eccentricity 0.02 max_evolution_time 15000 orbital_period 45000000080 phasevol 0.22723621650191106 probability 0.013208238029791246 separation 0\n",
+      "binary_c M_1 2.5102526289471614 eccentricity 0.02 max_evolution_time 15000 orbital_period 45000000080 phasevol 0.22723621650191106 probability 0.009829948023831718 separation 0\n",
+      "binary_c M_1 3.1506841305680684 eccentricity 0.02 max_evolution_time 15000 orbital_period 45000000080 phasevol 0.22723621650191106 probability 0.0073157281034221516 separation 0\n",
+      "binary_c M_1 3.9545065608702976 eccentricity 0.02 max_evolution_time 15000 orbital_period 45000000080 phasevol 0.22723621650191106 probability 0.005444573822104362 separation 0\n"
+     ]
+    }
+   ],
    "source": [
+    "example_pop.set(verbosity=10)\n",
+    "calls_filename = example_pop.write_binary_c_calls_to_file()\n",
+    "print(calls_filename)\n",
     "\n",
-    "\n",
-    "import os\n",
-    "from binarycpython.utils.grid import Population\n",
-    "from binarycpython.utils.functions import (\n",
-    "    get_help_all,\n",
-    "    get_help,\n",
-    "    create_hdf5,\n",
-    "    output_lines,\n",
-    ")\n",
-    "from binarycpython.utils.custom_logging_functions import temp_dir\n",
-    "\n",
-    "#########################################################\n",
-    "# This file serves as an example for running a population.\n",
-    "# The use of help(<function>) is a good way to inspect what parameters are there to use\n",
-    "#########################################################\n",
-    "\n",
-    "\n",
-    "def parse_function(self, output):\n",
-    "    # EXAMPLE PARSE_FUNCTION\n",
-    "\n",
-    "    # extract info from the population instance\n",
-    "\n",
-    "    # Get some information from the\n",
-    "    data_dir = self.custom_options[\"data_dir\"]\n",
-    "    base_filename = self.custom_options[\"base_filename\"]\n",
-    "\n",
-    "    # Check directory, make if necessary\n",
-    "    os.makedirs(data_dir, exist_ok=True)\n",
-    "\n",
-    "    seperator = \" \"\n",
-    "\n",
-    "    # Create filename\n",
-    "    outfilename = os.path.join(data_dir, base_filename)\n",
-    "\n",
-    "    parameters = [\"time\", \"mass\", \"zams_mass\", \"probability\", \"radius\", \"stellar_type\"]\n",
-    "\n",
-    "    # Go over the output.\n",
-    "    for el in output_lines(output):\n",
-    "        headerline = el.split()[0]\n",
-    "\n",
-    "        # CHeck the header and act accordingly\n",
-    "        if headerline == \"MY_STELLAR_DATA\":\n",
-    "            values = el.split()[1:]\n",
-    "            print(values)\n",
-    "\n",
-    "            if not len(parameters) == len(values):\n",
-    "                print(\"Amount of column names isnt equal to amount of columns\")\n",
-    "                raise ValueError\n",
-    "\n",
-    "            if not os.path.exists(outfilename):\n",
-    "                with open(outfilename, \"w\") as f:\n",
-    "                    f.write(seperator.join(parameters) + \"\\n\")\n",
-    "\n",
-    "            with open(outfilename, \"a\") as f:\n",
-    "                f.write(seperator.join(values) + \"\\n\")\n",
-    "\n",
-    "\n",
-    "# Create population object\n",
-    "example_pop = Population()\n",
-    "\n",
-    "# If you want verbosity, set this before other things\n",
-    "example_pop.set(verbose=1)\n",
-    "\n",
-    "# Setting values can be done via .set(<parameter_name>=<value>)\n",
-    "# Values that are known to be binary_c_parameters are loaded into bse_options.\n",
-    "# Those that are present in the default grid_options are set in grid_options\n",
-    "# All other values that you set are put in a custom_options dict\n",
-    "example_pop.set(\n",
-    "    # binary_c physics options\n",
-    "    M_1=10,  # bse_options\n",
-    "    separation=0,  # bse_options\n",
-    "    orbital_period=45000000080,  # bse_options\n",
-    "    max_evolution_time=15000,  # bse_options\n",
-    "    eccentricity=0.02,  # bse_options\n",
-    "    # Set companion to low mass\n",
-    "    M_2=0.08,  # Since in the example we run a single system, we should set the companion mass here. If we donm't do this, the code will complain.\n",
-    "    # grid_options\n",
-    "    amt_cores=2,  # grid_options\n",
-    "    verbose=1,  # verbosity. Not fully configured correctly yet but having it value of 1 prints alot of stuff\n",
-    "    # Custom options # TODO: need to be set in grid_options probably\n",
-    "    data_dir=os.path.join(\n",
-    "        temp_dir(), \"example_python_population_result\"\n",
-    "    ),  # custom_options\n",
-    "    base_filename=\"example_pop.dat\",  # custom_options\n",
-    ")\n",
-    "\n",
-    "# Creating a parsing function\n",
-    "example_pop.set(\n",
-    "    parse_function=parse_function,  # Setting the parse function thats used in the evolve_population\n",
-    ")\n",
-    "\n",
-    "### Custom logging\n",
-    "\n",
-    "## Below example requires changing the parse function\n",
-    "## very simple example of custom logging. Will work but need to change the parse function to handle that nicely.\n",
-    "# example_pop.set(\n",
-    "#     C_auto_logging={\n",
-    "#         \"MY_HEADER_LINE\": [\"star[0].mass\", \"star[1].mass\", \"model.probability\"]\n",
-    "#     }\n",
-    "# )\n",
-    "\n",
-    "\n",
-    "# Log the moment when the star turns into neutron\n",
-    "example_pop.set(\n",
-    "    C_logging_code=\"\"\"\n",
-    "if(stardata->star[0].stellar_type >= 13)    \n",
-    "{\n",
-    "    if (stardata->model.time < stardata->model.max_evolution_time)\n",
-    "    {\n",
-    "        Printf(\"MY_STELLAR_DATA %30.12e %g %g %g %g %d\\\\n\",\n",
-    "            // \n",
-    "            stardata->model.time, // 1\n",
-    "            stardata->star[0].mass, // 2\n",
-    "            stardata->common.zero_age.mass[0], // 4\n",
-    "            stardata->model.probability, // 5\n",
-    "            stardata->star[0].radius, // 6\n",
-    "            stardata->star[0].stellar_type // 7\n",
-    "      );\n",
-    "    };\n",
-    "    /* Kill the simulation to save time */\n",
-    "    stardata->model.max_evolution_time = stardata->model.time - stardata->model.dtm;\n",
-    "};\n",
-    "\"\"\"\n",
-    ")\n",
-    "\n",
-    "# Add grid variables\n",
-    "resolution = {\"M_1\": 20, \"q\": 20, \"per\": 40}\n",
-    "\n",
-    "# Mass\n",
-    "example_pop.add_grid_variable(\n",
-    "    name=\"lnm1\",\n",
-    "    longname=\"Primary mass\",\n",
-    "    valuerange=[2, 150],\n",
-    "    resolution=\"{}\".format(resolution[\"M_1\"]),\n",
-    "    spacingfunc=\"const(math.log(2), math.log(150), {})\".format(resolution[\"M_1\"]),\n",
-    "    precode=\"M_1=math.exp(lnm1)\",\n",
-    "    probdist=\"three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 150, -1.3, -2.3, -2.3)*M_1\",\n",
-    "    dphasevol=\"dlnm1\",\n",
-    "    parameter_name=\"M_1\",\n",
-    "    condition=\"\",  # Impose a condition on this grid variable. Mostly for a check for yourself\n",
-    ")\n",
-    "\n",
-    "# # Mass ratio\n",
-    "# test_pop.add_grid_variable(\n",
-    "#     name=\"q\",\n",
-    "#     longname=\"Mass ratio\",\n",
-    "#     valuerange=[\"0.1/M_1\", 1],\n",
-    "#     resolution=\"{}\".format(resolution['q']),\n",
-    "#     spacingfunc=\"const(0.1/M_1, 1, {})\".format(resolution['q']),\n",
-    "#     probdist=\"flatsections(q, [{'min': 0.1/M_1, 'max': 1.0, 'height': 1}])\",\n",
-    "#     dphasevol=\"dq\",\n",
-    "#     precode=\"M_2 = q * M_1\",\n",
-    "#     parameter_name=\"M_2\",\n",
-    "#     condition=\"\",  # Impose a condition on this grid variable. Mostly for a check for yourself\n",
-    "# )\n",
-    "\n",
-    "# #\n",
-    "# test_pop.add_grid_variable(\n",
-    "#    name=\"log10per\", # in days\n",
-    "#    longname=\"log10(Orbital_Period)\",\n",
-    "#    valuerange=[0.15, 5.5],\n",
-    "#    resolution=\"{}\".format(resolution[\"per\"]),\n",
-    "#    spacingfunc=\"const(0.15, 5.5, {})\".format(resolution[\"per\"]),\n",
-    "#    precode=\"\"\"orbital_period = 10** log10per\n",
-    "# sep = calc_sep_from_period(M_1, M_2, orbital_period)\n",
-    "# sep_min = calc_sep_from_period(M_1, M_2, 10**0.15)\n",
-    "# sep_max = calc_sep_from_period(M_1, M_2, 10**5.5)\"\"\",\n",
-    "#    probdist=\"sana12(M_1, M_2, sep, orbital_period, sep_min, sep_max, math.log10(10**0.15), math.log10(10**5.5), -0.55)\",\n",
-    "#    parameter_name=\"orbital_period\",\n",
-    "#    dphasevol=\"dlog10per\",\n",
-    "# )\n",
-    "\n",
-    "\n",
-    "# Exporting of all the settings can be done with .export_all_info()\n",
-    "# on default it exports everything, but can be supressed by turning it off:\n",
-    "#   population settings (bse_options, grid_options, custom_options), turn off with include_population\n",
-    "#       settings=False\n",
-    "#   binary_c_defaults (all the commandline arguments that binary c accepts, and their defaults).\n",
-    "#       turn off with include_binary_c_defaults=False\n",
-    "#   include_binary_c_version_info (all the compilation info, and information about the compiled\n",
-    "#       parameters), turn off with include_binary_c_version_info=False\n",
-    "#   include_binary_c_help_all (all the help information for all the binary_c parameters),\n",
-    "#       turn off with include_binary_c_help_all=Fase\n",
-    "# On default it will write this to the custom_options['data_dir'], but that can be overriden by\n",
-    "#   setting use_datadir=False and providing an outfile=<>\n",
-    "example_pop.export_all_info()\n",
-    "\n",
-    "## Executing a single system\n",
-    "## This uses the M_1 orbital period etc set with the set function\n",
-    "# output = example_pop.evolve_single()\n",
-    "# print(output)\n",
-    "\n",
-    "## Executing a population\n",
-    "## This uses the values generated by the grid_variables\n",
-    "example_pop.evolve()  # TODO: update this function call\n",
-    "\n",
-    "# Wrapping up the results to an hdf5 file can be done by using the create_hdf5\n",
-    "# (<directory containing data and settings>) This function takes the settings file\n",
-    "# (ending in _settings.json) and the data files (ending in .dat) from the data_dir\n",
-    "# and packing them into an hdf5 file, which is then written into the same data_dir directory\n",
-    "create_hdf5(data_dir=example_pop.custom_options[\"data_dir\"], name=\"example_pop.hdf5\")\n"
+    "with open(calls_filename, 'r') as f:\n",
+    "    print('\\n'.join(f.read().splitlines()[:4]))"
    ]
   },
   {
@@ -954,10 +694,81 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 12,
    "id": "7212b6be-9787-4122-a7f1-86538cf38179",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Generating grid code\n",
+      "Constructing/adding: lnm1\n",
+      "Grid has handled 20 stars\n",
+      "with a total probability of 0.05150046619238192\n",
+      "Total starcount for this run will be: 20\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Process Process-5:\n",
+      "Traceback (most recent call last):\n",
+      "Process Process-6:\n",
+      "Traceback (most recent call last):\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/process.py\", line 258, in _bootstrap\n",
+      "    self.run()\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/process.py\", line 93, in run\n",
+      "    self._target(*self._args, **self._kwargs)\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/process.py\", line 258, in _bootstrap\n",
+      "    self.run()\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\", line 1312, in _process_run_population_grid\n",
+      "    self._evolve_system_mp(full_system_dict)\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/process.py\", line 93, in run\n",
+      "    self._target(*self._args, **self._kwargs)\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\", line 1312, in _process_run_population_grid\n",
+      "    self._evolve_system_mp(full_system_dict)\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\", line 1128, in _evolve_system_mp\n",
+      "    self.grid_options[\"parse_function\"](self, out)\n",
+      "  File \"<ipython-input-12-6a22064fcbfb>\", line 30, in parse_function\n",
+      "    for el in output_lines(output):\n",
+      "NameError: name 'output_lines' is not defined\n",
+      "  File \"/home/david/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\", line 1128, in _evolve_system_mp\n",
+      "    self.grid_options[\"parse_function\"](self, out)\n",
+      "  File \"<ipython-input-12-6a22064fcbfb>\", line 30, in parse_function\n",
+      "    for el in output_lines(output):\n",
+      "NameError: name 'output_lines' is not defined\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Generating grid code\n",
+      "Constructing/adding: lnm1\n"
+     ]
+    },
+    {
+     "ename": "KeyboardInterrupt",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-12-6a22064fcbfb>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m    127\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    128\u001b[0m \u001b[0;31m# Evolve the population\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 129\u001b[0;31m \u001b[0mexample_pop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mevolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    130\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    131\u001b[0m \u001b[0;31m#\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\u001b[0m in \u001b[0;36mevolve\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    766\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    767\u001b[0m             \u001b[0;31m# Execute population evolution subroutines\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 768\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mevolve_population\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    769\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    770\u001b[0m         \u001b[0;31m# Put all interesting stuff in a variable and output that afterwards, as analytics of the run.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\u001b[0m in \u001b[0;36mevolve_population\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    826\u001b[0m         ):\n\u001b[1;32m    827\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgrid_options\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"evolution_type\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"grid\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 828\u001b[0;31m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_evolve_population_grid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    829\u001b[0m             \u001b[0;31m# elif self.grid_options[\"evolution_type\"] == \"mc\":\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    830\u001b[0m             \u001b[0;31m#     # TODO: add MC option\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/envs/dev-binarycpython3.6.4/lib/python3.6/site-packages/binarycpython/utils/grid.py\u001b[0m in \u001b[0;36m_evolve_population_grid\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1037\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1038\u001b[0m         \u001b[0msentinel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mobject\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1039\u001b[0;31m         \u001b[0;32mfor\u001b[0m \u001b[0moutput_dict\u001b[0m \u001b[0;32min\u001b[0m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msentinel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1040\u001b[0m             \u001b[0mcombined_output_dict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmerge_dicts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcombined_output_dict\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput_dict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1041\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mresult_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mempty\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, *args, **kwds)\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/managers.py\u001b[0m in \u001b[0;36m_callmethod\u001b[0;34m(self, methodname, args, kwds)\u001b[0m\n\u001b[1;32m    755\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    756\u001b[0m         \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethodname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 757\u001b[0;31m         \u001b[0mkind\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    758\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    759\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mkind\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'#RETURN'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/connection.py\u001b[0m in \u001b[0;36mrecv\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    248\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_check_closed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    249\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_check_readable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 250\u001b[0;31m         \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    251\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0m_ForkingPickler\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloads\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbuf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetbuffer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    252\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv_bytes\u001b[0;34m(self, maxsize)\u001b[0m\n\u001b[1;32m    405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    406\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 407\u001b[0;31m         \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    408\u001b[0m         \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstruct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munpack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"!i\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetvalue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    409\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mmaxsize\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0msize\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/.pyenv/versions/3.6.4/lib/python3.6/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv\u001b[0;34m(self, size, read)\u001b[0m\n\u001b[1;32m    377\u001b[0m         \u001b[0mremaining\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    378\u001b[0m         \u001b[0;32mwhile\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 379\u001b[0;31m             \u001b[0mchunk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremaining\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    380\u001b[0m             \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchunk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    381\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
+     ]
+    }
+   ],
    "source": [
     "import os\n",
     "\n",
@@ -988,7 +799,7 @@
     "    parameters = [\"time\", \"mass\", \"zams_mass\", \"probability\", \"radius\", \"stellar_type\"]\n",
     "\n",
     "    # Go over the output.\n",
-    "    for el in output_lines(output):\n",
+    "    for el in output.splitlines():\n",
     "        headerline = el.split()[0]\n",
     "\n",
     "        # CHeck the header and act accordingly\n",
-- 
GitLab