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

adding functionality to load binary_c calls from a sourcefile

parent 2fd73538
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -727,7 +727,7 @@ def inspect_dict(dict_1, indent=0, print_structure=True):
        if print_structure:
            print("\t" * indent, key, type(value))
        if isinstance(value, dict):
            structure_dict[key] = inspect_dict(value, indent=indent + 1)
            structure_dict[key] = inspect_dict(value, indent=indent + 1, print_structure=print_structure)
    return structure_dict


+173 −30
Original line number Diff line number Diff line
@@ -521,6 +521,85 @@ class Population:
                custom_logging_code, verbose=self.grid_options["verbosity"]
            )

    ###################################################
    # Sourcefile functions
    ###################################################

    def load_source_file(self, check=False):
        """
        Function that loads the source_file that contains a binary_c calls
        """

        if not os.path.isfile(self.grid_options["source_file_filename"]):
            verbose_print("Source file doesnt exist", self.grid_options["verbosity"], 0)

        verbose_print(
            message="Loading source file from {}".format(
                self.grid_options["gridcode_filename"]
            ),
            verbosity=self.grid_options["verbosity"],
            minimal_verbosity=1,
        )

        # We can choose to perform a check on the sourcefile, which checks if the lines start with 'binary_c'
        if check:
            source_file_check_filehandle = open(self.grid_options["source_file_filename"], 'r')
            for line in source_file_check_filehandle:
                if not line.startswith('binary_c')
                    failed = True
                    break
            if failed:
                verbose_print("Error, sourcefile contains lines that do not start with binary_c", self.grid_options["verbosity"], 0)
                raise ValueError

        source_file_filehandle = open(self.grid_options["source_file_filename"], 'r')

        self.grid_options["system_generator"] = source_file_filehandle

        verbose_print("Source file loaded", self.grid_options["verbosity"], 1)

    def dict_from_line_source_file(self):
        """
        Function that creates a dict from a binary_c argline 
        """

        if line.startswith("binary_c "):
            line = line.replace("binary_c ", "")

        split_line = line.split()
        arg_dict = {}

        for i in range(0, len(split_line), 2):
            if "." in split_line[i+1]:
                arg_dict[split_line[i]] = float(split_line[i + 1])
            else: 
                arg_dict[split_line[i]] = int(split_line[i + 1])

        return arg_dict

    def dry_run_source_file(self):
        """
        Function to go through the source_file and count the amount of lines and the total probability
        """

        system_generator = self.grid_options["system_generator"]

        total_starcount = 0
        total_probability = 0

        contains_probability = False

        for line in system_generator:
            


            total_starcount += 1


        total_starcount = system_generator(self)
        self.grid_options["total_starcount"] = total_starcount


    ###################################################
    # Ensemble functions
    ###################################################
@@ -637,6 +716,8 @@ class Population:
                )
                raise ValueError

        # Check which type of population generation
        if grid_options["population_type_options"] == "grid":
            #######################
            # Dry run and getting starcount
            self.grid_options["probtot"] = 0
@@ -676,6 +757,43 @@ class Population:
            #
            self.load_grid_function()

        # Source file
        elif grid_options["population_type_options"] == "source_file":
            #######################
            # Dry run and getting starcount
            self.grid_options["probtot"] = 0

            # Load the grid code
            self.load_source_file_function()

            # Do a dry run
            self.dry_run_source_file()

            print(
                "Total starcount for this run will be: {}".format(
                    self.grid_options["total_starcount"]
                )
            )

            #######################
            # Reset values and prepare the grid function
            self.grid_options[
                "probtot"
            ] = 0  # To make sure that the values are reset. TODO: fix this in a cleaner way
            self.grid_options[
                "start_time_evolution"
            ] = time.time()  # Setting start time of grid

            #
            self.load_source_file_function(dry_run=False)

            #
            self.load_grid_function()





        #######

    def cleanup(self):
@@ -1391,6 +1509,31 @@ class Population:
        # warning; dont use yet. not fully tested.
        """

        # Check if there is no compiled grid yet. If not, lets try to build it first.
        if not self.grid_options["system_generator"]:

            ## check the settings:
            if self.bse_options.get("ensemble", None):
                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

            # Put in check
            if len(self.grid_options["grid_variables"]) == 0:
                print("Error: you havent defined any grid variables! Aborting")
                raise ValueError

            #
            self.generate_grid_code(dry_run=False)

            #
            self.load_grid_function()

        if self.grid_options["system_generator"]:
            # Check if there is an output dir configured
            if self.custom_options.get("data_dir", None):
@@ -1435,7 +1578,7 @@ class Population:
                    file.write(binary_cmdline_string + "\n")
        else:
            print("Error. No grid function found!")
            raise KeyError
            raise ValueError

    def cleanup_defaults(self):
        """
+4 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ grid_options_defaults_dict = {
    # binary_c files
    ##########################
    "binary_c_executable": os.path.join(
        os.environ["BINARY_C"], "binary_c-config"
        os.environ["BINARY_C"], "binary_c"
    ),  # TODO: make this more robust
    "binary_c_shared_library": os.path.join(
        os.environ["BINARY_C"], "src", "libbinary_c.so"
@@ -69,7 +69,9 @@ grid_options_defaults_dict = {
    "population_type": "grid",  #
    "population_type_options": [
        "grid",
    ],  # Available choices for type of population generation # TODO: fill later with monte carlo, source file etc
        "source_file",
    ],  # Available choices for type of population generation # TODO: fill later with monte carlo etc
    "source_file_filename": None # filename for the source
    "count": 0,  # total count of systems
    "probtot": 0,  # total probability
    "weight": 1.0,  # weighting for the probability
+20 −4
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ def test_return_persistent_data_memaddr():
    print("Binary_c output:")
    print(textwrap.indent(str(output), "\t"))

    assert isinstance(output, int), "memory adress has to be an integer"
    assert output != 0, "memory adress seems not to have a correct value"

def test_passing_persistent_data_to_run_system():
    # Function to test the passing of the persistent data memoery adress, and having ensemble_defer = True
@@ -286,6 +288,12 @@ def test_adding_ensemble_output():
    and output on the second run
    """

    #
    # print(json.dumps(test_1_merged_dict, indent=4))
    # print(json.dumps(test_2_json, indent=4))



    #
    assert inspect_dict(test_1_merged_dict, print_structure=False) == inspect_dict(
        test_2_json, print_structure=False
@@ -293,7 +301,7 @@ def test_adding_ensemble_output():
    # assert inspect_dict(test_1_merged_dict, print_structure=False) == inspect_dict(test_3_json, print_structure=False), assert_message_2


def combine_with_empty_json():
def test_combine_with_empty_json():
    argstring_1 = return_argstring(defer_ensemble=0)
    output_1 = binary_c_python_api.run_system(argstring=argstring_1)
    ensemble_jsons_1 = [
@@ -351,12 +359,20 @@ def test_free_and_json_output():
    # ensemble_jsons_1 = [line for line in output_1.splitlines() if line.startswith("ENSEMBLE_JSON")]
    # json_1 = json.loads(ensemble_jsons_1[0][len("ENSEMBLE_JSON "):], cls=binarycDecoder)

def test_all():
    test_return_persistent_data_memaddr()
    test_passing_persistent_data_to_run_system()
    test_full_ensemble_output()
    test_adding_ensemble_output()
    test_free_and_json_output()
    test_combine_with_empty_json()

####
if __name__ == "__main__":
    # test_return_persistent_data_memaddr()
    # test_passing_persistent_data_to_run_system()
    # test_full_ensemble_output()
    # test_adding_ensemble_output()
    test_free_and_json_output()
    # combine_with_empty_json()
    test_adding_ensemble_output()
    # test_free_and_json_output()
    # test_combine_with_empty_json()
    print("Done")