From 7bd358ad833129c7b47092b3dbac9f83e2e81fe9 Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Wed, 2 Sep 2020 20:19:29 +0100 Subject: [PATCH] updated the to handle the keywords to deal with %d and some extra small things --- binarycpython/utils/grid.py | 148 +++++++++---------- binarycpython/utils/grid_options_defaults.py | 2 +- 2 files changed, 71 insertions(+), 79 deletions(-) diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py index 889145c68..4d84ae5ff 100644 --- a/binarycpython/utils/grid.py +++ b/binarycpython/utils/grid.py @@ -111,7 +111,10 @@ class Population: def set_bse_option(self, key, arg): """ Setter for the BSE options. + + # TODO: Put a check here that compares it to the defaults and says something """ + self.bse_options[key] = arg def set(self, **kwargs): @@ -126,19 +129,26 @@ class Population: in the self.grid_options If neither of above is met; the key and the value get stored in a custom_options dict. - - TODO: catch those parameter names that contain an %d """ + # Select the params that end with %d + special_params = [el for el in list(self.defaults.keys()) if el.endswith('%d')] + + # Go over all the input for key in kwargs: # Filter out keys for the bse_options if key in self.defaults.keys(): - verbose_print("adding: {}={} to BSE_options".format(key, kwargs[key]), self.grid_options["verbose"], 1) + verbose_print("adding: {}={} to BSE_options".format(key, kwargs[key]), self.grid_options["verbosity"], 1) + self.bse_options[key] = kwargs[key] + + # Extra check to check if the key fits one of parameter names that end with %d + elif any([True if (key.startswith(param[:-2]) and len(param[:-2]) < len(key)) else False for param in special_params]): + verbose_print("adding: {}={} to BSE_options by catching the %d".format(key, kwargs[key]), self.grid_options["verbosity"], 1) self.bse_options[key] = kwargs[key] # Filter out keys for the grid_options elif key in self.grid_options.keys(): - verbose_print("adding: {}={} to grid_options".format(key, kwargs[key]), self.grid_options["verbose"], 1) + verbose_print("adding: {}={} to grid_options".format(key, kwargs[key]), self.grid_options["verbosity"], 1) self.grid_options[key] = kwargs[key] # The of the keys go into a custom_options dict @@ -168,7 +178,7 @@ class Population: # How its set up now is that as input you need to give --cmdline "metallicity=0.002" # Its checked if this exists and handled accordingly. if args.cmdline: - verbose_print("Found cmdline args. Parsing them now", self.grid_options["verbose"], 1) + verbose_print("Found cmdline args. Parsing them now", self.grid_options["verbosity"], 1) # Grab the input and split them up, while accepting only non-empty entries cmdline_args = args.cmdline @@ -285,7 +295,7 @@ class Population: # Load it into the grid_options self.grid_options["grid_variables"][grid_variable["name"]] = grid_variable - verbose_print("Added grid variable: {}".format(json.dumps(grid_variable, indent=4)), self.grid_options["verbose"], 1) + verbose_print("Added grid variable: {}".format(json.dumps(grid_variable, indent=4)), self.grid_options["verbosity"], 1) ################################################### # Return functions @@ -378,6 +388,8 @@ class Population: TODO: Fix to write things to the directory. which options do which etc TODO: theres flawed logic here. rewrite this part pls + + TODO: consider actually just removing the whole 'output to file' part and let the user do this. """ all_info = self.return_all_info( @@ -390,19 +402,6 @@ class Population: # Copy dict all_info_cleaned = copy.deepcopy(all_info) - # # Clean the all_info_dict: (i.e. transform the function objects to strings) - # if all_info_cleaned.get("population_settings", None): - # if all_info_cleaned["population_settings"]["grid_options"][ - # "parse_function" - # ]: - # all_info_cleaned["population_settings"]["grid_options"][ - # "parse_function" - # ] = str( - # all_info_cleaned["population_settings"]["grid_options"][ - # "parse_function" - # ] - # ) - if use_datadir: if not self.custom_options.get("base_filename", None): base_name = "simulation_{}".format( @@ -420,7 +419,7 @@ class Population: self.custom_options["data_dir"], settings_name ) - verbose_print("Writing settings to {}".format(settings_fullname), self.grid_options["verbose"], 1) + verbose_print("Writing settings to {}".format(settings_fullname), self.grid_options["verbosity"], 1) # if not outfile.endswith('json'): with open(settings_fullname, "w") as file: file.write( @@ -428,10 +427,10 @@ class Population: ) else: - verbose_print("Writing settings to {}".format(outfile), self.grid_options["verbose"], 1) + verbose_print("Writing settings to {}".format(outfile), self.grid_options["verbosity"], 1) # if not outfile.endswith('json'): with open(outfile, "w") as file: - file.write(json.dumps(all_info_cleaned, indent=4)) + file.write(json.dumps(all_info_cleaned, indent=4, default=binaryc_json_serializer)) def set_custom_logging(self): """ @@ -440,12 +439,12 @@ class Population: """ # C_logging_code gets priority of C_autogen_code - verbose_print("Creating and loading custom logging functionality", self.grid_options["verbose"], 1) + verbose_print("Creating and loading custom logging functionality", self.grid_options["verbosity"], 1) if self.grid_options["C_logging_code"]: # Generate entire shared lib code around logging lines custom_logging_code = binary_c_log_code( self.grid_options["C_logging_code"], - verbose=self.grid_options["verbose"], + verbose=self.grid_options["verbosity"], ) # Load memory adress @@ -453,19 +452,19 @@ class Population: self.grid_options["custom_logging_func_memaddr"], self.grid_options["custom_logging_shared_library_file"], ) = create_and_load_logging_function( - custom_logging_code, verbose=self.grid_options["verbose"] + custom_logging_code, verbose=self.grid_options["verbosity"] ) elif self.grid_options["C_auto_logging"]: # Generate real logging code logging_line = autogen_C_logging_code( self.grid_options["C_auto_logging"], - verbose=self.grid_options["verbose"], + verbose=self.grid_options["verbosity"], ) # Generate entire shared lib code around logging lines custom_logging_code = binary_c_log_code( - logging_line, verbose=self.grid_options["verbose"] + logging_line, verbose=self.grid_options["verbosity"] ) # Load memory adress @@ -473,7 +472,7 @@ class Population: self.grid_options["custom_logging_func_memaddr"], self.grid_options["custom_logging_shared_library_file"], ) = create_and_load_logging_function( - custom_logging_code, verbose=self.grid_options["verbose"] + custom_logging_code, verbose=self.grid_options["verbosity"] ) ################################################### @@ -484,8 +483,6 @@ class Population: """ Function that loads a set amount (amt_cores) of persistent data memory adresses to pass to binary_c. - - TODO: fix the function """ for thread_nr in self.grid_options["amt_cores"]: @@ -493,7 +490,7 @@ class Population: self.persistent_data_memory_dict[thread_nr] = persistent_data_memaddr verbose_print("Created the following dict with persistent memaddresses: {}".format(self.persistent_data_memory_dict), self.grid_options["verbosity"], 1) - def free_persistent_data_memory_and_combine_results(self): + def free_persistent_data_memory_and_combine_results_and_output(self): """ Function that loads a set amount of persisten data memory adresses to pass to binary_c. @@ -520,7 +517,9 @@ class Population: full_output_filename = os.path.join(self.custom_options["data_dir"], self.custom_options["ensemble_output_name"]) verbose_print("Writing ensemble output to {}".format(full_output_filename), self.grid_options["verbosity"], 1) - + # Output to dir: + with open(full_output_filename, 'w') as output_file: + output_file.write(json.dumps(combined_ensemble_json, indent=4)) ################################################### # Evolution functions @@ -528,7 +527,11 @@ class Population: def setup(self): """ - Function to set up the necessary stuff for the population evolution: + Function to set up the necessary stuff for the population evolution. + + The idea is to do all the stuff that is necessary for a population to run. + Since we have different methods of running a population, this setup function + will do different things depending on different settings # TODO: Make other kinds of populations possible. i.e, read out type of grid, and set up accordingly @@ -548,6 +551,17 @@ class Population: ### Load store self.grid_options["store_memaddr"] = binary_c_python_api.return_store("") + ### ensemble: + ## Load persistent_data_memaddr if necessary: + if self.bse_options["ensemble"] == 1: + self.load_persistent_data_memory_dict() + + ## check the settings: + if self.bse_options["ensemble"] == 1: + if not self.bse_options["ensemble_defer"] == 1: + verbose_print("Error, if you want to run an ensemble in a population, the output needs to be deferred", self.grid_options["verbosity"], 0) + raise ValueError + ####################### # Dry run and getting starcount self.grid_options["probtot"] = 0 @@ -557,10 +571,13 @@ class Population: print("Error: you havent defined any grid variables! Aborting") raise ValueError + # Set up the grid code with a dry run option to see total probability self.generate_grid_code(dry_run=True) + # Load the grid code self.load_grid_function() + # Do a dry run self.dry_run() print( @@ -597,14 +614,22 @@ class Population: - unload dry grid function/module """ + # Output the ensemble if necessary: + if self.bse_options["ensemble"] == 1: + self.free_persistent_data_memory_and_combine_results_and_output() + # Reset values self.grid_options["count"] = 0 self.grid_options["probtot"] = 0 self.grid_options["system_generator"] = None # Remove files + # Unload functions + # Unload store + binary_c_python_api.binary_c_free_store_memaddr(self.grid_options["store_memaddr"]) + def evolve_system_mp(self, binary_cmdline_string): """ Function that the multiprocessing evolution method calls to evolve a system @@ -652,7 +677,8 @@ class Population: # Get argument line argline = self.return_argline(self.bse_options) - print("Running {}".format(argline)) + verbose_print("Running {}".format(argline), self.grid_options['verbosity'], 1) + # Run system out = binary_c_python_api.run_system( argstring=argline, @@ -768,40 +794,6 @@ class Population: # Clean up code: remove files, unset values. self.cleanup() - ################################################### - # Function to test evolution algorithms - ################################################### - - def test_evolve_single(self): - """ - Function to test the evolution of a system. Calls the api binding directly. - """ - - verbose_print("running a single system as a test", self.grid_options["verbose"], 1) - - m_1 = 15.0 # Msun - m_2 = 14.0 # Msun - separation = 0 # 0 = ignored, use period - orbital_period = 4530.0 # days - eccentricity = 0.0 - metallicity = 0.02 - max_evolution_time = 15000 - argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g}\ - eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g}".format( - m_1, - m_2, - separation, - orbital_period, - eccentricity, - metallicity, - max_evolution_time, - ) - - output = binary_c_python_api.run_system(argstring) - - print("\n\nBinary_c output:") - print(output) - ################################################### # Gridcode functions # @@ -830,7 +822,7 @@ class Population: Results in a generated file that contains a system_generator function. """ - verbose_print("Generating grid code", self.grid_options["verbose"], 1) + verbose_print("Generating grid code", self.grid_options["verbosity"], 1) # Some local values code_string = "" @@ -1193,7 +1185,7 @@ class Population: # Stop of code generation. Here the code is saved and written # Save the gridcode to the grid_options - verbose_print("Saving grid code to grid_options", self.grid_options["verbose"], 1) + verbose_print("Saving grid code to grid_options", self.grid_options["verbosity"], 1) self.grid_options["code_string"] = code_string @@ -1203,7 +1195,7 @@ class Population: ) self.grid_options["gridcode_filename"] = gridcode_filename - verbose_print("Writing grid code to {}".format(gridcode_filename), self.grid_options["verbose"], 1) + verbose_print("Writing grid code to {}".format(gridcode_filename), self.grid_options["verbosity"], 1) with open(gridcode_filename, "w") as file: file.write(code_string) @@ -1219,7 +1211,7 @@ class Population: message="Loading grid code function from {}".format( self.grid_options["gridcode_filename"] ), - verbosity=self.grid_options["verbose"], minimal_verbosity=1) + verbosity=self.grid_options["verbosity"], minimal_verbosity=1) spec = importlib.util.spec_from_file_location( "binary_c_python_grid", @@ -1231,7 +1223,7 @@ class Population: self.grid_options["system_generator"] = generator - verbose_print("Grid code loaded", self.grid_options["verbose"], 1) + verbose_print("Grid code loaded", self.grid_options["verbosity"], 1) def dry_run(self): """ @@ -1253,7 +1245,7 @@ class Population: """ # Define frequency - if self.grid_options["verbose"] == 1: + if self.grid_options["verbosity"] == 1: print_freq = 1 else: print_freq = 10 @@ -1394,7 +1386,7 @@ class Population: """ if evol_type == "single": - verbose_print("Cleaning up the custom logging stuff. type: single", self.grid_options["verbose"], 1) + verbose_print("Cleaning up the custom logging stuff. type: single", self.grid_options["verbosity"], 1) # TODO: Unset custom logging code @@ -1405,11 +1397,11 @@ class Population: if self.grid_options["custom_logging_shared_library_file"]: remove_file( self.grid_options["custom_logging_shared_library_file"], - self.grid_options["verbose"], + self.grid_options["verbosity"], ) if evol_type == "population": - verbose_print("Cleaning up the custom logging stuffs. type: population", self.grid_options["verbose"], 1) + verbose_print("Cleaning up the custom logging stuffs. type: population", self.grid_options["verbosity"], 1) # TODO: make sure that these also work. not fully sure if necessary tho. # whether its a single file, or a dict of files/memaddresses @@ -1444,7 +1436,7 @@ class Population: # Set up logger self.logger = logging.getLogger('binary_c_python_logger') - self.logger.setLevel(self.grid_options["verbose"]) + self.logger.setLevel(self.grid_options["verbosity"]) # Reset handlers self.logger.handlers = [] diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index 68eeef0f9..bed3b9fab 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -19,7 +19,7 @@ grid_options_defaults_dict = { ########################## # Execution log: ########################## - "verbose": 0, # Level of verbosity of the simulation. 0=INFO, + "verbosity": 0, # Level of verbosity of the simulation. 0=INFO, "log_file": os.path.join(temp_dir(), 'binary_c_python.log'), # Set to None to not log to file. The directory will be created ########################## # binary_c files -- GitLab