From 490e28b9355ac95a0fcf0b854624cadc410ac182 Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Wed, 10 Mar 2021 19:10:38 +0000
Subject: [PATCH] More detailed test output

---
 binarycpython/tests/test_distributions.py | 58 +++++++++++++++----
 binarycpython/utils/grid.py               | 70 +++++++++++++----------
 2 files changed, 87 insertions(+), 41 deletions(-)

diff --git a/binarycpython/tests/test_distributions.py b/binarycpython/tests/test_distributions.py
index def8ba241..4c1204f09 100644
--- a/binarycpython/tests/test_distributions.py
+++ b/binarycpython/tests/test_distributions.py
@@ -93,12 +93,15 @@ class TestDistributions(unittest.TestCase):
             0.000161214690242696,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(powerlaw(1, 100, -2.3, mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
+            msg = "Error: Value perl: {} Value python: {} for mass, per: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
             self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
 
         # extra test for k = -1
@@ -118,15 +121,18 @@ class TestDistributions(unittest.TestCase):
             6.19974072148769e-06,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(
                 three_part_powerlaw(mass, 0.08, 0.1, 1, 300, -1.3, -2.3, -2.3)
             )
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass, per: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
         # Extra test:
         # M < M0
@@ -149,13 +155,17 @@ class TestDistributions(unittest.TestCase):
             1.77061658757533e-05,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(Kroupa2001(mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
+
         # Extra tests:
         self.assertEqual(
             Kroupa2001(10, newopts={"mmax": 300}),
@@ -176,13 +186,17 @@ class TestDistributions(unittest.TestCase):
             4.02817276824841e-06,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(ktg93(mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
+
         # extra test:
         self.assertEqual(
             ktg93(10, newopts={"mmax": 300}),
@@ -235,7 +249,7 @@ class TestDistributions(unittest.TestCase):
         self.assertLess(
             np.abs(imf_chabrier2003(m) - 0.581457346702825),
             self.tolerance,
-            msg="Difference is bigger than the tolerance",
+            msg="Difference is bigger than the tolerance. Input mass = {}".format(m),
         )
 
         # For m = 2
@@ -243,7 +257,7 @@ class TestDistributions(unittest.TestCase):
         self.assertLess(
             np.abs(imf_chabrier2003(m) - 0.581457346702825),
             self.tolerance,
-            msg="Difference is bigger than the tolerance",
+            msg="Difference is bigger than the tolerance. Input mass = {}".format(m),
         )
 
     def test_duquennoy1991(self):
@@ -267,13 +281,16 @@ class TestDistributions(unittest.TestCase):
             0.0134332780385336,
         ]
         python_results = []
+        input_lists = []
 
         for logper in self.logper_list:
+            input_lists.append(logper)
             python_results.append(gaussian(logper, 4.8, 2.3, -2.0, 12.0))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for logper: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
         # Extra test:
         self.assertTrue(
@@ -295,13 +312,16 @@ class TestDistributions(unittest.TestCase):
             0.8388,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(Arenou2010_binary_fraction(mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
     def test_raghavan2010_binary_fraction(self):
         """
@@ -310,13 +330,16 @@ class TestDistributions(unittest.TestCase):
 
         perl_results = [0.304872297931597, 0.334079955706623, 0.41024, 1, 1, 1]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
+            input_lists.append(mass)
             python_results.append(raghavan2010_binary_fraction(mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
     def test_Izzard2012_period_distribution(self):
         """
@@ -362,14 +385,18 @@ class TestDistributions(unittest.TestCase):
             0.0221093965810181,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
             for per in self.per_list:
+                input_lists.append([mass, per])
+
                 python_results.append(Izzard2012_period_distribution(per, mass))
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for mass, per: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
     def test_flatsections(self):
         """
@@ -385,15 +412,18 @@ class TestDistributions(unittest.TestCase):
             1.01010101010101,
         ]
         python_results = []
+        input_lists = []
 
         for q in self.q_list:
+            input_lists.append(q)
             python_results.append(
                 flatsections(q, [{"min": 0.01, "max": 1.0, "height": 1.0}])
             )
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
+            msg = "Error: Value perl: {} Value python: {} for q: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
     def test_sana12(self):
         """
@@ -619,6 +649,7 @@ class TestDistributions(unittest.TestCase):
             0.066436408359805,
         ]
         python_results = []
+        input_lists = []
 
         for mass in self.mass_list:
             for q in self.q_list:
@@ -628,6 +659,9 @@ class TestDistributions(unittest.TestCase):
                     sep = calc_sep_from_period(mass, mass_2, per)
                     sep_min = calc_sep_from_period(mass, mass_2, 10 ** 0.15)
                     sep_max = calc_sep_from_period(mass, mass_2, 10 ** 5.5)
+
+                    input_lists.append([mass, mass_2, per])
+
                     python_results.append(
                         sana12(
                             mass, mass_2, sep, per, sep_min, sep_max, 0.15, 5.5, -0.55
@@ -636,8 +670,8 @@ class TestDistributions(unittest.TestCase):
 
         # GO over the results and check whether they are equal (within tolerance)
         for i in range(len(python_results)):
-            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance)
-
+            msg = "Error: Value perl: {} Value python: {} for mass, mass2, per: {}".format(python_results[i], perl_results[i], str(input_lists[i]))
+            self.assertLess(np.abs(python_results[i] - perl_results[i]), self.tolerance, msg=msg)
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py
index 9e0840e3d..02211402f 100644
--- a/binarycpython/utils/grid.py
+++ b/binarycpython/utils/grid.py
@@ -843,6 +843,7 @@ class Population:
         """
 
         binary_cmdline_string = self._return_argline(full_system_dict)
+        print(binary_cmdline_string)
 
         persistent_data_memaddr = -1
         if self.bse_options.get("ensemble", 0) == 1:
@@ -884,17 +885,27 @@ class Population:
             ID  # Store the ID as a object property again, lets see if that works.
         )
 
+        # lets try out making stores for all the grids:
+        self.grid_options["_store_memaddr"] = _binary_c_bindings.return_store_memaddr()
+
+        verbose_print(
+            "Process {} started at {}.\tUsing store memaddr {}".format(ID, datetime.datetime.now().isoformat(), self.grid_options["_store_memaddr"]), self.grid_options["verbosity"], 0
+        )
+
+        # Set the ensemble memaddr
         if self.bse_options.get("ensemble", 0) == 1:
             # set persistent data memaddr if necessary.
             persistent_data_memaddr = (
                 _binary_c_bindings.return_persistent_data_memaddr()
             )
+
             self.persistent_data_memory_dict = {
                 self.process_ID: persistent_data_memaddr
             }
 
-        # lets try out making stores for all the grids:
-        self.grid_options["_store_memaddr"] = _binary_c_bindings.return_store_memaddr()
+            verbose_print(
+                "\tUsing persistent_data memaddr: {}".format(persistent_data_memaddr), self.grid_options["verbosity"], 0
+            )
 
         # apparently we have to re-load this for every process, otherwise NameErrors arise (seems like a bug but I'm not sure)
         self._load_grid_function()
@@ -914,10 +925,6 @@ class Population:
             0  # counter for the actual amt of systems this thread ran
         )
 
-        verbose_print(
-            "Process {} started at {}. Using store memaddr {}".format(ID, datetime.datetime.now().isoformat(), self.grid_options["_store_memaddr"]), self.grid_options["verbosity"], 0
-        )
-
         round_number_mod = 0 # rotating modulo
 
         total_time_calling_binary_c = 0
@@ -931,7 +938,7 @@ class Population:
                 system = next(generator)
 
                 # Check if the ID is the correct one for this process
-                if (localcounter + (ID+round_number_mod)) % self.grid_options["amt_cores"] == 0:
+                if (localcounter + (ID + round_number_mod)) % self.grid_options["amt_cores"] == 0:
 
                     # Combine that with the other settings
                     full_system_dict = self.bse_options.copy()
@@ -975,7 +982,7 @@ class Population:
 
             if (localcounter+1)%self.grid_options["amt_cores"]==0:
                 round_number_mod += 1
-            # round_number_mod = (localcounter+1)%self.grid_options["amt_cores"]
+
             # print("thread {} round_nr_mod {}. localcounter {}".format(ID, round_number_mod, localcounter))
 
             # Has to be here because this one is used for the (localcounter+ID) % (self..)
@@ -984,14 +991,26 @@ class Population:
         # Handle ensemble output: is ensemble==1, then either directly write that data to a file, or combine everything into 1 file.
         ensemble_json = {}  # Make sure it exists already
         if self.bse_options.get("ensemble", 0) == 1:
+            verbose_print(
+                "Process {}: is freeing ensemble output (using persisten_data memaddr {})".format(ID, self.persistent_data_memory_dict[self.process_ID]), self.grid_options["verbosity"], 2
+            )
+
             ensemble_raw_output = (
                 _binary_c_bindings.free_persistent_data_memaddr_and_return_json_output(
                     self.persistent_data_memory_dict[self.process_ID]
                 )
             )
+            if ensemble_raw_output == None:
+                verbose_print(
+                    "Process {}: Warning! Ensemble output is empty. ".format(ID), self.grid_options["verbosity"], 2
+                )
 
             #
             if self.grid_options["combine_ensemble_with_thread_joining"] == True:
+                verbose_print(
+                    "Process {}: Extracting ensemble info from raw string".format(ID), self.grid_options["verbosity"], 2
+                )
+
                 ensemble_json = extract_ensemble_json_from_string(
                     ensemble_raw_output
                 )  # Load this into a dict so that we can combine it later
@@ -1004,16 +1023,17 @@ class Population:
                         self.grid_options["_population_id"], self.process_ID
                     ),
                 )
-                print(
-                    "Thread {}: Chosen to output the ensemble results directly to file: {}".format(
-                        self.process_ID, output_file
-                    )
-                )
 
                 # Write to file
                 with open(output_file, "w") as f:
                     f.write(ensemble_raw_output)
 
+                print(
+                    "Thread {}: Wrote ensemble results directly to file: {}".format(
+                        self.process_ID, output_file
+                    )
+                )
+
         # free store mem:
         _binary_c_bindings.free_store_memaddr(self.grid_options["_store_memaddr"])
 
@@ -1124,7 +1144,7 @@ class Population:
         ### ensemble: make some checks for this
         ## check the settings and set all the warnings.
         if self.bse_options.get("ensemble", None):
-            if not self.bse_options["ensemble_defer"] == 1:
+            if not self.bse_options.get("ensemble_defer", 0) == 1:
                 verbose_print(
                     "Error, if you want to run an ensemble in a population, the output needs to be deferred. Please set 'ensemble_defer' to 1",
                     self.grid_options["verbosity"],
@@ -1132,31 +1152,22 @@ class Population:
                 )
                 raise ValueError
 
-            if not self.custom_options["ensemble_output_name"]:
+            if not any(
+                [key.startswith("ensemble_filter_") for key in self.bse_options]
+            ):
                 verbose_print(
-                    "Error: if you want to run an ensemble in a population, please set set 'ensemble_output_name'. It will be combined with 'data_dir' to write the output of the ensembles to",
+                    "Warning: Running the ensemble without any filter requires alot of available RAM",
                     self.grid_options["verbosity"],
                     0,
                 )
-                raise ValueError
 
-            if not any(
-                [key.startswith("ensemble_filter_") for key in self.bse_options]
-            ):
+            if self.bse_options.get("ensemble_filters_off", 0) != 1:
                 verbose_print(
                     "Warning: Running the ensemble without any filter requires alot of available RAM",
                     self.grid_options["verbosity"],
                     0,
                 )
 
-            if self.bse_options.get("ensemble_filters_off", None):
-                if self.bse_options["ensemble_filters_off"] == 0:
-                    verbose_print(
-                        "Warning: Running the ensemble without any filter requires alot of available RAM",
-                        self.grid_options["verbosity"],
-                        0,
-                    )
-
             if self.grid_options["combine_ensemble_with_thread_joining"] == False:
                 if not self.custom_options.get("data_dir", None):
                     verbose_print(
@@ -1164,6 +1175,7 @@ class Population:
                         self.grid_options["verbosity"],
                         0,
                     )
+                    raise ValueError
 
         # Check which type of population generation
         if self.grid_options["evolution_type"] == "grid":
@@ -2383,7 +2395,7 @@ class Population:
             ## check the settings:
             if self.bse_options.get("ensemble", None):
                 if self.bse_options["ensemble"] == 1:
-                    if not self.bse_options["ensemble_defer"] == 1:
+                    if not self.bse_options.get("ensemble_defer", 0) == 1:
                         verbose_print(
                             "Error, if you want to run an ensemble in a population, the output needs to be deferred",
                             self.grid_options["verbosity"],
-- 
GitLab