From ee872b09b45ce5a163ab43dc34ad1445583ddf4d Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Tue, 14 Jan 2020 23:36:35 +0000 Subject: [PATCH] added store loading function and added run_population function and add_grid_variable function --- .../utils/custom_logging_functions.py | 2 + binarycpython/utils/grid.py | 163 +++++++++++++----- binarycpython/utils/grid_options_defaults.py | 28 ++- src/binary_c_python_api.c | 13 +- tests/population/grid_tests.py | 12 +- tests/python_API_test.py | 3 +- 6 files changed, 154 insertions(+), 67 deletions(-) diff --git a/binarycpython/utils/custom_logging_functions.py b/binarycpython/utils/custom_logging_functions.py index b966f6eae..9f58b705a 100644 --- a/binarycpython/utils/custom_logging_functions.py +++ b/binarycpython/utils/custom_logging_functions.py @@ -5,6 +5,7 @@ import socket import tempfile import ctypes + def autogen_C_logging_code(logging_dict): """ Function that autogenerates PRINTF statements for binaryc. intput is a dictionary where the key is the header of that logging line and items which are lists of parameters\ @@ -220,6 +221,7 @@ def return_compilation_dict(verbose=False): return {"cc": cc, "ld": ld, "ccflags": ccflags, "libs": libs, "inc": inc} + def compile_shared_lib(code, sourcefile_name, outfile_name, verbose=False): """ Function to write the custom logging code to a file and then compile it. diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py index c846fcbd2..c8b66521e 100644 --- a/binarycpython/utils/grid.py +++ b/binarycpython/utils/grid.py @@ -7,11 +7,14 @@ import binary_c_python_api import binarycpython from binarycpython.utils.grid_options_defaults import grid_options_defaults_dict -from binarycpython.utils.custom_logging_functions import autogen_C_logging_code, binary_c_log_code, create_and_load_logging_function +from binarycpython.utils.custom_logging_functions import ( + autogen_C_logging_code, + binary_c_log_code, + create_and_load_logging_function, +) from binarycpython.utils.functions import get_defaults - # TODO list # TODO: add functionality to parse cmdline args # TODO: add functionality to 'on-init' set arguments @@ -27,11 +30,10 @@ from binarycpython.utils.functions import get_defaults # TODO: add functionality to return the ensemble_list # DONE: add functionality to return the evcode_version_string - # Make this function also an API call. Doest seem to get written to a buffer that is stored into a python object. rather its just written to stdout +# Make this function also an API call. Doest seem to get written to a buffer that is stored into a python object. rather its just written to stdout # DONE: add functionality to return the evcode_args_list - class Population(object): def __init__(self): """ @@ -41,30 +43,30 @@ class Population(object): self.defaults = get_defaults() # Different sections of options - self.bse_options = {} # bse_options is just empty. Setting stuff will check against the defaults to see if the input is correct. + self.bse_options = ( + {} + ) # bse_options is just empty. Setting stuff will check against the defaults to see if the input is correct. self.grid_options = grid_options_defaults_dict.copy() self.custom_options = {} # Argline dict self.argline_dict = {} - ################################################### # Argument functions ################################################### # General flow of generating the arguments for the binary_c call: # - user provides parameter and value via set (or manually but that is risky) - # - The parameter names of these input get compared to the parameter names in the self.defaults; with this, we know that its a valid - # parameter to give to binary_c. + # - The parameter names of these input get compared to the parameter names in the self.defaults; with this, we know that its a valid + # parameter to give to binary_c. # - For a single system, the bse_options will be written as a arg line - # - For a population the bse_options will get copied to a temp_bse_options file and updated with all the parameters generated by the grid + # - For a population the bse_options will get copied to a temp_bse_options dict and updated with all the parameters generated by the grid - - # I will NOT create the argument line by fully writing ALL the defaults and overriding user input, that seems not necessary + # I will NOT create the argument line by fully writing ALL the defaults and overriding user input, that seems not necessary # because by using the get_defaults() function we already know for sure which parameter names are valid for the binary_c version - # 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 + # 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. def set(self, **kwargs): """ @@ -80,7 +82,7 @@ class Population(object): for key in kwargs.keys(): # Filter out keys for the bse_options if key in self.defaults.keys(): - print('adding: {}={} to BSE_options'.format(key,kwargs[key])) + print("adding: {}={} to BSE_options".format(key, kwargs[key])) self.bse_options[key] = kwargs[key] # Filter out keys for the grid_options @@ -111,6 +113,71 @@ class Population(object): pass + def add_grid_variable( + self, + name, + longname, + range, + resolution, + spacingfunc, + precode, + probdist, + dphasevol, + condition, + ): + """ + Function to add grid variables to the grid_options. + + TODO: Fix this complex function. + + The execution of the grid generation will be through a nested forloop, + and will rely heavily on the eval() functionality of python. Which, in terms of safety is very bad, but in terms of flexibility is very good. + + name: + name of parameter + example: name = 'lnm1' + longname: + Long name of parameter + example: longname = 'Primary mass' + range: + Range of values to take + example: range = [log($mmin),log($mmax)] + resolution: + Resolution of the sampled range (amount of samples) + example: resolution = $resolution->{m1} + spacingfunction: + Function determining how the range is sampled + example: spacingfunction = "const(log($mmin),log($mmax),$resolution->{m1})" + precode: + # TODO: think of good description. + example: precode = '$m1=exp($lnm1);' + probdist: + FUnction determining the probability that gets asigned to the sampled parameter + example: probdist = 'Kroupa2001($m1)*$m1' + dphasevol: + part of the parameter space that the total probability is calculated with + example: dphasevol = '$dlnm1' + condition: + condition that has to be met in order for the grid generation to continue + example: condition = '$self->{_grid_options}{binary}==1' + """ + + # Add grid_variable + grid_variable = { + "name": name, + "longname": longname, + "range": range, # TODO: change name + "resolution": resolution, + "spacingfunction": spacingfunction, + "precode": precode, + "probdist": probdist, + "dphasevol": dphasevol, + "condition": condition, + "grid_variable_number": len(self.grid_options["grid_variables"]), + } + + # Load it into the grid_options + self.grid_options["grid_variables"][grid_variable["name"]] = grid_variable ################################################### # Return functions @@ -124,9 +191,9 @@ class Population(object): """ options = { - 'bse_options': self.bse_options, - 'grid_options': self.grid_options, - 'custom_options': self.custom_options, + "bse_options": self.bse_options, + "grid_options": self.grid_options, + "custom_options": self.custom_options, } return options @@ -162,10 +229,10 @@ class Population(object): binary_c_help_all_info = get_help_all(print_help=False, return_dict=True) all_info = {} - all_info['population_settings'] = population_settings - all_info['binary_c_defaults'] = binary_c_defaults - all_info['binary_c_version_info'] = binary_c_version_info - all_info['binary_c_help_all'] = binary_c_help_all_info + all_info["population_settings"] = population_settings + all_info["binary_c_defaults"] = binary_c_defaults + all_info["binary_c_version_info"] = binary_c_version_info + all_info["binary_c_help_all"] = binary_c_help_all_info return all_info @@ -180,7 +247,7 @@ class Population(object): all_info = self.return_all_info() # if not outfile.endswith('json'): - with open(outfile, 'w') as f: + with open(outfile, "w") as f: f.write(json.dumps(all_info, indent=4)) ################################################### @@ -192,9 +259,7 @@ class Population(object): Function to run a single system """ - argline = self.return_argline(self.bse_options) -return_binary_c_version_info out = binary_c_python_api.run_binary(argline) # out = binary_c_python_api.run_binary('binary_c M_1 15 M_2 14 separation 0 orbital_period 4530 eccentricity 0 metallicity 0.02 max_evolution_time 15000') return out @@ -206,27 +271,39 @@ return_binary_c_version_info ### Custom logging code: # C_logging_code gets priority of C_autogen_code - if self.grid_options['C_auto_logging']: + if self.grid_options["C_auto_logging"]: # Generate real logging code - logging_line = autogen_C_logging_code( - self.grid_options['C_auto_logging'] - ) + logging_line = autogen_C_logging_code(self.grid_options["C_auto_logging"]) # Generate entire shared lib code around logging lines custom_logging_code = binary_c_log_code(logging_line) # Load memory adress - self.grid_options['custom_logging_func_memaddr'] = create_and_load_logging_function(custom_logging_code) - # - if self.grid_options['C_logging_code']: + self.grid_options[ + "custom_logging_func_memaddr" + ] = create_and_load_logging_function(custom_logging_code) + # + 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']) + custom_logging_code = binary_c_log_code(self.grid_options["C_logging_code"]) # Load memory adress - self.grid_options['custom_logging_func_memaddr'] = create_and_load_logging_function(custom_logging_code) - ### + self.grid_options[ + "custom_logging_func_memaddr" + ] = create_and_load_logging_function(custom_logging_code) - ### Arguments + ### Load store + store = binary_c_python_api.return_store("") + + print("ho") + + print(self.return_argline()) + + out = binary_c_python_api.run_population(self.return_argline(), 12, store) + print(out) + quit() + + ### Arguments # If user inputs a file containing arg lines then use that if custom_arg_file: # check if file exists @@ -237,14 +314,14 @@ return_binary_c_version_info temp = f.read().splitlines() # Filter out all the lines that dont start with binary_c - population_arglines = [line for line in temp if line.startswith('binary_c')] + population_arglines = [ + line for line in temp if line.startswith("binary_c") + ] else: - # generate population from options - + # generate population from options - - print('ho') + print("ho") pass @@ -253,12 +330,8 @@ return_binary_c_version_info for line in population_arglines: print(line) - - - pass - ################################################### # Testing functions ################################################### @@ -287,4 +360,4 @@ return_binary_c_version_info print(output) -################################################################################################ +################################################################################################ diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index d45f0a53b..8c99fec7d 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -1,25 +1,21 @@ grid_options_defaults_dict = { - # - 'amt_cores': 1, # total amount of cores used to evolve the population - 'verbose': 0, # Level of verbosity of the simulation - + # + "amt_cores": 1, # total amount of cores used to evolve the population + "verbose": 0, # Level of verbosity of the simulation # Custom logging - 'C_auto_logging': None, # Should contain a dictionary where the kes are they headers and the values are lists of parameters that should be logged. This will get parsed by autogen_C_logging_code in custom_loggion_functions.py - 'C_logging_code': None, # Should contain a string which holds the logging code. - 'custom_logging_func_memaddr': -1, # Contains the custom_logging functions memory address - - # Log args: logging of arguments - 'log_args': 0, # - 'log_args_dir': '/tmp/', - - + "C_auto_logging": None, # Should contain a dictionary where the kes are they headers and the values are lists of parameters that should be logged. This will get parsed by autogen_C_logging_code in custom_loggion_functions.py + "C_logging_code": None, # Should contain a string which holds the logging code. + "custom_logging_func_memaddr": -1, # Contains the custom_logging functions memory address + # Log args: logging of arguments + "log_args": 0, # + "log_args_dir": "/tmp/", + # Grid variables: instructions to generate the values of the parameters + "grid_variables": {}, # return_array_refs=>1, # quicker data parsing mode # sort_args=>1, # save_args=>1, - # nice=>'nice -n +20', # nice command e.g. 'nice -n +10' or '' + # nice=>'nice -n +20', # nice command e.g. 'nice -n +10' or '' # timeout=>15, # seconds until timeout # log_filename=>"/scratch/davidh/results_simulations/tmp/log.txt", # # current_log_filename=>"/scratch/davidh/results_simulations/tmp/grid_errors.log", - } - diff --git a/src/binary_c_python_api.c b/src/binary_c_python_api.c index e8922c589..603f89d5c 100644 --- a/src/binary_c_python_api.c +++ b/src/binary_c_python_api.c @@ -229,7 +229,11 @@ int run_population(char * argstring, // load the store // struct libbinary_c_store_t * store = (void*)store_memaddr; - struct libbinary_c_store_t * store = NULL; + struct libbinary_c_store_t * store = (void*)store_memaddr; + // struct libbinary_c_store_t * store = (void*)(struct stardata_t *)custom_logging_func_memaddr; + // struct libbinary_c_store_t * store = (void*)(struct stardata_t *)custom_logging_func_memaddr; + // struct libbinary_c_store_t * store = (void*)(struct stardata_t *)custom_logging_func_memaddr; + // struct libbinary_c_store_t * store = NULL; /* make new stardata */ stardata = NULL; @@ -253,7 +257,7 @@ int run_population(char * argstring, /* output to strings */ stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE; stardata->preferences->batchmode = BATCHMODE_LIBRARY; - stardata->preferences->custom_output_function = (void*)(struct stardata_t *)custom_logging_func_memaddr; + // stardata->preferences->custom_output_function = (void*)(struct stardata_t *)custom_logging_func_memaddr; /* do binary evolution */ binary_c_evolve_for_dt(stardata, @@ -491,6 +495,11 @@ long int return_store(char * argstring, /* free stardata (except the buffer) */ binary_c_free_memory(&stardata, TRUE, TRUE, FALSE, FALSE); + // int store_ptr; + // store_ptr = (void *)store; + + // binary_c_free_store_contents(store); + // return store_ptr; return store; } \ No newline at end of file diff --git a/tests/population/grid_tests.py b/tests/population/grid_tests.py index a8d8ec1e8..666bf9b39 100644 --- a/tests/population/grid_tests.py +++ b/tests/population/grid_tests.py @@ -13,7 +13,13 @@ test_pop = Population() # test_pop.set(M_1=10, M_2=500) # print(test_pop.bse_options['M_1']) # print(test_pop.bse_options['M_2']) -test_pop.set(M_1=10, separation=0, orbital_period=4580, max_evolution_time=15000, eccentricity=0.02, ) +test_pop.set( + M_1=10, + separation=0, + orbital_period=4580, + max_evolution_time=15000, + eccentricity=0.02, +) # print(test_pop.bse_options) ## Testing single evolution @@ -55,7 +61,7 @@ test_pop.set(M_1=10, separation=0, orbital_period=4580, max_evolution_time=15000 # return all info: # print(json.dumps(test_pop.return_all_info(), indent=4)) -test_pop.export_all_info(outfile=os.path.join(os.getcwd(), 'test_output.txt')) - +test_pop.export_all_info(outfile=os.path.join(os.getcwd(), "test_output.txt")) +test_pop.evolve_population() diff --git a/tests/python_API_test.py b/tests/python_API_test.py index 8d295b57f..9ef833b0c 100755 --- a/tests/python_API_test.py +++ b/tests/python_API_test.py @@ -121,13 +121,14 @@ def test_return_help_all(): out = binary_c_python_api.return_help_all("M_1") print(out) + def test_return_version_info(): out = binary_c_python_api.return_version_info() print(out) def test_return_store(): - out = binary_c_python_api.return_store("binary_c M_1 10") + out = binary_c_python_api.return_store("") print(out) -- GitLab