diff --git a/binarycpython/tests/test_c_bindings.py b/binarycpython/tests/test_c_bindings.py
index 942ae169c66d9ab2341879770d33b6365234a160..5d016dcdf030f7d2b95f93191d705f4ec5032b98 100644
--- a/binarycpython/tests/test_c_bindings.py
+++ b/binarycpython/tests/test_c_bindings.py
@@ -14,7 +14,8 @@ from binarycpython.utils.functions import (
     inspect_dict,
     merge_dicts,
     handle_ensemble_string_to_json,
-    verbose_print
+    verbose_print,
+    extract_ensemble_json_from_string
 )
 
 # https://docs.python.org/3/library/unittest.html
@@ -58,29 +59,6 @@ ensemble_filters_off {8} ensemble_filter_{9} 1 probability 0.1"
 
     return argstring
 
-def extract_ensemble_json_from_string(binary_c_output):
-    """
-    Function to extract the ensemble_json information from a raw binary_c output string
-    """
-
-    json = None
-
-    try:
-        ensemble_jsons_strings = [
-            line for line in binary_c_output.splitlines() if line.startswith("ENSEMBLE_JSON")
-        ]
-
-        json = handle_ensemble_string_to_json(
-            ensemble_jsons_strings[0][len("ENSEMBLE_JSON ") :]
-        )
-
-        if len(ensemble_jsons_strings)>1:
-            verbose_print("Warning: There is more than one line starting with ENSEMBLE_JSON. Taking the first, but you should check this out.",1, 0)
-    except IndexError:
-        verbose_print("Error: Couldn't extract the ensemble information from the output string", 0, 0)
-
-    return json
-
 #######################################################################################################################################################
 ### General run_system test
 #######################################################################################################################################################
diff --git a/binarycpython/tests/test_grid.py b/binarycpython/tests/test_grid.py
index b3990afae845b7f181d9016291676b1e8fff3e06..848380e4b3fac736881d4b710d20131ed3f68ead 100644
--- a/binarycpython/tests/test_grid.py
+++ b/binarycpython/tests/test_grid.py
@@ -34,438 +34,562 @@ binary_c_temp_dir = temp_dir()
 #     """
 
 
-class test_Population(unittest.TestCase):
-    """
-    Unittests for function
-    """
-
-    def test_setup(self):
-        test_pop = Population()
-
-        self.assertTrue("orbital_period" in test_pop.defaults)
-        self.assertTrue("metallicity" in test_pop.defaults)
-        self.assertNotIn("help_all", test_pop.cleaned_up_defaults)
-        self.assertEqual(test_pop.bse_options, {})
-        self.assertEqual(test_pop.custom_options, {})
-        self.assertEqual(test_pop.argline_dict, {})
-        self.assertEqual(test_pop.persistent_data_memory_dict, {})
-        self.assertTrue(test_pop.grid_options["parse_function"] == None)
-        self.assertTrue(isinstance(test_pop.grid_options["_main_pid"], int))
-
-    def test_set(self):
-        test_pop = Population()
-        test_pop.set(amt_cores=2)
-        test_pop.set(M_1=10)
-        test_pop.set(data_dir="/tmp/binary_c_python")
-        test_pop.set(ensemble_filter_SUPERNOVAE=1)
-
-        self.assertIn("data_dir", test_pop.custom_options)
-        self.assertEqual(test_pop.custom_options["data_dir"], "/tmp/binary_c_python")
-
-        #
-        self.assertTrue(test_pop.bse_options["M_1"] == 10)
-        self.assertTrue(test_pop.bse_options["ensemble_filter_SUPERNOVAE"] == 1)
-
-        #
-        self.assertTrue(test_pop.grid_options["amt_cores"] == 2)
-
-    def test_cmdline(self):
-        # copy old sys.argv values
-        prev_sysargv = sys.argv.copy()
-
-        # make a dummy cmdline arg input
-        sys.argv = [
-            "script",
-            "--cmdline",
-            "metallicity=0.0002 amt_cores=2 data_dir=/tmp/binary_c_python",
-        ]
-
-        # Set up population
-        test_pop = Population()
-        test_pop.set(data_dir="/tmp")
-
-        # parse arguments
-        test_pop.parse_cmdline()
-
-        # metallicity
-        self.assertTrue(isinstance(test_pop.bse_options["metallicity"], str))
-        self.assertTrue(test_pop.bse_options["metallicity"] == "0.0002")
-
-        # Amt cores
-        self.assertTrue(isinstance(test_pop.grid_options["amt_cores"], int))
-        self.assertTrue(test_pop.grid_options["amt_cores"] == 2)
-
-        # datadir
-        self.assertTrue(isinstance(test_pop.custom_options["data_dir"], str))
-        self.assertTrue(test_pop.custom_options["data_dir"] == "/tmp/binary_c_python")
-
-        # put back the other args if they exist
-        sys.argv = prev_sysargv.copy()
-
-    def test__return_argline(self):
-        """
-        Unittests for the function _return_argline
-        """
-
-        # Set up population
-        test_pop = Population()
-        test_pop.set(metallicity=0.02)
-        test_pop.set(M_1=10)
-
-        argline = test_pop._return_argline()
-        self.assertTrue(argline == "binary_c M_1 10 metallicity 0.02")
-
-        # custom dict
-        argline2 = test_pop._return_argline(
-            {"example_parameter1": 10, "example_parameter2": "hello"}
-        )
-        self.assertTrue(
-            argline2 == "binary_c example_parameter1 10 example_parameter2 hello"
-        )
-
-    def test_add_grid_variable(self):
-        """
-        Unittests for the function add_grid_variable
-
-        TODO: Should I test more here?
-        """
-
-        test_pop = Population()
-
-        resolution = {"M_1": 10, "q": 10}
-
-        test_pop.add_grid_variable(
-            name="lnm1",
-            longname="Primary mass",
-            valuerange=[1, 100],
-            resolution="{}".format(resolution["M_1"]),
-            spacingfunc="const(math.log(1), math.log(100), {})".format(
-                resolution["M_1"]
-            ),
-            precode="M_1=math.exp(lnm1)",
-            probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
-            dphasevol="dlnm1",
-            parameter_name="M_1",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        test_pop.add_grid_variable(
-            name="q",
-            longname="Mass ratio",
-            valuerange=["0.1/M_1", 1],
-            resolution="{}".format(resolution["q"]),
-            spacingfunc="const(0.1/M_1, 1, {})".format(resolution["q"]),
-            probdist="flatsections(q, [{'min': 0.1/M_1, 'max': 1.0, 'height': 1}])",
-            dphasevol="dq",
-            precode="M_2 = q * M_1",
-            parameter_name="M_2",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        self.assertIn("q", test_pop.grid_options["_grid_variables"])
-        self.assertIn("lnm1", test_pop.grid_options["_grid_variables"])
-        self.assertEqual(len(test_pop.grid_options["_grid_variables"]), 2)
-
-    def test_return_population_settings(self):
-        """
-        Unittests for the function return_population_settings
-        """
-
-        test_pop = Population()
-        test_pop.set(metallicity=0.02)
-        test_pop.set(M_1=10)
-        test_pop.set(amt_cores=2)
-        test_pop.set(data_dir="/tmp")
-
-        population_settings = test_pop.return_population_settings()
-
-        self.assertIn("bse_options", population_settings)
-        self.assertTrue(population_settings["bse_options"]["metallicity"] == 0.02)
-        self.assertTrue(population_settings["bse_options"]["M_1"] == 10)
-
-        self.assertIn("grid_options", population_settings)
-        self.assertTrue(population_settings["grid_options"]["amt_cores"] == 2)
-
-        self.assertIn("custom_options", population_settings)
-        self.assertTrue(population_settings["custom_options"]["data_dir"] == "/tmp")
-
-    def test__return_binary_c_version_info(self):
-        """
-        Unittests for the function _return_binary_c_version_info
-        """
-
-        test_pop = Population()
-        binary_c_version_info = test_pop._return_binary_c_version_info(parsed=True)
-
-        self.assertTrue(isinstance(binary_c_version_info, dict))
-        self.assertIn("isotopes", binary_c_version_info)
-        self.assertIn("argpairs", binary_c_version_info)
-        self.assertIn("ensembles", binary_c_version_info)
-        self.assertIn("macros", binary_c_version_info)
-        self.assertIn("dt_limits", binary_c_version_info)
-        self.assertIn("nucleosynthesis_sources", binary_c_version_info)
-        self.assertIn("miscellaneous", binary_c_version_info)
-
-        self.assertIsNotNone(binary_c_version_info["argpairs"])
-        self.assertIsNotNone(binary_c_version_info["ensembles"])
-        self.assertIsNotNone(binary_c_version_info["macros"])
-        self.assertIsNotNone(binary_c_version_info["dt_limits"])
-        self.assertIsNotNone(binary_c_version_info["miscellaneous"])
-
-        if binary_c_version_info['miscellaneous']['NUCSYN'] == 'on':
-            self.assertIsNotNone(binary_c_version_info["isotopes"])
-            self.assertIsNotNone(binary_c_version_info["nucleosynthesis_sources"])
-
-
-
-    def test__return_binary_c_defaults(self):
-        """
-        Unittests for the function _return_binary_c_defaults
-        """
-
-        test_pop = Population()
-        binary_c_defaults = test_pop._return_binary_c_defaults()
-        self.assertIn("probability", binary_c_defaults)
-        self.assertIn("phasevol", binary_c_defaults)
-        self.assertIn("metallicity", binary_c_defaults)
-
-    def test_return_all_info(self):
-        """
-        Unittests for the function return_all_info
-        Not going to do too much tests here, just check if they are not empty
-        """
-
-        test_pop = Population()
-        all_info = test_pop.return_all_info()
-
-        self.assertIn("population_settings", all_info)
-        self.assertIn("binary_c_defaults", all_info)
-        self.assertIn("binary_c_version_info", all_info)
-        self.assertIn("binary_c_help_all", all_info)
-
-        self.assertNotEqual(all_info["population_settings"], {})
-        self.assertNotEqual(all_info["binary_c_defaults"], {})
-        self.assertNotEqual(all_info["binary_c_version_info"], {})
-        self.assertNotEqual(all_info["binary_c_help_all"], {})
-
-    def test_export_all_info(self):
-        """
-        Unittests for the function export_all_info
-        """
-
-        test_pop = Population()
-
-        test_pop.set(metallicity=0.02)
-        test_pop.set(M_1=10)
-        test_pop.set(amt_cores=2)
-        test_pop.set(data_dir=binary_c_temp_dir)
-
-        # datadir
-        settings_filename = test_pop.export_all_info(use_datadir=True)
-        self.assertTrue(os.path.isfile(settings_filename))
-        with open(settings_filename, "r") as f:
-            all_info = json.loads(f.read())
-
-        #
-        self.assertIn("population_settings", all_info)
-        self.assertIn("binary_c_defaults", all_info)
-        self.assertIn("binary_c_version_info", all_info)
-        self.assertIn("binary_c_help_all", all_info)
-
-        #
-        self.assertNotEqual(all_info["population_settings"], {})
-        self.assertNotEqual(all_info["binary_c_defaults"], {})
-        self.assertNotEqual(all_info["binary_c_version_info"], {})
-        self.assertNotEqual(all_info["binary_c_help_all"], {})
-
-        # custom name
-        # datadir
-        settings_filename = test_pop.export_all_info(
-            use_datadir=False,
-            outfile=os.path.join(binary_c_temp_dir, "example_settings.json"),
-        )
-        self.assertTrue(os.path.isfile(settings_filename))
-        with open(settings_filename, "r") as f:
-            all_info = json.loads(f.read())
-
-        #
-        self.assertIn("population_settings", all_info)
-        self.assertIn("binary_c_defaults", all_info)
-        self.assertIn("binary_c_version_info", all_info)
-        self.assertIn("binary_c_help_all", all_info)
-
-        #
-        self.assertNotEqual(all_info["population_settings"], {})
-        self.assertNotEqual(all_info["binary_c_defaults"], {})
-        self.assertNotEqual(all_info["binary_c_version_info"], {})
-        self.assertNotEqual(all_info["binary_c_help_all"], {})
-
-        # wrong filename
-        self.assertRaises(
-            ValueError,
-            test_pop.export_all_info,
-            use_datadir=False,
-            outfile=os.path.join(binary_c_temp_dir, "example_settings.txt"),
-        )
-
-    def test__cleanup_defaults(self):
-        """
-        Unittests for the function _cleanup_defaults
-        """
-
-        test_pop = Population()
-        cleaned_up_defaults = test_pop._cleanup_defaults()
-        self.assertNotIn("help_all", cleaned_up_defaults)
-
-    def test__increment_probtot(self):
-        """
-        Unittests for the function _increment_probtot
-        """
-
-        test_pop = Population()
-        test_pop._increment_probtot(0.5)
-        self.assertEqual(test_pop.grid_options["_probtot"], 0.5)
-
-    def test__increment_count(self):
-        """
-        Unittests for the function _increment_probtot
-        """
-
-        test_pop = Population()
-        test_pop._increment_count()
-        self.assertEqual(test_pop.grid_options["_count"], 1)
-
-    def test__dict_from_line_source_file(self):
-        """
-        Unittests for the function _dict_from_line_source_file
-        """
-
-        source_file = os.path.join(binary_c_temp_dir, "example_source_file.txt")
-
-        # write
-        with open(source_file, "w") as f:
-            f.write("binary_c M_1 10 metallicity 0.02\n")
-
-        test_pop = Population()
-
-        # readout
-        with open(source_file, "r") as f:
-            for line in f.readlines():
-                argdict = test_pop._dict_from_line_source_file(line)
-
-                self.assertTrue(argdict["M_1"] == 10)
-                self.assertTrue(argdict["metallicity"] == 0.02)
-
-    def test_evolve_single(self):
-        """
-        Unittests for the function evolve_single
-        """
+# class test_Population(unittest.TestCase):
+#     """
+#     Unittests for function
+#     """
 
-        CUSTOM_LOGGING_STRING_MASSES = """
-        Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
-            //
-            stardata->model.time, // 1
+#     def test_setup(self):
+#         test_pop = Population()
+
+#         self.assertTrue("orbital_period" in test_pop.defaults)
+#         self.assertTrue("metallicity" in test_pop.defaults)
+#         self.assertNotIn("help_all", test_pop.cleaned_up_defaults)
+#         self.assertEqual(test_pop.bse_options, {})
+#         self.assertEqual(test_pop.custom_options, {})
+#         self.assertEqual(test_pop.argline_dict, {})
+#         self.assertEqual(test_pop.persistent_data_memory_dict, {})
+#         self.assertTrue(test_pop.grid_options["parse_function"] == None)
+#         self.assertTrue(isinstance(test_pop.grid_options["_main_pid"], int))
+
+#     def test_set(self):
+#         test_pop = Population()
+#         test_pop.set(amt_cores=2)
+#         test_pop.set(M_1=10)
+#         test_pop.set(data_dir="/tmp/binary_c_python")
+#         test_pop.set(ensemble_filter_SUPERNOVAE=1)
+
+#         self.assertIn("data_dir", test_pop.custom_options)
+#         self.assertEqual(test_pop.custom_options["data_dir"], "/tmp/binary_c_python")
+
+#         #
+#         self.assertTrue(test_pop.bse_options["M_1"] == 10)
+#         self.assertTrue(test_pop.bse_options["ensemble_filter_SUPERNOVAE"] == 1)
+
+#         #
+#         self.assertTrue(test_pop.grid_options["amt_cores"] == 2)
+
+#     def test_cmdline(self):
+#         # copy old sys.argv values
+#         prev_sysargv = sys.argv.copy()
+
+#         # make a dummy cmdline arg input
+#         sys.argv = [
+#             "script",
+#             "--cmdline",
+#             "metallicity=0.0002 amt_cores=2 data_dir=/tmp/binary_c_python",
+#         ]
+
+#         # Set up population
+#         test_pop = Population()
+#         test_pop.set(data_dir="/tmp")
+
+#         # parse arguments
+#         test_pop.parse_cmdline()
+
+#         # metallicity
+#         self.assertTrue(isinstance(test_pop.bse_options["metallicity"], str))
+#         self.assertTrue(test_pop.bse_options["metallicity"] == "0.0002")
+
+#         # Amt cores
+#         self.assertTrue(isinstance(test_pop.grid_options["amt_cores"], int))
+#         self.assertTrue(test_pop.grid_options["amt_cores"] == 2)
+
+#         # datadir
+#         self.assertTrue(isinstance(test_pop.custom_options["data_dir"], str))
+#         self.assertTrue(test_pop.custom_options["data_dir"] == "/tmp/binary_c_python")
+
+#         # put back the other args if they exist
+#         sys.argv = prev_sysargv.copy()
+
+#     def test__return_argline(self):
+#         """
+#         Unittests for the function _return_argline
+#         """
+
+#         # Set up population
+#         test_pop = Population()
+#         test_pop.set(metallicity=0.02)
+#         test_pop.set(M_1=10)
+
+#         argline = test_pop._return_argline()
+#         self.assertTrue(argline == "binary_c M_1 10 metallicity 0.02")
+
+#         # custom dict
+#         argline2 = test_pop._return_argline(
+#             {"example_parameter1": 10, "example_parameter2": "hello"}
+#         )
+#         self.assertTrue(
+#             argline2 == "binary_c example_parameter1 10 example_parameter2 hello"
+#         )
+
+#     def test_add_grid_variable(self):
+#         """
+#         Unittests for the function add_grid_variable
+
+#         TODO: Should I test more here?
+#         """
+
+#         test_pop = Population()
+
+#         resolution = {"M_1": 10, "q": 10}
+
+#         test_pop.add_grid_variable(
+#             name="lnm1",
+#             longname="Primary mass",
+#             valuerange=[1, 100],
+#             resolution="{}".format(resolution["M_1"]),
+#             spacingfunc="const(math.log(1), math.log(100), {})".format(
+#                 resolution["M_1"]
+#             ),
+#             precode="M_1=math.exp(lnm1)",
+#             probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+#             dphasevol="dlnm1",
+#             parameter_name="M_1",
+#             condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+#         )
+
+#         test_pop.add_grid_variable(
+#             name="q",
+#             longname="Mass ratio",
+#             valuerange=["0.1/M_1", 1],
+#             resolution="{}".format(resolution["q"]),
+#             spacingfunc="const(0.1/M_1, 1, {})".format(resolution["q"]),
+#             probdist="flatsections(q, [{'min': 0.1/M_1, 'max': 1.0, 'height': 1}])",
+#             dphasevol="dq",
+#             precode="M_2 = q * M_1",
+#             parameter_name="M_2",
+#             condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+#         )
+
+#         self.assertIn("q", test_pop.grid_options["_grid_variables"])
+#         self.assertIn("lnm1", test_pop.grid_options["_grid_variables"])
+#         self.assertEqual(len(test_pop.grid_options["_grid_variables"]), 2)
+
+#     def test_return_population_settings(self):
+#         """
+#         Unittests for the function return_population_settings
+#         """
+
+#         test_pop = Population()
+#         test_pop.set(metallicity=0.02)
+#         test_pop.set(M_1=10)
+#         test_pop.set(amt_cores=2)
+#         test_pop.set(data_dir="/tmp")
+
+#         population_settings = test_pop.return_population_settings()
+
+#         self.assertIn("bse_options", population_settings)
+#         self.assertTrue(population_settings["bse_options"]["metallicity"] == 0.02)
+#         self.assertTrue(population_settings["bse_options"]["M_1"] == 10)
+
+#         self.assertIn("grid_options", population_settings)
+#         self.assertTrue(population_settings["grid_options"]["amt_cores"] == 2)
+
+#         self.assertIn("custom_options", population_settings)
+#         self.assertTrue(population_settings["custom_options"]["data_dir"] == "/tmp")
+
+#     def test__return_binary_c_version_info(self):
+#         """
+#         Unittests for the function _return_binary_c_version_info
+#         """
+
+#         test_pop = Population()
+#         binary_c_version_info = test_pop._return_binary_c_version_info(parsed=True)
+
+#         self.assertTrue(isinstance(binary_c_version_info, dict))
+#         self.assertIn("isotopes", binary_c_version_info)
+#         self.assertIn("argpairs", binary_c_version_info)
+#         self.assertIn("ensembles", binary_c_version_info)
+#         self.assertIn("macros", binary_c_version_info)
+#         self.assertIn("dt_limits", binary_c_version_info)
+#         self.assertIn("nucleosynthesis_sources", binary_c_version_info)
+#         self.assertIn("miscellaneous", binary_c_version_info)
+
+#         self.assertIsNotNone(binary_c_version_info["argpairs"])
+#         self.assertIsNotNone(binary_c_version_info["ensembles"])
+#         self.assertIsNotNone(binary_c_version_info["macros"])
+#         self.assertIsNotNone(binary_c_version_info["dt_limits"])
+#         self.assertIsNotNone(binary_c_version_info["miscellaneous"])
+
+#         if binary_c_version_info['miscellaneous']['NUCSYN'] == 'on':
+#             self.assertIsNotNone(binary_c_version_info["isotopes"])
+#             self.assertIsNotNone(binary_c_version_info["nucleosynthesis_sources"])
+
+#     def test__return_binary_c_defaults(self):
+#         """
+#         Unittests for the function _return_binary_c_defaults
+#         """
+
+#         test_pop = Population()
+#         binary_c_defaults = test_pop._return_binary_c_defaults()
+#         self.assertIn("probability", binary_c_defaults)
+#         self.assertIn("phasevol", binary_c_defaults)
+#         self.assertIn("metallicity", binary_c_defaults)
+
+#     def test_return_all_info(self):
+#         """
+#         Unittests for the function return_all_info
+#         Not going to do too much tests here, just check if they are not empty
+#         """
+
+#         test_pop = Population()
+#         all_info = test_pop.return_all_info()
+
+#         self.assertIn("population_settings", all_info)
+#         self.assertIn("binary_c_defaults", all_info)
+#         self.assertIn("binary_c_version_info", all_info)
+#         self.assertIn("binary_c_help_all", all_info)
+
+#         self.assertNotEqual(all_info["population_settings"], {})
+#         self.assertNotEqual(all_info["binary_c_defaults"], {})
+#         self.assertNotEqual(all_info["binary_c_version_info"], {})
+#         self.assertNotEqual(all_info["binary_c_help_all"], {})
+
+#     def test_export_all_info(self):
+#         """
+#         Unittests for the function export_all_info
+#         """
+
+#         test_pop = Population()
+
+#         test_pop.set(metallicity=0.02)
+#         test_pop.set(M_1=10)
+#         test_pop.set(amt_cores=2)
+#         test_pop.set(data_dir=binary_c_temp_dir)
+
+#         # datadir
+#         settings_filename = test_pop.export_all_info(use_datadir=True)
+#         self.assertTrue(os.path.isfile(settings_filename))
+#         with open(settings_filename, "r") as f:
+#             all_info = json.loads(f.read())
+
+#         #
+#         self.assertIn("population_settings", all_info)
+#         self.assertIn("binary_c_defaults", all_info)
+#         self.assertIn("binary_c_version_info", all_info)
+#         self.assertIn("binary_c_help_all", all_info)
+
+#         #
+#         self.assertNotEqual(all_info["population_settings"], {})
+#         self.assertNotEqual(all_info["binary_c_defaults"], {})
+#         self.assertNotEqual(all_info["binary_c_version_info"], {})
+#         self.assertNotEqual(all_info["binary_c_help_all"], {})
+
+#         # custom name
+#         # datadir
+#         settings_filename = test_pop.export_all_info(
+#             use_datadir=False,
+#             outfile=os.path.join(binary_c_temp_dir, "example_settings.json"),
+#         )
+#         self.assertTrue(os.path.isfile(settings_filename))
+#         with open(settings_filename, "r") as f:
+#             all_info = json.loads(f.read())
+
+#         #
+#         self.assertIn("population_settings", all_info)
+#         self.assertIn("binary_c_defaults", all_info)
+#         self.assertIn("binary_c_version_info", all_info)
+#         self.assertIn("binary_c_help_all", all_info)
+
+#         #
+#         self.assertNotEqual(all_info["population_settings"], {})
+#         self.assertNotEqual(all_info["binary_c_defaults"], {})
+#         self.assertNotEqual(all_info["binary_c_version_info"], {})
+#         self.assertNotEqual(all_info["binary_c_help_all"], {})
+
+#         # wrong filename
+#         self.assertRaises(
+#             ValueError,
+#             test_pop.export_all_info,
+#             use_datadir=False,
+#             outfile=os.path.join(binary_c_temp_dir, "example_settings.txt"),
+#         )
+
+#     def test__cleanup_defaults(self):
+#         """
+#         Unittests for the function _cleanup_defaults
+#         """
+
+#         test_pop = Population()
+#         cleaned_up_defaults = test_pop._cleanup_defaults()
+#         self.assertNotIn("help_all", cleaned_up_defaults)
+
+#     def test__increment_probtot(self):
+#         """
+#         Unittests for the function _increment_probtot
+#         """
+
+#         test_pop = Population()
+#         test_pop._increment_probtot(0.5)
+#         self.assertEqual(test_pop.grid_options["_probtot"], 0.5)
+
+#     def test__increment_count(self):
+#         """
+#         Unittests for the function _increment_probtot
+#         """
+
+#         test_pop = Population()
+#         test_pop._increment_count()
+#         self.assertEqual(test_pop.grid_options["_count"], 1)
+
+#     def test__dict_from_line_source_file(self):
+#         """
+#         Unittests for the function _dict_from_line_source_file
+#         """
+
+#         source_file = os.path.join(binary_c_temp_dir, "example_source_file.txt")
+
+#         # write
+#         with open(source_file, "w") as f:
+#             f.write("binary_c M_1 10 metallicity 0.02\n")
+
+#         test_pop = Population()
+
+#         # readout
+#         with open(source_file, "r") as f:
+#             for line in f.readlines():
+#                 argdict = test_pop._dict_from_line_source_file(line)
+
+#                 self.assertTrue(argdict["M_1"] == 10)
+#                 self.assertTrue(argdict["metallicity"] == 0.02)
+
+#     def test_evolve_single(self):
+#         """
+#         Unittests for the function evolve_single
+#         """
+
+#         CUSTOM_LOGGING_STRING_MASSES = """
+#         Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
+#             //
+#             stardata->model.time, // 1
             
-            // masses
-            stardata->common.zero_age.mass[0], //
-            stardata->common.zero_age.mass[1], //
+#             // masses
+#             stardata->common.zero_age.mass[0], //
+#             stardata->common.zero_age.mass[1], //
 
-            stardata->star[0].mass,
-            stardata->star[1].mass
-            );
-        """
+#             stardata->star[0].mass,
+#             stardata->star[1].mass
+#             );
+#         """
 
-        test_pop = Population()
-        test_pop.set(M_1=10, M_2=5, orbital_period=100000, metallicty=0.02, max_evolution_time = 15000)
+#         test_pop = Population()
+#         test_pop.set(M_1=10, M_2=5, orbital_period=100000, metallicty=0.02, max_evolution_time = 15000)
 
-        test_pop.set(C_logging_code=CUSTOM_LOGGING_STRING_MASSES)
+#         test_pop.set(C_logging_code=CUSTOM_LOGGING_STRING_MASSES)
 
-        output = test_pop.evolve_single()
+#         output = test_pop.evolve_single()
 
-        # 
-        self.assertTrue(len(output.splitlines())>1)
-        self.assertIn('TEST_CUSTOM_LOGGING_1', output)
+#         # 
+#         self.assertTrue(len(output.splitlines())>1)
+#         self.assertIn('TEST_CUSTOM_LOGGING_1', output)
 
 
-        # 
-        custom_logging_dict = {
-            'TEST_CUSTOM_LOGGING_2': ['star[0].mass', 'model.time']
-        }
-        test_pop_2 = Population()
-        test_pop_2.set(M_1=10, M_2=5, orbital_period=100000, metallicty=0.02, max_evolution_time = 15000)
+#         # 
+#         custom_logging_dict = {
+#             'TEST_CUSTOM_LOGGING_2': ['star[0].mass', 'model.time']
+#         }
+#         test_pop_2 = Population()
+#         test_pop_2.set(M_1=10, M_2=5, orbital_period=100000, metallicty=0.02, max_evolution_time = 15000)
 
-        test_pop_2.set(C_auto_logging=custom_logging_dict)
+#         test_pop_2.set(C_auto_logging=custom_logging_dict)
 
-        output_2 = test_pop_2.evolve_single()
+#         output_2 = test_pop_2.evolve_single()
 
-        # 
-        self.assertTrue(len(output_2.splitlines())>1)
-        self.assertIn('TEST_CUSTOM_LOGGING_2', output_2)
+#         # 
+#         self.assertTrue(len(output_2.splitlines())>1)
+#         self.assertIn('TEST_CUSTOM_LOGGING_2', output_2)
 
 class test_grid_evolve(unittest.TestCase):
     """
     Unittests for function Population.evolve()
     """
 
-    def test_grid_evolve_1_thread(self):
-        # test to see if 1 thread does all the systems
-
-        test_pop_evolve_1_thread = Population()
-        test_pop_evolve_1_thread.set(amt_cores=1, verbosity=1, M_2=1, orbital_period=100000)
-
-        resolution = {"M_1": 10}
-
-        test_pop_evolve_1_thread.add_grid_variable(
-            name="lnm1",
-            longname="Primary mass",
-            valuerange=[1, 100],
-            resolution="{}".format(resolution["M_1"]),
-            spacingfunc="const(math.log(1), math.log(100), {})".format(
-                resolution["M_1"]
-            ),
-            precode="M_1=math.exp(lnm1)",
-            probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
-            dphasevol="dlnm1",
-            parameter_name="M_1",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        analytics = test_pop_evolve_1_thread.evolve()
-        self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10)
-        self.assertTrue(analytics['total_count']==10)
-
-    def test_grid_evolve_2_threads(self):
-        # test to see if 1 thread does all the systems
-
-        test_pop = Population()
-        test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
-
-        resolution = {"M_1": 10}
-
-        test_pop.add_grid_variable(
-            name="lnm1",
-            longname="Primary mass",
-            valuerange=[1, 100],
-            resolution="{}".format(resolution["M_1"]),
-            spacingfunc="const(math.log(1), math.log(100), {})".format(
-                resolution["M_1"]
-            ),
-            precode="M_1=math.exp(lnm1)",
-            probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
-            dphasevol="dlnm1",
-            parameter_name="M_1",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        analytics = test_pop.evolve()
-        self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
-        self.assertTrue(analytics['total_count']==10)
-
-    def test_grid_evolve_2_threads_with_custom_logging(self):
+    # def test_grid_evolve_1_thread(self):
+    #     # test to see if 1 thread does all the systems
+
+    #     test_pop_evolve_1_thread = Population()
+    #     test_pop_evolve_1_thread.set(amt_cores=1, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     resolution = {"M_1": 10}
+
+    #     test_pop_evolve_1_thread.add_grid_variable(
+    #         name="lnm1",
+    #         longname="Primary mass",
+    #         valuerange=[1, 100],
+    #         resolution="{}".format(resolution["M_1"]),
+    #         spacingfunc="const(math.log(1), math.log(100), {})".format(
+    #             resolution["M_1"]
+    #         ),
+    #         precode="M_1=math.exp(lnm1)",
+    #         probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+    #         dphasevol="dlnm1",
+    #         parameter_name="M_1",
+    #         condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #     )
+
+    #     analytics = test_pop_evolve_1_thread.evolve()
+    #     self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10)
+    #     self.assertTrue(analytics['total_count']==10)
+
+    # def test_grid_evolve_2_threads(self):
+    #     # test to see if 1 thread does all the systems
+
+    #     test_pop = Population()
+    #     test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     resolution = {"M_1": 10}
+
+    #     test_pop.add_grid_variable(
+    #         name="lnm1",
+    #         longname="Primary mass",
+    #         valuerange=[1, 100],
+    #         resolution="{}".format(resolution["M_1"]),
+    #         spacingfunc="const(math.log(1), math.log(100), {})".format(
+    #             resolution["M_1"]
+    #         ),
+    #         precode="M_1=math.exp(lnm1)",
+    #         probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+    #         dphasevol="dlnm1",
+    #         parameter_name="M_1",
+    #         condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #     )
+
+    #     analytics = test_pop.evolve()
+    #     self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
+    #     self.assertTrue(analytics['total_count']==10)
+
+    # def test_grid_evolve_2_threads_with_custom_logging(self):
+    #     # test to see if 1 thread does all the systems
+
+    #     test_pop = Population()
+    #     test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     resolution = {"M_1": 10}
+
+    #     test_pop.add_grid_variable(
+    #         name="lnm1",
+    #         longname="Primary mass",
+    #         valuerange=[1, 100],
+    #         resolution="{}".format(resolution["M_1"]),
+    #         spacingfunc="const(math.log(1), math.log(100), {})".format(
+    #             resolution["M_1"]
+    #         ),
+    #         precode="M_1=math.exp(lnm1)",
+    #         probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+    #         dphasevol="dlnm1",
+    #         parameter_name="M_1",
+    #         condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #     )
+
+    #     analytics = test_pop.evolve()
+    #     self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
+    #     self.assertTrue(analytics['total_count']==10)
+
+    # def test_grid_evolve_with_condition_error(self):
+    #     # Test to see if we can catch the errors correctly. 
+
+    #     test_pop = Population()
+    #     test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     # Set the amt of failed systems that each thread will log
+    #     test_pop.set(failed_systems_threshold=4)
+
+    #     CUSTOM_LOGGING_STRING_WITH_EXIT = """
+    #     Exit_binary_c(BINARY_C_NORMAL_EXIT, "testing exits");
+    #     Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
+    #         //
+    #         stardata->model.time, // 1
+            
+    #         // masses
+    #         stardata->common.zero_age.mass[0], //
+    #         stardata->common.zero_age.mass[1], //
+
+    #         stardata->star[0].mass,
+    #         stardata->star[1].mass
+    #         );
+    #     """
+
+    #     test_pop.set(C_logging_code=CUSTOM_LOGGING_STRING_WITH_EXIT)
+
+    #     resolution = {"M_1": 10}
+    #     test_pop.add_grid_variable(
+    #         name="lnm1",
+    #         longname="Primary mass",
+    #         valuerange=[1, 100],
+    #         resolution="{}".format(resolution["M_1"]),
+    #         spacingfunc="const(math.log(1), math.log(100), {})".format(
+    #             resolution["M_1"]
+    #         ),
+    #         precode="M_1=math.exp(lnm1)",
+    #         probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+    #         dphasevol="dlnm1",
+    #         parameter_name="M_1",
+    #         condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #     )
+
+    #     analytics = test_pop.evolve()
+    #     self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
+    #     self.assertLess(np.abs(analytics['failed_prob']-0.1503788456014623), 1e-10) # 
+    #     self.assertEqual(analytics['failed_systems_error_codes'], [0])
+    #     self.assertTrue(analytics['total_count']==10)
+    #     self.assertTrue(analytics['failed_count']==10)
+    #     self.assertTrue(analytics['errors_found']==True)
+    #     self.assertTrue(analytics['errors_exceeded']==True)
+
+    #     # test to see if 1 thread does all the systems
+
+    #     test_pop = Population()
+    #     test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     resolution = {"M_1": 10, "q": 2}
+
+    #     test_pop.add_grid_variable(
+    #         name="lnm1",
+    #         longname="Primary mass",
+    #         valuerange=[1, 100],
+    #         resolution="{}".format(resolution["M_1"]),
+    #         spacingfunc="const(math.log(1), math.log(100), {})".format(
+    #             resolution["M_1"]
+    #         ),
+    #         precode="M_1=math.exp(lnm1)",
+    #         probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
+    #         dphasevol="dlnm1",
+    #         parameter_name="M_1",
+    #         condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #     )
+
+    #     test_pop.add_grid_variable(
+    #         name="q",
+    #         longname="Mass ratio",
+    #         valuerange=["0.1/M_1", 1],
+    #         resolution="{}".format(resolution["q"]),
+    #         spacingfunc="const(0.1/M_1, 1, {})".format(resolution["q"]),
+    #         probdist="flatsections(q, [{'min': 0.1/M_1, 'max': 1.0, 'height': 1}])",
+    #         dphasevol="dq",
+    #         precode="M_2 = q * M_1",
+    #         parameter_name="M_2",
+    #         # condition="M_1 in dir()",  # Impose a condition on this grid variable. Mostly for a check for yourself
+    #         condition="'random_var' in dir()", # This will raise an error because random_var is not defined. 
+    #     )
+
+    #     self.assertRaises(ValueError, test_pop.evolve)
+
+    # def test_grid_evolve_no_grid_variables(self):
+    #     # test to see if 1 thread does all the systems
+
+    #     test_pop = Population()
+    #     test_pop.set(amt_cores=1, verbosity=1, M_2=1, orbital_period=100000)
+
+    #     resolution = {"M_1": 10}
+    #     self.assertRaises(ValueError, test_pop.evolve)
+
+    def test_grid_evolve_2_threads_with_ensemble(self):
         # test to see if 1 thread does all the systems
 
         test_pop = Population()
-        test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
+        test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000, ensemble=1, ensemble_defer=1, ensemble_filters_off=1, ensemble_filter_STELLAR_TYPE_COUNTS=1)
+        test_pop.set(data_dir=binary_c_temp_dir, ensemble_output_name="ensemble_output.json", combine_ensemble_with_thread_joining=False)
 
         resolution = {"M_1": 10}
 
@@ -485,108 +609,10 @@ class test_grid_evolve(unittest.TestCase):
         )
 
         analytics = test_pop.evolve()
-        self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
-        self.assertTrue(analytics['total_count']==10)
-
-
-    def test_grid_evolve_with_condition_error(self):
-        # Test to see if we can catch the errors correctly. 
-
-        test_pop = Population()
-        test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
-
-        # Set the amt of failed systems that each thread will log
-        test_pop.set(failed_systems_threshold=4)
-
-        CUSTOM_LOGGING_STRING_WITH_EXIT = """
-        Exit_binary_c(BINARY_C_NORMAL_EXIT, "testing exits");
-        Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
-            //
-            stardata->model.time, // 1
-            
-            // masses
-            stardata->common.zero_age.mass[0], //
-            stardata->common.zero_age.mass[1], //
-
-            stardata->star[0].mass,
-            stardata->star[1].mass
-            );
-        """
-
-        test_pop.set(C_logging_code=CUSTOM_LOGGING_STRING_WITH_EXIT)
-
-        resolution = {"M_1": 10}
-        test_pop.add_grid_variable(
-            name="lnm1",
-            longname="Primary mass",
-            valuerange=[1, 100],
-            resolution="{}".format(resolution["M_1"]),
-            spacingfunc="const(math.log(1), math.log(100), {})".format(
-                resolution["M_1"]
-            ),
-            precode="M_1=math.exp(lnm1)",
-            probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
-            dphasevol="dlnm1",
-            parameter_name="M_1",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        analytics = test_pop.evolve()
-        self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
-        self.assertLess(np.abs(analytics['failed_prob']-0.1503788456014623), 1e-10) # 
-        self.assertEqual(analytics['failed_systems_error_codes'], [0])
-        self.assertTrue(analytics['total_count']==10)
-        self.assertTrue(analytics['failed_count']==10)
-        self.assertTrue(analytics['errors_found']==True)
-        self.assertTrue(analytics['errors_exceeded']==True)
-
-        # test to see if 1 thread does all the systems
-
-        test_pop = Population()
-        test_pop.set(amt_cores=2, verbosity=1, M_2=1, orbital_period=100000)
 
-        resolution = {"M_1": 10, "q": 2}
-
-        test_pop.add_grid_variable(
-            name="lnm1",
-            longname="Primary mass",
-            valuerange=[1, 100],
-            resolution="{}".format(resolution["M_1"]),
-            spacingfunc="const(math.log(1), math.log(100), {})".format(
-                resolution["M_1"]
-            ),
-            precode="M_1=math.exp(lnm1)",
-            probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 100, -1.3, -2.3, -2.3)*M_1",
-            dphasevol="dlnm1",
-            parameter_name="M_1",
-            condition="",  # Impose a condition on this grid variable. Mostly for a check for yourself
-        )
-
-        test_pop.add_grid_variable(
-            name="q",
-            longname="Mass ratio",
-            valuerange=["0.1/M_1", 1],
-            resolution="{}".format(resolution["q"]),
-            spacingfunc="const(0.1/M_1, 1, {})".format(resolution["q"]),
-            probdist="flatsections(q, [{'min': 0.1/M_1, 'max': 1.0, 'height': 1}])",
-            dphasevol="dq",
-            precode="M_2 = q * M_1",
-            parameter_name="M_2",
-            # condition="M_1 in dir()",  # Impose a condition on this grid variable. Mostly for a check for yourself
-            condition="'random_var' in dir()", # This will raise an error because random_var is not defined. 
-        )
-
-        self.assertRaises(ValueError, test_pop.evolve)
-
-    def test_grid_evolve_no_grid_variables(self):
-        # test to see if 1 thread does all the systems
-
-        test_pop = Population()
-        test_pop.set(amt_cores=1, verbosity=1, M_2=1, orbital_period=100000)
-
-        resolution = {"M_1": 10}
-        self.assertRaises(ValueError, test_pop.evolve)
 
+        # self.assertLess(np.abs(analytics['total_probability']-0.1503788456014623), 1e-10) # 
+        # self.assertTrue(analytics['total_count']==10)
 
 
 if __name__ == "__main__":