diff --git a/binarycpython/tests/test_distributions.py b/binarycpython/tests/test_distributions.py index def8ba24139bf244c114eaa73eae8abb8873d969..4c1204f09dec936dd18a570e096f9841f412a113 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 9e0840e3daad8bd7fc6062f8973302ec581be31f..02211402f51dc14977c92ee0ea08fc9f157fded9 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"],