From 05064ac269bbc7589947ba1cc3c880dec314aaba Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Thu, 27 Feb 2020 01:12:04 +0000 Subject: [PATCH] fixed bug in hdf5 writer. updated example population script --- binarycpython/utils/functions.py | 4 +- examples/example_population.py | 128 +++++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 32 deletions(-) diff --git a/binarycpython/utils/functions.py b/binarycpython/utils/functions.py index da2c5bb5e..127772da6 100644 --- a/binarycpython/utils/functions.py +++ b/binarycpython/utils/functions.py @@ -134,8 +134,8 @@ def create_hdf5(data_dir, name): [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) + with open(settings_file, "r") as settings_file: + settings_json = json.load(settings_file) # Create settings group settings_grp = f.create_group("settings") diff --git a/examples/example_population.py b/examples/example_population.py index 4ee06d7d7..bfac41b69 100644 --- a/examples/example_population.py +++ b/examples/example_population.py @@ -6,13 +6,53 @@ import os from binarycpython.utils.grid import Population from binarycpython.utils.functions import get_help_all, get_help, create_hdf5 - +from binarycpython.utils.custom_logging_functions import temp_dir ######################################################### # This file serves as an example for running a population. # The use of help(<function>) is a good way to inspect what parameters are there to use ######################################################### + +## Quick script to get some output about which stars go supernova when. +def output_lines(output): + """ + Function that outputs the lines that were recieved from the binary_c run. + """ + return output.splitlines() + +def parse_function(self, output): + # extract info from the population instance + # TODO: think about whether this is smart. Passing around this object might be an overkill + + # Get some information from the + data_dir = self.custom_options['data_dir'] + base_filename = self.custom_options['base_filename'] + + # Check directory, make if necessary + os.makedirs(data_dir, exist_ok=True) + + seperator = ' ' + + # Create filename + outfilename = os.path.join(data_dir, base_filename) + + # Go over the output. + for el in output_lines(output): + headerline = el.split()[0] + + # CHeck the header and act accordingly + if (headerline=='MY_STELLAR_DATA'): + parameters = ['time', 'mass', 'zams_mass', 'probability'] + values = el.split()[1:] + + if not os.path.exists(outfilename): + with open(outfilename, 'w') as f: + f.write(seperator.join(parameters)+'\n') + + with open(outfilename, 'a') as f: + f.write(seperator.join(values)+'\n') + # Create population object example_pop = Population() @@ -24,48 +64,72 @@ example_pop.set(verbose=1) # Those that are present in the default grid_options are set in grid_options # All other values that you set are put in a custom_options dict example_pop.set( - # + # binary_c physics options M_1=10, # bse_options separation=0, # bse_options orbital_period=4580, # bse_options max_evolution_time=15000, # bse_options eccentricity=0.02, # bse_options - # + + # grid_options amt_cores=1, # grid_options - # + verbose=1, # verbosity. Not fully configured correctly yet but having it value of 1 prints alot of stuff + parse_function=parse_function, # Setting the parse function thats used in the evolve_population + + # Custom options # TODO: need to be set in grid_options probably data_dir=os.path.join( - os.environ["BINARYC_DATA_ROOT"], "example_python" + temp_dir(), "example_python_population_result" ), # custom_options base_filename="example_pop.dat", # custom_options ) -# Custom logging -# TODO: show different ways -example_pop.set( - C_auto_logging={ - "MY_HEADER_LINE": ["star[0].mass", "star[1].mass", "model.probability"] - } -) +### Custom logging + +## Below example requires changing the parse function +## very simple example of custom logging. Will work but need to change the parse function to handle that nicely. +# example_pop.set( +# C_auto_logging={ +# "MY_HEADER_LINE": ["star[0].mass", "star[1].mass", "model.probability"] +# } +# ) + + +# Log the moment when the star turns into a hertzsprung-gap example_pop.set( - C_logging_code='Printf("MY_STELLAR_DATA time=%g mass=%g radius=%g\\n", stardata->model.time, stardata->star[0].mass, stardata->star[0].radius);' -) + C_logging_code=""" +if(stardata->star[0].stellar_type >= 2) +{ + if (stardata->model.time < stardata->model.max_evolution_time) + { + Printf("MY_STELLAR_DATA %30.12e %g %g %g\\n", + // + stardata->model.time, // 1 + stardata->star[0].mass, //2 + stardata->star[0].pms_mass, //4 + stardata->model.probability //6 + ); + }; + /* Kill the simulation to save time */ + stardata->model.max_evolution_time = stardata->model.time - stardata->model.dtm; +}; +""") -# TODO: show when reading from file -example_pop.set_custom_logging() # TODO: remove this one +# Add grid variables +resolution = {'M_1': 10} -# Adding grid variables: +# Mass example_pop.add_grid_variable( name="lnm1", - longname="log primary mass", - valuerange=[10, 20], - resolution="10", - spacingfunc="np.linspace(0.213, 10.2, 10)", + longname="Primary mass", + valuerange=[2, 150], + resolution="{}".format(resolution['M_1']), + spacingfunc="const(math.log(2), math.log(150), {})".format(resolution['M_1']), precode="M_1=math.exp(lnm1)", - probdist="flat(M_1)", - # probdist='self.custom_options["extra_prob_function"](M_1)', - dphasevol="", + probdist="three_part_powerlaw(M_1, 0.1, 0.5, 1.0, 150, -1.3, -2.3, -2.3)*M_1", + dphasevol="dlnm1", parameter_name="M_1", - condition="", + condition="", # Impose a condition on this grid variable. Mostly for a check for yourself + ) # Exporting of all the settings can be done with .export_all_info() @@ -80,13 +144,17 @@ example_pop.export_all_info() # Creating a parsing function # TODO: add example of setting up a parsing function -# Executing a single system -# TODO: add example of running a single system +## Executing a single system +## This uses the M_1 orbital period etc set with the set function +# output = example_pop.evolve_single() +# print(output) + -# Executing a population -# TODO: add example of running a population +## Executing a population +## This uses the values generated by the grid_variables +example_pop.evolve_population_mp_chunks() # TODO: update this function call # Wrapping up the results to an hdf5 file can be done by using the create_hdf5(<directory containing data and settings>) # This function takes the settings file (ending in _settings.json) and the data files (ending in .dat) from the data_dir # and packing them into an hdf5 file, which is then written into the same data_dir directory -create_hdf5(example_pop.custom_options["data_dir"]) +create_hdf5(data_dir=example_pop.custom_options["data_dir"], name='example_pop.hdf5') \ No newline at end of file -- GitLab