Commit 7bd358ad authored by David Hendriks's avatar David Hendriks
Browse files

updated the to handle the keywords to deal with %d and some extra small things

parent 448bea8f
Loading
Loading
Loading
Loading
+70 −78
Original line number Diff line number Diff line
@@ -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 = []
+1 −1
Original line number Diff line number Diff line
@@ -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