From 68e82a11eb34ab7cf85fe7023611d2941d8a7616 Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Fri, 23 Sep 2022 22:56:45 +0100
Subject: [PATCH] working on the mc sampling

---
 .../grid_options_defaults.py                  |   1 +
 .../population_extensions/grid_sampling.py    |   4 +-
 .../monte_carlo_sampling.py                   | 162 +++++++++++++++++-
 3 files changed, 158 insertions(+), 9 deletions(-)

diff --git a/binarycpython/utils/population_extensions/grid_options_defaults.py b/binarycpython/utils/population_extensions/grid_options_defaults.py
index 7670f6565..628c525fe 100644
--- a/binarycpython/utils/population_extensions/grid_options_defaults.py
+++ b/binarycpython/utils/population_extensions/grid_options_defaults.py
@@ -192,6 +192,7 @@ class grid_options_defaults:
             "_monte_carlo_current_total_mass_evolved": 0,
             "_monte_carlo_threshold_reached": False,
             "_monte_carlo_custom_threshold_function": None,
+            "_monte_carlo_generator_filename": None,
             ## Evolution from source file
             # TODO: make run from sourcefile options.
             ########################################
diff --git a/binarycpython/utils/population_extensions/grid_sampling.py b/binarycpython/utils/population_extensions/grid_sampling.py
index 2a5600e4c..59eb23905 100644
--- a/binarycpython/utils/population_extensions/grid_sampling.py
+++ b/binarycpython/utils/population_extensions/grid_sampling.py
@@ -6,10 +6,10 @@ This class object is an extension to the population grid object
 
 # pylint: disable=E1101
 
+import os
+import json
 import datetime
 import importlib
-import json
-import os
 from typing import Union, Any
 
 
diff --git a/binarycpython/utils/population_extensions/monte_carlo_sampling.py b/binarycpython/utils/population_extensions/monte_carlo_sampling.py
index 3b03e6e63..8788ff200 100644
--- a/binarycpython/utils/population_extensions/monte_carlo_sampling.py
+++ b/binarycpython/utils/population_extensions/monte_carlo_sampling.py
@@ -3,10 +3,16 @@ Main script to provide the Monte-Carlo sampling class extensions
 """
 
 # pylint: disable=E1101
+import os
+import datetime
+import importlib
+
 from binarycpython.utils.functions import (
     calculate_total_mass_system,
 )
 
+_numba = False
+
 
 class monte_carlo_sampling:
     """
@@ -27,7 +33,29 @@ class monte_carlo_sampling:
 
         raise NotImplementedError("This functionality is not available yet")
 
-    def _write_monte_carlo_generator(self):
+    def _monte_carlo_sampling_generator_filename(self):
+        """
+        Returns a filename for the gridcode.
+        """
+
+        if self.HPC_job():
+            filename = os.path.join(
+                self.grid_options["tmp_dir"],
+                "binary_c_monte_carlo_sampling_generator_{population_id}.{jobid}.py".format(
+                    population_id=self.grid_options["_population_id"],
+                    jobid=self.jobID(),
+                ),
+            )
+        else:
+            filename = os.path.join(
+                self.grid_options["tmp_dir"],
+                "binary_c_monte_carlo_sampling_generator_{population_id}.py".format(
+                    population_id=self.grid_options["_population_id"]
+                ),
+            )
+        return filename
+
+    def _monte_carlo_sampling_write_generator(self):
         """
         Function that generates the monte-carlo grid file that gets imported
         """
@@ -41,21 +69,141 @@ class monte_carlo_sampling:
         # - (optionally) a latin hypercube implementation
         # - function to write the CDF sampling functions for each grid_variable
 
+        ####################
+        # Development setup: simple 1-value mass yield
+
+        #########
+        # Set up header and start of function
+        self._add_code(
+            # Import packages
+            "import math\n",
+            "import numpy as np\n",
+            "from collections import OrderedDict\n",
+            "from binarycpython.utils.useful_funcs import *\n",
+            "import numba" if _numba else "",
+            "\n\n",
+            # Make the function
+            "def monte_carlo_generator(self, print_results=True):\n",
+        )
+
+        # Increase indent_depth
+        self._increment_indent_depth(+1)
+
+        # Code to set up some parameters
+        self._add_code(
+            # Write some info in the function
+            "# Grid code generated on {}\n".format(datetime.datetime.now().isoformat()),
+            "# This function generates the systems that will be evolved with binary_c\n\n"
+            # Set some values in the generated code:
+            "# Set initial values\n",
+            "_total_starcount = 0\n",
+            "parameter_dict = {}\n",
+        )
+
+        #########
+        # Set up the loop and yield calls
+        self._add_code(
+            # Comment
+            "# Start of the while loop"
+            # while loop
+            "while True:"
+        )
+
+        # Increase indent_depth
+        self._increment_indent_depth(+1)
+
+        #########
+        # Fill the while loop with a dummy sytem of a fixed mass
+        self._add_code(
+            # Sample the variables
+            "# Add M_1 variable\n"
+            # while loop
+            "parameter_dict['M_1'] = 1\n\n"
+        )
+
+        #########
+        # Handle system yield
+        self._add_code(
+            # Comment
+            "# Yield the system dict\n"
+            # while loop
+            "yield(parameter_dict)\n"
+        )
+
+        #################################################################################
+        # Stop of code generation. Here the code is saved and written
+
+        # Save the grid code to the grid_options
+        self.verbose_print(
+            "Save monte_carlo sampling generator to grid_options",
+            self.grid_options["verbosity"],
+            1,
+        )
+
+        self.grid_options["code_string"] = self.code_string
+
+        # Write to file
+        monte_carlo_sampling_generator_filename = (
+            self._monte_carlo_sampling_generator_filename()
+        )
+
+        self.grid_options[
+            "_monte_carlo_sampling_generator_filename"
+        ] = monte_carlo_sampling_generator_filename
+
+        self.verbose_print(
+            "{blue}Write grid code to {file} {reset}".format(
+                blue=self.ANSI_colours["blue"],
+                file=monte_carlo_sampling_generator_filename,
+                reset=self.ANSI_colours["reset"],
+            ),
+            self.grid_options["verbosity"],
+            1,
+        )
+
+        with self.open(
+            monte_carlo_sampling_generator_filename, "w", encoding="utf-8"
+        ) as file:
+            file.write(self.code_string)
+
         raise NotImplementedError("This functionality is not available yet")
 
-    def _load_monte_carlo_generator(self):
+    def _monte_carlo_sampling_load_generator(self):
         """
         Function to load the monte_carlo grid
         """
 
-        raise NotImplementedError("This functionality is not available yet")
+        # Code to load the
+        self.verbose_print(
+            message="Load monte-carlo generator function from {file}".format(
+                file=self.grid_options["_monte_carlo_generator_filename"]
+            ),
+            verbosity=self.grid_options["verbosity"],
+            minimal_verbosity=1,
+        )
+
+        spec = importlib.util.spec_from_file_location(
+            "binary_c_python_monte_carlo_sampling_generator",
+            os.path.join(self.grid_options["monte_carlo_sampling_generator_filename"]),
+        )
+        monte_carlo_sampling_generator_file = importlib.util.module_from_spec(spec)
+        spec.loader.exec_module(monte_carlo_sampling_generator_file)
+        generator = monte_carlo_sampling_generator_file.grid_code
+
+        self.grid_options["_monte_carlo_sampling_generator"] = generator
+
+        self.verbose_print("Grid code loaded", self.grid_options["verbosity"], 1)
+
+        # raise NotImplementedError("This functionality is not available yet")
 
     def _monte_carlo_sampling_setup(self):
         """
         Function to prepate the class for a monte-carlo sampling simulation
         """
 
-        raise NotImplementedError("This functionality is not available yet")
+        print("setup mc sampling")
+
+        # raise NotImplementedError("This functionality is not available yet")
 
     def _monte_carlo_sampling_get_generator(self):
         """
@@ -63,11 +211,11 @@ class monte_carlo_sampling:
         """
 
         # Write monte_carlo generator
-        self._write_monte_carlo_generator()
+        self._monte_carlo_sampling_write_generator()
 
         # Load generator
-        self._load_monte_carlo_generator()
-        generator = self.grid_options["_system_generator"]
+        self._monte_carlo_sampling_load_generator()
+        generator = self.grid_options["_monte_carlo_sampling_generator"]
 
         return generator
 
-- 
GitLab