diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py index 977dd7be06c5bc3beeba4e53d2cd7491640e9763..f63319dd70e948a3cf65db2efc82ae4fbc497373 100644 --- a/binarycpython/utils/grid.py +++ b/binarycpython/utils/grid.py @@ -2,9 +2,13 @@ import os import copy import json import sys +import datetime + + 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 ( @@ -16,8 +20,8 @@ from binarycpython.utils.custom_logging_functions import ( from binarycpython.utils.functions import get_defaults, parse_binary_c_version_info -# TODO list -# TODO: add functionality to parse cmdline args +# Todo-list +# DONE: add functionality to parse cmdline args # TODO: add functionality to 'on-init' set arguments # DONE: add functionality to export the arg string. # DONE: add functionality to export all the options @@ -33,7 +37,7 @@ from binarycpython.utils.functions import get_defaults, parse_binary_c_version_i # 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 # DONE: add functionality to return the evcode_args_list -# TODO: add grid generation script +# DONE: add grid generation script class Population(object): @@ -494,15 +498,19 @@ class Population(object): # TODO: Add correct logging everywhere # TODO: add different types of grid. # TODO: add part to handle separation if orbital_period is added + # TODO: add part to calculate probability + # TODO: add part to correctly set the values with the spacingsfunctions. + # TODO: add phasevol correctly + # TODO: add centering center left right for the spacing """ # Some local values code_string = "" depth = 0 indent = " " + total_grid_variables = len(self.grid_options["grid_variables"]) # Import packages - code_string += "import math\n" code_string += "import numpy as np\n" code_string += "from binarycpython.utils.probability_distributions import *\n" @@ -518,24 +526,36 @@ class Population(object): # 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() + + "# Grid code generated on {}\n".format(datetime.datetime.now().isoformat()) + + indent * depth + "# This function generates the systems that will be evolved with binary_c\n\n" ) # Set some values in the generated code: - code_string += indent * depth + "starcount = 0\n" + code_string += indent * depth + '# Setting initial values\n' + code_string += indent * depth + "total_starcount = 0\n" + code_string += indent * depth + "starcounts = [0 for i in range({})]\n".format(total_grid_variables) code_string += indent * depth + "probabilities = {}\n" + code_string += indent * depth + "probabilities_list = [0 for i in range({})]\n".format(total_grid_variables) + code_string += indent * depth + "probabilities_sum = [0 for i in range({})]\n".format(total_grid_variables) code_string += indent * depth + "parameter_dict = {}\n" + code_string += indent * depth + "\n" + code_string += indent * depth + "# setting probability lists\n" # Prepare the probability for el in sorted( self.grid_options["grid_variables"].items(), key=lambda x: x[1]["grid_variable_number"], ): + # Make probabilities dict grid_variable = el[1] code_string += indent * depth + 'probabilities["{}"] = 0\n'.format( grid_variable["parameter_name"] ) + ################################################################################# + # Start of code generation + ################################################################################# + code_string += indent * depth + "\n" # Generate code print("Generating grid code") for el in sorted( @@ -545,8 +565,18 @@ class Population(object): print("Constructing/adding: {}".format(el[0])) grid_variable = el[1] + ################################################################################# + # Check condition and generate forloop + # If the grid variable has a condition, write the check and the action if grid_variable["condition"]: + # Add comment + code_string += ( + indent * depth + + "# Condition for {}".format(grid_variable['parameter_name']) + + "\n" + ) + # Add condition check code_string += ( indent * depth @@ -557,15 +587,29 @@ class Population(object): # Add condition failed action: #TODO: add correct exception error code_string += ( indent * (depth + 1) - + 'print("Condition not met!")'.format(grid_variable["condition"]) + + 'print("Condition for {} not met!")'.format(grid_variable["parameter_name"]) + "\n" ) code_string += ( indent * (depth + 1) - + "raise ValueError".format(grid_variable["condition"]) + + "raise ValueError" + "\n" ) + # Add some whiteline + code_string += (indent * (depth + 1) + "\n") + + ######################### + # Setting up the forloop + # Add comment for forloop + code_string += ( + indent * depth + + "# for loop for {}".format( + grid_variable["parameter_name"]) + + "\n" + ) + + # Adding for loop structure code_string += ( indent * depth @@ -575,6 +619,9 @@ class Population(object): + "\n" ) + + ######################### + # Setting up pre-code and # Add pre-code code_string += ( indent * (depth + 1) @@ -584,17 +631,51 @@ class Population(object): + "\n" ) + ####################### + # Probabilities # Calculate probability + code_string += indent * (depth + 1) + "\n" + code_string += indent * (depth + 1) + "# Setting probabilities\n" code_string += ( indent * (depth + 1) - + 'probabilities["{}"] = {}'.format( - grid_variable["parameter_name"], grid_variable["probdist"] - ) + + 'd{} = {}'.format(grid_variable['name'], grid_variable["probdist"]) + "\n" ) - # some testing line. - # code_string += indent * (depth + 1) + 'print({})'.format(grid_variable['name']) + '\n' + # Saving probability sum + code_string += ( + indent * (depth + 1) + + 'probabilities_sum[{}] += d{}'.format( + grid_variable['grid_variable_number'], + grid_variable["name"] + ) + + "\n" + ) + + if grid_variable['grid_variable_number'] == 0: + code_string += ( + indent * (depth + 1) + + 'probabilities_list[0] = d{}'.format(grid_variable['name']) + + "\n" + ) + else: + code_string += ( + indent * (depth + 1) + + 'probabilities_list[{}] = probabilities_list[{}] * d{}'.format(grid_variable['grid_variable_number'], grid_variable['grid_variable_number']-1, grid_variable['name']) + + "\n" + ) + + ####################### + # Increment starcount for this parameter + code_string += "\n" + code_string += indent * (depth + 1) + "# Increment starcount for {}\n".format(grid_variable['parameter_name']) + code_string += ( + indent * (depth + 1) + + 'starcounts[{}] += 1'.format( + grid_variable['grid_variable_number'], + ) + + "\n" + ) # Add value to dict code_string += ( @@ -611,13 +692,75 @@ class Population(object): # increment depth depth += 1 - # placeholder for calls to threading - # starcount - code_string += indent * (depth) + "starcount += 1\n" + + ################################################################################# + # Here are the calls to the queuing or other solution. this part is for every system + # Add comment + code_string += indent * (depth) + "# Code below will get evaluated for every generated system\n" + + # Calculate value + code_string += indent * (depth) + 'probability = self.grid_options["weight"] * probabilities_list[{}]'.format(grid_variable['grid_variable_number']) + "\n" + code_string += indent * (depth) + 'repeat_probability = probability / self.grid_options["repeat"]' + "\n" + code_string += indent * (depth) + "total_starcount += 1\n" code_string += indent * (depth) + "print(probabilities)\n" - code_string += indent * (depth) + 'print("starcount: ", starcount)\n' + code_string += indent * (depth) + 'print("total_starcount: ", total_starcount)\n' code_string += indent * (depth) + "yield(parameter_dict)\n" + + + + + + + + + + + # { + # { + # $self->increment_probtot($prob); + # { + # my $system; + # if($self->{_grid_options}->{binary}) + # { + # $system={ + # M_1=>$m1, + # M_2=>$m2, + # metallicity=>$self->metallicity(), + # orbital_period=>$per, + # eccentricity=>$eccentricity, + # probability=>$repeat_prob, + # phasevol=>$phasevol + # }; + # } + # else + # { + # $system={ + # M_1=>$m1, + # M_2=>0.01, + # metallicity=>$self->metallicity(), + # orbital_period=>$self->{_grid_options}->{single_star_period}, + # eccentricity=>0.0, + # probability=>$repeat_prob, + # phasevol=>$phasevol + # }; + # } + + # $self->queue_evolution_code_run($self->{_flexigrid}->{thread_q}, + # $system); + + # } + + + + + + + + + ################################################################################# + # Stop of code generation. Here the code is saved and written + # Save the gridcode to the grid_options self.grid_options["code_string"] = code_string @@ -626,10 +769,11 @@ class Population(object): self.grid_options["tmp_dir"], "example_grid.py" ) self.grid_options["gridcode_filename"] = gridcode_filename - with open(gridcode_filename, "w") as f: f.write(code_string) + + def load_grid_function(self): """ Test function to run grid stuff. mostly to test the import diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index 223d0bd17501cac466a947962b51c8e878d3ecd8..533aec119d130969ed6faf386b7c8a41e9118150 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -26,8 +26,12 @@ grid_options_defaults_dict = { "binary": 0, # Locations: "binary_c_dir": os.environ["BINARYC_DIR"], - "tmp_dir": temp_dir() + "tmp_dir": temp_dir(), + # Probability: + "weight": 1.0, # weighting for the probability + "repeat": 1.0, # number of times to repeat each system (probability is adjusted to be 1/repeat) ## + # return_array_refs=>1, # quicker data parsing mode # sort_args=>1, # save_args=>1, @@ -85,8 +89,7 @@ grid_options_defaults_dict = { # merge_datafiles=>'', # merge_datafiles_filelist=>'', # # parameter space options - # weight=>1.0, # weighting for the probability - # repeat=>1, # number of times to repeat each system (probability is adjusted to be 1/repeat) + # binary=>0, # set to 0 for single stars, 1 for binaries # # if use_full_resolution is 1, then run a dummy grid to # # calculate the resolution. this could be slow... diff --git a/binarycpython/utils/spacings_functions.py b/binarycpython/utils/spacing_functions.py similarity index 100% rename from binarycpython/utils/spacings_functions.py rename to binarycpython/utils/spacing_functions.py