Commit 4d609804 authored by David Hendriks's avatar David Hendriks
Browse files

working on grid generation code. also black-formatted the whole code again

parent 948abf58
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ def compile_shared_lib(code, sourcefile_name, outfile_name, verbose=False):
            print("Output of compilation command:\n{}".format(res))


def temp_custom_logging_dir():
def temp_dir():
    """
    Function to return the path the custom logging library shared object and script will be written to.

@@ -293,14 +293,12 @@ def create_and_load_logging_function(custom_logging_code):
    #

    library_name = os.path.join(
        temp_custom_logging_dir(), "libcustom_logging_{}.so".format(uuid.uuid4().hex)
        temp_dir(), "libcustom_logging_{}.so".format(uuid.uuid4().hex)
    )

    compile_shared_lib(
        custom_logging_code,
        sourcefile_name=os.path.join(temp_custom_logging_dir(), "custom_logging.c"),
        # outfile_name=os.path.join(temp_custom_logging_dir(), "libcustom_logging.so"),
        # outfile_name=os.path.join(temp_custom_logging_dir(), "libcustom_logging_{}.so".format(random.randint(1, 100))),
        sourcefile_name=os.path.join(temp_dir(), "custom_logging.c"),
        outfile_name=library_name,
        # verbose=True
    )
+82 −77
Original line number Diff line number Diff line
@@ -10,90 +10,91 @@ from binarycpython.utils.custom_logging_functions import (
    create_and_load_logging_function,
)


def parse_binary_c_version_info(version_info_string):
    version_info_dict = {}

    for el in version_info_string.splitlines():
        el = el.strip()
        if el =='':
        if el == "":
            continue
        if ' is ' in el:
        if " is " in el:
            split = el.split(" is ")
            version_info_dict[split[0].strip()] = split[1].strip()
        else:
            if el.startswith('Binary_c/nucsyn'):
                version_info_dict['intro'] = el
            elif el.startswith('Email'):
                emails = el.split('Email ')[1].split(',')
            if el.startswith("Binary_c/nucsyn"):
                version_info_dict["intro"] = el
            elif el.startswith("Email"):
                emails = el.split("Email ")[1].split(",")
                cleaned_emails = [email.strip() for email in emails]
                version_info_dict['emails'] = cleaned_emails
            elif el.startswith('DTlimit'):
                split = el.split(' : ')
                version_info_dict[split[0]] = ': '.join(split[1:])
            elif el.startswith('Version'):
                version_info_dict["emails"] = cleaned_emails
            elif el.startswith("DTlimit"):
                split = el.split(" : ")
                version_info_dict[split[0]] = ": ".join(split[1:])
            elif el.startswith("Version"):
                split = el.split("Version ")
                version_number = split[1]
                version_info_dict['version_number'] = version_number
                version_info_dict["version_number"] = version_number
            elif el.startswith("git URL"):
                split = el.split("git URL ")
                git_url = split[1]
                version_info_dict['git_url'] = git_url
                version_info_dict["git_url"] = git_url
            elif el.startswith("Build: "):
                split = el.split('Build: ')
                split = el.split("Build: ")
                build = split[1]
                version_info_dict['build'] = build
                version_info_dict["build"] = build
            elif el.startswith("Compiled for "):
                split = el.split('Compiled for ')
                split = el.split("Compiled for ")
                compiled_for = split[1]
                version_info_dict['compiled_for'] = compiled_for
                version_info_dict["compiled_for"] = compiled_for
            elif el.startswith("Stack limit "):
                split = el.split('Stack limit ')
                split = el.split("Stack limit ")
                stack_limit = split[1]
                version_info_dict['stack_limit'] = stack_limit
            elif el.startswith('SVN URL '):
                split = el.split('SVN URL ')
                version_info_dict["stack_limit"] = stack_limit
            elif el.startswith("SVN URL "):
                split = el.split("SVN URL ")
                svn_url = split[1]
                version_info_dict['svn_url'] = svn_url
            elif el.startswith('git branch '):
                split = el.split('git branch ')
                version_info_dict["svn_url"] = svn_url
            elif el.startswith("git branch "):
                split = el.split("git branch ")
                git_branch = split[1]
                version_info_dict['git_branch'] = git_branch
            elif el.startswith('_SC_CLK_TCK'):
                split = el.split(' = ')
                version_info_dict["git_branch"] = git_branch
            elif el.startswith("_SC_CLK_TCK"):
                split = el.split(" = ")
                _SC_CLK_TCK = split[1]
                version_info_dict['_SC_CLK_TCK'] = _SC_CLK_TCK
            elif el.startswith('Random number mean '):
                split = el.split('Random number mean ')
                version_info_dict["_SC_CLK_TCK"] = _SC_CLK_TCK
            elif el.startswith("Random number mean "):
                split = el.split("Random number mean ")
                random_number_mean = split[1]
                version_info_dict['Random number mean'] = random_number_mean
            elif el.startswith('SVN revision '):
                split = el.split('SVN revision ')
                version_info_dict["Random number mean"] = random_number_mean
            elif el.startswith("SVN revision "):
                split = el.split("SVN revision ")
                svn_revision = split[1]
                version_info_dict['svn_revision'] = svn_revision
            elif el.startswith('Size of :'):
                split = el.split('Size of :')
                version_info_dict["svn_revision"] = svn_revision
            elif el.startswith("Size of :"):
                split = el.split("Size of :")
                data_type_sizes = split[1]
                version_info_dict['data_type_sizes'] = data_type_sizes
            elif el.startswith('git revision '):
                split = el.split('git revision ')
                version_info_dict["data_type_sizes"] = data_type_sizes
            elif el.startswith("git revision "):
                split = el.split("git revision ")
                git_revision = split[1]
                version_info_dict['git_revision'] = git_revision
            elif el.startswith('BINARY_C_PRE_VERSION '):
                split = el.split('BINARY_C_PRE_VERSION ')
                version_info_dict["git_revision"] = git_revision
            elif el.startswith("BINARY_C_PRE_VERSION "):
                split = el.split("BINARY_C_PRE_VERSION ")
                binary_c_pre_version = split[1]
                version_info_dict['binary_c_pre_version'] = binary_c_pre_version
            elif el.startswith('Comenv accretion:'):
                split = el.split('Comenv accretion:')
                version_info_dict["binary_c_pre_version"] = binary_c_pre_version
            elif el.startswith("Comenv accretion:"):
                split = el.split("Comenv accretion:")
                comenv_accretion = split[1]
                version_info_dict['comenv_accretion'] = comenv_accretion
            elif el.startswith('Compiled in parameters:'):
                split = el.split('Compiled in parameters:')
                version_info_dict["comenv_accretion"] = comenv_accretion
            elif el.startswith("Compiled in parameters:"):
                split = el.split("Compiled in parameters:")
                compiled_in_parameters = split[1]
                version_info_dict['compiled_in_parameters'] = compiled_in_parameters
            elif el.startswith('__short__ is'):
                split = el.split('__short__ is')
                version_info_dict["compiled_in_parameters"] = compiled_in_parameters
            elif el.startswith("__short__ is"):
                split = el.split("__short__ is")
                short_type = split[1]
                version_info_dict['short_type'] = short_type
                version_info_dict["short_type"] = short_type
            else:
                print("Still found unmatched items!:\n{}".format(repr(el)))

@@ -111,30 +112,34 @@ def create_hdf5(data_dir):
    content_data_dir = os.listdir(data_dir)

    # Settings
    settings_file = [file for file in content_data_dir if file.endswith('_settings.json')][0]
    with open(settings_file, 'r') as f:
    settings_file = [
        file for file in content_data_dir if file.endswith("_settings.json")
    ][0]
    with open(settings_file, "r") as f:
        settings_json = json.load(f)

    # create basename for hdf5
    base_name = settings_file.replace('_settings.json', '')
    base_name = settings_file.replace("_settings.json", "")

    # Get data files
    data_files = [el for el in content_data_dir if el.endswith('.dat')]
    data_files = [el for el in content_data_dir if el.endswith(".dat")]

    # Create the file
    hdf5_filename = os.path.join(data_dir,'{base_name}.hdf5'.format(base_name=base_name))
    f = h5py.File(hdf5_filename, 'w')
    hdf5_filename = os.path.join(
        data_dir, "{base_name}.hdf5".format(base_name=base_name)
    )
    f = h5py.File(hdf5_filename, "w")

    # Create settings group
    settings_grp = f.create_group('settings')
    settings_grp = f.create_group("settings")

    # Write version_string to settings_group
    settings_grp.create_dataset('used_settings', data=json.dumps(settings_json))
    settings_grp.create_dataset("used_settings", data=json.dumps(settings_json))

    # Create the data group
    data_grp = f.create_group('data')
    data_grp = f.create_group("data")

    print('Creating {}'.format(hdf5_filename))
    print("Creating {}".format(hdf5_filename))

    # Write the data to the file:
    # Make sure:
@@ -145,8 +150,8 @@ def create_hdf5(data_dir):
        base_name = os.path.splitext(os.path.basename(filename))[0]

        # Get header info
        header_name = '{base_name}_header'.format(base_name=base_name)
        data_headers = np.genfromtxt(full_path, dtype='str', max_rows=1)
        header_name = "{base_name}_header".format(base_name=base_name)
        data_headers = np.genfromtxt(full_path, dtype="str", max_rows=1)
        data_headers = np.char.encode(data_headers)
        data_grp.create_dataset(header_name, data=data_headers)

@@ -156,6 +161,7 @@ def create_hdf5(data_dir):

    f.close()


def get_help_super(print_help=False, return_dict=True, fail_silently=True):
    """
    Function that first runs get_help_all, and then per argument also run the help function to get as much information as possible.
@@ -175,30 +181,31 @@ def get_help_super(print_help=False, return_dict=True, fail_silently=True):

            # Get detailed help info
            detailed_help = get_help(
                parameter_name, print_help=False, return_dict=True, fail_silently=fail_silently
                parameter_name,
                print_help=False,
                return_dict=True,
                fail_silently=fail_silently,
            )

            if detailed_help:
                # check whether the descriptions of help_all and detailed help are the same
                if not fail_silently:
                    if (
                        not parameter["description"]
                        == detailed_help["description"]
                    ):
                    if not parameter["description"] == detailed_help["description"]:
                        print(json.dumps(parameter, indent=4))

                ## put values into help all super dict
                # input type
                parameter["parameter_value_input_type"] = detailed_help["parameter_value_input_type"]
                parameter["parameter_value_input_type"] = detailed_help[
                    "parameter_value_input_type"
                ]

                # default
                parameter["default"] = detailed_help["default"]

                # macros
                if 'macros' in detailed_help.keys():
                if "macros" in detailed_help.keys():
                    parameter["macros"] = detailed_help["macros"]


    if print_help:
        # TODO: make a pretty print
        print(json.dumps(help_all_super_dict, indent=4))
@@ -326,6 +333,7 @@ def create_arg_string(arg_dict):
    arg_string = arg_string.strip()
    return arg_string


def get_defaults(filter_values=False):
    """
    Function that calls the binaryc get args function and cast it into a dictionary
@@ -453,9 +461,6 @@ def get_help(param_name, print_help=True, return_dict=False, fail_silently=False
        return None


# get_help("RLOF_method")


def run_system(**kwargs):
    """
    Wrapper to run a system with settings 
+126 −47
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ from binarycpython.utils.custom_logging_functions import (
    autogen_C_logging_code,
    binary_c_log_code,
    create_and_load_logging_function,
    temp_custom_logging_dir,
    temp_dir,
)
from binarycpython.utils.functions import get_defaults, parse_binary_c_version_info

@@ -35,6 +35,7 @@ from binarycpython.utils.functions import get_defaults, parse_binary_c_version_i
# DONE: add functionality to return the evcode_args_list
# TODO: add grid generation script


class Population(object):
    def __init__(self):
        """
@@ -69,6 +70,8 @@ class Population(object):
    # And because binary_c uses internal defaults, its not necessary to explicitly pass them.
    # I do however suggest everyone to export the binary_c defaults to a file, so that you know exactly which values were the defaults.

    # TODO: maybe make a set_bse option.

    def set(self, **kwargs):
        """
        Function to set the values of the population. This is the preferred method to set values of functions, as it 
@@ -100,7 +103,6 @@ class Population(object):
                )
                self.custom_options[key] = kwargs[key]


    def parse_cmdline(self):
        """
        Function to handle settings values via the command line:
@@ -108,22 +110,29 @@ class Population(object):
        """

        import argparse

        parser = argparse.ArgumentParser()
        parser.add_argument('--cmdline', help='Setting values via the commandline. Input like --cmdline "metallicity=0.02"')
        parser.add_argument(
            "--cmdline",
            help='Setting values via the commandline. Input like --cmdline "metallicity=0.02"',
        )
        args = parser.parse_args()


        # 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:
            # Grab the input and split them up, while accepting only non-empty entries
            cmdline_args = args.cmdline
            split_args = [cmdline_arg for cmdline_arg in cmdline_args.split(' ') if not cmdline_arg=='']
            split_args = [
                cmdline_arg
                for cmdline_arg in cmdline_args.split(" ")
                if not cmdline_arg == ""
            ]

            # Make dict and fill it
            cmdline_dict = {}
            for cmdline_arg in split_args:
                split = cmdline_arg.split('=')
                split = cmdline_arg.split("=")
                parameter = split[0]
                value = split[1]

@@ -155,7 +164,19 @@ class Population(object):

        pass

    def add_grid_variable(self, name, longname, valuerange, resolution, spacingfunc, precode, probdist, dphasevol, parameter_name, condition=None):
    def add_grid_variable(
        self,
        name,
        longname,
        valuerange,
        resolution,
        spacingfunc,
        precode,
        probdist,
        dphasevol,
        parameter_name,
        condition=None,
    ):
        """
        Function to add grid variables to the grid_options.

@@ -284,13 +305,15 @@ class Population(object):
        all_info = self.return_all_info()

        if use_datadir:
            base_name = os.path.splitext(self.custom_options['base_filename'])[0]
            settings_name =  base_name + '_settings.json'
            base_name = os.path.splitext(self.custom_options["base_filename"])[0]
            settings_name = base_name + "_settings.json"

            # Check directory, make if necessary
            os.makedirs(self.custom_options['data_dir'], exist_ok=True)
            os.makedirs(self.custom_options["data_dir"], exist_ok=True)

            settings_fullname = os.path.join(self.custom_options['data_dir'], settings_name)
            settings_fullname = os.path.join(
                self.custom_options["data_dir"], settings_name
            )

            # if not outfile.endswith('json'):
            with open(settings_fullname, "w") as f:
@@ -463,7 +486,6 @@ class Population(object):
    # Unordered functions
    ###################################################


    def generate_grid_code(self):
        """
        Function that generates the code from which the population will be made.
@@ -474,16 +496,17 @@ class Population(object):
        # TODO: add part to handle separation if orbital_period is added
        """


        # Some local values
        code_string = ""
        depth = 0
        indent = '    '
        indent = "    "

        # Import packages
        code_string += "from binarycpython.utils.probability_distributions import *\n"  

        code_string += "import math\n"
        code_string += "import numpy as np\n"
        code_string += "from binarycpython.utils.probability_distributions import *\n"
        code_string += "from binarycpython.utils.spacing_functions import *\n"
        code_string += "\n\n"

        # Make the function
@@ -492,46 +515,95 @@ class Population(object):
        # Increase depth
        depth += 1

        # Write some info in the function
        code_string += (
            indent * depth
            + "# Grid code generated on {}. This function generates the systems that will be evolved with binary_c\n\n".format()
        )

        # Set some values in the generated code:
        code_string += indent * depth + "starcount = 0\n"
        code_string += indent * depth + "probabilities = {}\n"
        code_string += indent * depth + "parameter_dict = {}\n"

        # Prepare the probability
        for el in sorted(self.grid_options["grid_variables"].items(), key=lambda x: x[1]['grid_variable_number']):
        for el in sorted(
            self.grid_options["grid_variables"].items(),
            key=lambda x: x[1]["grid_variable_number"],
        ):
            grid_variable = el[1]
            code_string += indent*depth + 'probabilities["{}"] = 0\n'.format(grid_variable['parameter_name'])
            code_string += indent * depth + 'probabilities["{}"] = 0\n'.format(
                grid_variable["parameter_name"]
            )

        # Generate code
        print("Generating grid code")
        for el in sorted(self.grid_options["grid_variables"].items(), key=lambda x: x[1]['grid_variable_number']):
        for el in sorted(
            self.grid_options["grid_variables"].items(),
            key=lambda x: x[1]["grid_variable_number"],
        ):
            print("Constructing/adding: {}".format(el[0]))
            grid_variable = el[1]

            # If the grid variable has a condition, write the check and the action
            if grid_variable['condition']:
            if grid_variable["condition"]:
                # Add condition check
                code_string += indent * depth + 'if not {}:'.format(grid_variable['condition']) + '\n'
                code_string += (
                    indent * depth
                    + "if not {}:".format(grid_variable["condition"])
                    + "\n"
                )

                # Add condition failed action: #TODO: add correct exception error
                code_string += indent * (depth + 1) + 'print("Condition not met!")'.format(grid_variable['condition']) + '\n'            
                code_string += indent * (depth + 1) + 'raise ValueError'.format(grid_variable['condition']) + '\n'
                code_string += (
                    indent * (depth + 1)
                    + 'print("Condition not met!")'.format(grid_variable["condition"])
                    + "\n"
                )
                code_string += (
                    indent * (depth + 1)
                    + "raise ValueError".format(grid_variable["condition"])
                    + "\n"
                )

            # Adding for loop structure
            code_string += indent * depth + 'for {} in {}:'.format(grid_variable['name'], grid_variable['spacingfunc']) + '\n'
            code_string += (
                indent * depth
                + "for {} in {}:".format(
                    grid_variable["name"], grid_variable["spacingfunc"]
                )
                + "\n"
            )

            # Add pre-code
            code_string += indent * (depth + 1) + '{}'.format(grid_variable['precode'].replace('\n', '\n'+indent * (depth + 1))) + '\n'
            code_string += (
                indent * (depth + 1)
                + "{}".format(
                    grid_variable["precode"].replace("\n", "\n" + indent * (depth + 1))
                )
                + "\n"
            )

            # Calculate probability
            code_string += indent * (depth + 1) + 'probabilities["{}"] = {}'.format(grid_variable['parameter_name'], grid_variable['probdist']) + '\n'
            code_string += (
                indent * (depth + 1)
                + 'probabilities["{}"] = {}'.format(
                    grid_variable["parameter_name"], grid_variable["probdist"]
                )
                + "\n"
            )

            # some testing line.
            # code_string += indent * (depth + 1) + 'print({})'.format(grid_variable['name']) + '\n'

            # Add value to dict
            code_string += indent * (depth + 1) + 'parameter_dict["{}"] = {}'.format(grid_variable['parameter_name'], grid_variable['parameter_name']) + '\n'

            code_string += (
                indent * (depth + 1)
                + 'parameter_dict["{}"] = {}'.format(
                    grid_variable["parameter_name"], grid_variable["parameter_name"]
                )
                + "\n"
            )

            # Add some space
            code_string += "\n"
@@ -541,19 +613,21 @@ class Population(object):

        # placeholder for calls to threading
        # starcount
        code_string += indent * (depth) + 'starcount += 1\n'
        code_string += indent * (depth) + 'print(probabilities)\n'
        code_string += indent * (depth) + "starcount += 1\n"
        code_string += indent * (depth) + "print(probabilities)\n"
        code_string += indent * (depth) + 'print("starcount: ", starcount)\n'
        code_string += indent * (depth) + 'yield(parameter_dict)\n'
        code_string += indent * (depth) + "yield(parameter_dict)\n"

        # Save the gridcode to the grid_options
        self.grid_options['code_string'] = code_string
        self.grid_options["code_string"] = code_string

        # Write to file
        gridcode_filename = os.path.join(temp_custom_logging_dir(), 'example_grid.py')
        self.grid_options['gridcode_filename'] = gridcode_filename
        gridcode_filename = os.path.join(
            self.grid_options["tmp_dir"], "example_grid.py"
        )
        self.grid_options["gridcode_filename"] = gridcode_filename

        with open(gridcode_filename, 'w') as f:
        with open(gridcode_filename, "w") as f:
            f.write(code_string)

    def load_grid_function(self):
@@ -563,13 +637,18 @@ class Population(object):

        # Code to load the
        import importlib.util
        spec = importlib.util.spec_from_file_location("binary_c_python_grid", os.path.join(temp_custom_logging_dir(), 'example_grid.py'))

        spec = importlib.util.spec_from_file_location(
            "binary_c_python_grid",
            os.path.join(self.grid_options["tmp_dir"], "example_grid.py"),
        )
        grid_file = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(grid_file)
        generator = grid_file.grid_code(self)


        print(next(generator))
        print(next(generator))
        print(next(generator))


################################################################################################
+44 −126

File changed.

Preview size limit exceeded, changes collapsed.

+24 −13
Original line number Diff line number Diff line

# TODO: make some things globally present? rob does this in his module. i guess it saves calculations but not sure if im gonna do that now


def flat(parameter):
    """
    Dummt distribution function that returns 1
    """
    return 1


def number(value):
    """
    Dummy distribution function that returns the input
    """
    return value


def powerlaw_constant(min_val, max_val, k):
    """
    Function that returns the constant to normalise a powerlaw
    """

    k1 = k + 1.0
    print("Powerlaw consts from {} to {}, k={} where k1={}".format(min_val, max_val, k, k1))
    print(
        "Powerlaw consts from {} to {}, k={} where k1={}".format(
            min_val, max_val, k, k1
        )
    )

    powerlaw_const = k1/(max_val**k1 - min_val**k1);
    powerlaw_const = k1 / (max_val ** k1 - min_val ** k1)
    return powerlaw_const


def powerlaw(min_val, max_val, k, x):
    """
    Single powerlaw with index k at x from min to max
@@ -42,7 +49,11 @@ def powerlaw(min_val, max_val, k, x):

        # powerlaw
        y = const * (x ** k)
        print("Power law from {} to {}: const = {}, y = {}".format(min_val, max_val, const, y))
        print(
            "Power law from {} to {}: const = {}, y = {}".format(
                min_val, max_val, const, y
            )
        )
        return y


Loading