Skip to content
Snippets Groups Projects
Commit acbb8c31 authored by David Hendriks's avatar David Hendriks
Browse files

Merge branch 'development' into development_version/2.2.1

parents 55799985 ed97dce6
No related branches found
No related tags found
No related merge requests found
...@@ -12,7 +12,6 @@ obj/ ...@@ -12,7 +12,6 @@ obj/
binarycpython_snippets binarycpython_snippets
-1.log -1.log
# Standard template # Standard template
*.org~ *.org~
*.so *.so
......
%% Cell type:code id:fd5b1a83-7212-4aca-b317-991bf289fba8 tags:
``` python
def add(a, b):
return a + b
```
%% Cell type:code id:4d842395-3e17-48e8-b613-9856365e9796 tags:
``` python
add(5, 6)
```
%% Output
11
%% Cell type:code id:f2afc967-a66a-4a47-bfc5-0d6c17826794 tags:
``` python
1 / 0
```
%% Output
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-3-bc757c3fda29> in <module>
----> 1 1 / 0
ZeroDivisionError: division by zero
%% Cell type:markdown id:8491b29d-375d-458f-8a46-fc822422d8f3 tags:
hello
%% Cell type:code id:601a89e6-5ca6-4725-8834-5e975ba76726 tags:
``` python
```
...@@ -24,9 +24,7 @@ from binarycpython.utils.functions import ( ...@@ -24,9 +24,7 @@ from binarycpython.utils.functions import (
Capturing, Capturing,
) )
# https://docs.python.org/3/library/unittest.html TMP_DIR = temp_dir("tests", "test_c_bindings")
TMP_DIR = temp_dir()
os.makedirs(os.path.join(TMP_DIR, "test"), exist_ok=True)
#### some useful functions #### some useful functions
def return_argstring( def return_argstring(
......
...@@ -7,8 +7,7 @@ import unittest ...@@ -7,8 +7,7 @@ import unittest
from binarycpython.utils.custom_logging_functions import * from binarycpython.utils.custom_logging_functions import *
from binarycpython.utils.functions import Capturing from binarycpython.utils.functions import Capturing
binary_c_temp_dir = temp_dir() TMP_DIR = temp_dir("tests", "test_custom_logging")
class test_custom_logging(unittest.TestCase): class test_custom_logging(unittest.TestCase):
""" """
...@@ -26,7 +25,7 @@ class test_custom_logging(unittest.TestCase): ...@@ -26,7 +25,7 @@ class test_custom_logging(unittest.TestCase):
""" """
input_dict_1 = None input_dict_1 = None
output_1 = autogen_C_logging_code(input_dict_1, verbose=1) output_1 = autogen_C_logging_code(input_dict_1, verbosity=1)
self.assertEqual(output_1, None, msg="Error. return value should be None") self.assertEqual(output_1, None, msg="Error. return value should be None")
input_dict_2 = { input_dict_2 = {
...@@ -37,7 +36,7 @@ class test_custom_logging(unittest.TestCase): ...@@ -37,7 +36,7 @@ class test_custom_logging(unittest.TestCase):
"model.dt", "model.dt",
] ]
} }
output_2 = autogen_C_logging_code(input_dict_2, verbose=1) output_2 = autogen_C_logging_code(input_dict_2, verbosity=1)
test_output_2 = 'Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));' test_output_2 = 'Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));'
self.assertEqual( self.assertEqual(
...@@ -45,7 +44,7 @@ class test_custom_logging(unittest.TestCase): ...@@ -45,7 +44,7 @@ class test_custom_logging(unittest.TestCase):
) )
input_dict_3 = {"MY_STELLAR_DATA": 2} input_dict_3 = {"MY_STELLAR_DATA": 2}
output_3 = autogen_C_logging_code(input_dict_3, verbose=1) output_3 = autogen_C_logging_code(input_dict_3, verbosity=1)
self.assertEqual(output_3, None, msg="Output should be None") self.assertEqual(output_3, None, msg="Output should be None")
def test_binary_c_log_code(self): def test_binary_c_log_code(self):
...@@ -59,11 +58,11 @@ class test_custom_logging(unittest.TestCase): ...@@ -59,11 +58,11 @@ class test_custom_logging(unittest.TestCase):
""" """
input_1 = "None" input_1 = "None"
output_1 = binary_c_log_code(input_1, verbose=1) output_1 = binary_c_log_code(input_1, verbosity=1)
self.assertEqual(output_1, None, msg="Output should be None") self.assertEqual(output_1, None, msg="Output should be None")
input_2 = 'Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));' input_2 = 'Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));'
output_2 = binary_c_log_code(input_2, verbose=1) output_2 = binary_c_log_code(input_2, verbosity=1)
test_value_2 = '#pragma push_macro("Max")\n#pragma push_macro("Min")\n#undef Max\n#undef Min\n#include "binary_c.h"\n\n// add visibility __attribute__ ((visibility ("default"))) to it \nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata);\nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata)\n{\n // struct stardata_t * stardata = (struct stardata_t *)x;\n Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));;\n}\n\n#undef Max \n#undef Min\n#pragma pop_macro("Min")\n#pragma pop_macro("Max") ' test_value_2 = '#pragma push_macro("Max")\n#pragma push_macro("Min")\n#undef Max\n#undef Min\n#include "binary_c.h"\n\n// add visibility __attribute__ ((visibility ("default"))) to it \nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata);\nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata)\n{\n // struct stardata_t * stardata = (struct stardata_t *)x;\n Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));;\n}\n\n#undef Max \n#undef Min\n#pragma pop_macro("Min")\n#pragma pop_macro("Max") '
self.assertEqual( self.assertEqual(
...@@ -86,18 +85,18 @@ class test_custom_logging(unittest.TestCase): ...@@ -86,18 +85,18 @@ class test_custom_logging(unittest.TestCase):
binary_c_write_log_code( binary_c_write_log_code(
input_1, input_1,
os.path.join(binary_c_temp_dir, "test_binary_c_write_log_code.txt"), os.path.join(TMP_DIR, "test_binary_c_write_log_code.txt"),
verbose=1, verbosity=1,
) )
self.assertTrue( self.assertTrue(
os.path.isfile( os.path.isfile(
os.path.join(binary_c_temp_dir, "test_binary_c_write_log_code.txt") os.path.join(TMP_DIR, "test_binary_c_write_log_code.txt")
), ),
msg="File not created", msg="File not created",
) )
with open( with open(
os.path.join(binary_c_temp_dir, "test_binary_c_write_log_code.txt") os.path.join(TMP_DIR, "test_binary_c_write_log_code.txt")
) as f: ) as f:
content_file = repr(f.read()) content_file = repr(f.read())
self.assertEqual(repr(input_1), content_file, msg="Contents are not similar") self.assertEqual(repr(input_1), content_file, msg="Contents are not similar")
...@@ -144,7 +143,7 @@ class test_custom_logging(unittest.TestCase): ...@@ -144,7 +143,7 @@ class test_custom_logging(unittest.TestCase):
# Just going to check whether the dictionary has the components it needs # Just going to check whether the dictionary has the components it needs
# TODO: check whether we need to make this better # TODO: check whether we need to make this better
output = return_compilation_dict(verbose=1) output = return_compilation_dict(verbosity=1)
self.assertTrue("cc" in output) self.assertTrue("cc" in output)
self.assertTrue("ld" in output) self.assertTrue("ld" in output)
...@@ -164,7 +163,7 @@ class test_custom_logging(unittest.TestCase): ...@@ -164,7 +163,7 @@ class test_custom_logging(unittest.TestCase):
# #
input_1 = '#pragma push_macro("MAX")\n#pragma push_macro("MIN")\n#undef MAX\n#undef MIN\n#include "binary_c.h"\n\n// add visibility __attribute__ ((visibility ("default"))) to it \nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata);\nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata)\n{\n // struct stardata_t * stardata = (struct stardata_t *)x;\n Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));;\n}\n\n#undef MAX \n#undef MIN\n#pragma pop_macro("MIN")\n#pragma pop_macro("MAX") ' input_1 = '#pragma push_macro("MAX")\n#pragma push_macro("MIN")\n#undef MAX\n#undef MIN\n#include "binary_c.h"\n\n// add visibility __attribute__ ((visibility ("default"))) to it \nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata);\nvoid binary_c_API_function custom_output_function(struct stardata_t * stardata)\n{\n // struct stardata_t * stardata = (struct stardata_t *)x;\n Printf("MY_STELLAR_DATA %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));;\n}\n\n#undef MAX \n#undef MIN\n#pragma pop_macro("MIN")\n#pragma pop_macro("MAX") '
output_1 = create_and_load_logging_function(input_1, verbose=1) output_1 = create_and_load_logging_function(input_1, verbosity=1)
self.assertTrue(isinstance(output_1[0], int), msg="memaddr is not an int") self.assertTrue(isinstance(output_1[0], int), msg="memaddr is not an int")
self.assertTrue(output_1[0] > 0, msg="memaddr is an int but not set correctly") self.assertTrue(output_1[0] > 0, msg="memaddr is an int but not set correctly")
......
...@@ -6,8 +6,12 @@ import unittest ...@@ -6,8 +6,12 @@ import unittest
from binarycpython.utils.distribution_functions import * from binarycpython.utils.distribution_functions import *
from binarycpython.utils.useful_funcs import calc_sep_from_period from binarycpython.utils.useful_funcs import calc_sep_from_period
from binarycpython.utils.functions import Capturing from binarycpython.utils.functions import (
Capturing,
temp_dir
)
TMP_DIR = temp_dir("tests", "test_distributions")
class TestDistributions(unittest.TestCase): class TestDistributions(unittest.TestCase):
""" """
......
...@@ -8,19 +8,7 @@ from binarycpython.utils.functions import * ...@@ -8,19 +8,7 @@ from binarycpython.utils.functions import *
from binarycpython.utils.custom_logging_functions import binary_c_log_code from binarycpython.utils.custom_logging_functions import binary_c_log_code
from binarycpython.utils.run_system_wrapper import run_system from binarycpython.utils.run_system_wrapper import run_system
binary_c_temp_dir = temp_dir() TMP_DIR = temp_dir("tests", "test_functions")
#############################
# Script that contains unit tests for functions from the binarycpython.utils.functions file
# class test_(unittest.TestCase):
# """
# Unittests for function
# """
# def test_1(self):
# pass
class dummy: class dummy:
""" """
...@@ -82,11 +70,11 @@ class test_remove_file(unittest.TestCase): ...@@ -82,11 +70,11 @@ class test_remove_file(unittest.TestCase):
""" """
with open( with open(
os.path.join(binary_c_temp_dir, "test_remove_file_file.txt"), "w" os.path.join(TMP_DIR, "test_remove_file_file.txt"), "w"
) as f: ) as f:
f.write("test") f.write("test")
remove_file(os.path.join(binary_c_temp_dir, "test_remove_file_file.txt")) remove_file(os.path.join(TMP_DIR, "test_remove_file_file.txt"))
def test_remove_nonexisting_file(self): def test_remove_nonexisting_file(self):
with Capturing() as output: with Capturing() as output:
...@@ -97,7 +85,7 @@ class test_remove_file(unittest.TestCase): ...@@ -97,7 +85,7 @@ class test_remove_file(unittest.TestCase):
Test to try to remove a nonexistant file Test to try to remove a nonexistant file
""" """
file = os.path.join(binary_c_temp_dir, "test_remove_nonexistingfile_file.txt") file = os.path.join(TMP_DIR, "test_remove_nonexistingfile_file.txt")
remove_file(file) remove_file(file)
...@@ -141,7 +129,7 @@ class test_create_hdf5(unittest.TestCase): ...@@ -141,7 +129,7 @@ class test_create_hdf5(unittest.TestCase):
Test that creates files, packs them in a hdf5 file and checks the contents Test that creates files, packs them in a hdf5 file and checks the contents
""" """
testdir = os.path.join(binary_c_temp_dir, "test_create_hdf5") testdir = os.path.join(TMP_DIR, "test_create_hdf5")
os.makedirs(testdir, exist_ok=True) os.makedirs(testdir, exist_ok=True)
# Create dummy settings file: # Create dummy settings file:
...@@ -600,7 +588,7 @@ class test_write_binary_c_parameter_descriptions_to_rst_file(unittest.TestCase): ...@@ -600,7 +588,7 @@ class test_write_binary_c_parameter_descriptions_to_rst_file(unittest.TestCase):
""" """
output_name = os.path.join( output_name = os.path.join(
binary_c_temp_dir, TMP_DIR,
"test_write_binary_c_parameter_descriptions_to_rst_file_test_1.txt", "test_write_binary_c_parameter_descriptions_to_rst_file_test_1.txt",
) )
output_1 = write_binary_c_parameter_descriptions_to_rst_file(output_name) output_1 = write_binary_c_parameter_descriptions_to_rst_file(output_name)
...@@ -616,7 +604,7 @@ class test_write_binary_c_parameter_descriptions_to_rst_file(unittest.TestCase): ...@@ -616,7 +604,7 @@ class test_write_binary_c_parameter_descriptions_to_rst_file(unittest.TestCase):
""" """
output_name = os.path.join( output_name = os.path.join(
binary_c_temp_dir, TMP_DIR,
"test_write_binary_c_parameter_descriptions_to_rst_file_test_1.rst", "test_write_binary_c_parameter_descriptions_to_rst_file_test_1.rst",
) )
output_1 = write_binary_c_parameter_descriptions_to_rst_file(output_name) output_1 = write_binary_c_parameter_descriptions_to_rst_file(output_name)
......
...@@ -22,8 +22,7 @@ from binarycpython.utils.functions import ( ...@@ -22,8 +22,7 @@ from binarycpython.utils.functions import (
) )
from binarycpython.utils.custom_logging_functions import binary_c_log_code from binarycpython.utils.custom_logging_functions import binary_c_log_code
binary_c_temp_dir = temp_dir() TMP_DIR = temp_dir("tests", "test_grid")
TEST_VERBOSITY = 1 TEST_VERBOSITY = 1
def parse_function_test_grid_evolve_2_threads_with_custom_logging(self, output): def parse_function_test_grid_evolve_2_threads_with_custom_logging(self, output):
...@@ -342,7 +341,7 @@ class test_Population(unittest.TestCase): ...@@ -342,7 +341,7 @@ class test_Population(unittest.TestCase):
test_pop.set(metallicity=0.02, verbosity=TEST_VERBOSITY) test_pop.set(metallicity=0.02, verbosity=TEST_VERBOSITY)
test_pop.set(M_1=10) test_pop.set(M_1=10)
test_pop.set(amt_cores=2) test_pop.set(amt_cores=2)
test_pop.set(data_dir=binary_c_temp_dir) test_pop.set(data_dir=TMP_DIR)
# datadir # datadir
settings_filename = test_pop.export_all_info(use_datadir=True) settings_filename = test_pop.export_all_info(use_datadir=True)
...@@ -366,7 +365,7 @@ class test_Population(unittest.TestCase): ...@@ -366,7 +365,7 @@ class test_Population(unittest.TestCase):
# datadir # datadir
settings_filename = test_pop.export_all_info( settings_filename = test_pop.export_all_info(
use_datadir=False, use_datadir=False,
outfile=os.path.join(binary_c_temp_dir, "example_settings.json"), outfile=os.path.join(TMP_DIR, "example_settings.json"),
) )
self.assertTrue(os.path.isfile(settings_filename)) self.assertTrue(os.path.isfile(settings_filename))
with open(settings_filename, "r") as f: with open(settings_filename, "r") as f:
...@@ -389,7 +388,7 @@ class test_Population(unittest.TestCase): ...@@ -389,7 +388,7 @@ class test_Population(unittest.TestCase):
ValueError, ValueError,
test_pop.export_all_info, test_pop.export_all_info,
use_datadir=False, use_datadir=False,
outfile=os.path.join(binary_c_temp_dir, "example_settings.txt"), outfile=os.path.join(TMP_DIR, "example_settings.txt"),
) )
def test__cleanup_defaults(self): def test__cleanup_defaults(self):
...@@ -440,7 +439,7 @@ class test_Population(unittest.TestCase): ...@@ -440,7 +439,7 @@ class test_Population(unittest.TestCase):
Unittests for the function _dict_from_line_source_file Unittests for the function _dict_from_line_source_file
""" """
source_file = os.path.join(binary_c_temp_dir, "example_source_file.txt") source_file = os.path.join(TMP_DIR, "example_source_file.txt")
# write # write
with open(source_file, "w") as f: with open(source_file, "w") as f:
...@@ -602,7 +601,7 @@ class test_grid_evolve(unittest.TestCase): ...@@ -602,7 +601,7 @@ class test_grid_evolve(unittest.TestCase):
Unittests to see if multiple threads do the custom logging correctly Unittests to see if multiple threads do the custom logging correctly
""" """
data_dir_value = os.path.join(binary_c_temp_dir, "grid_tests") data_dir_value = os.path.join(TMP_DIR, "grid_tests")
amt_cores_value = 2 amt_cores_value = 2
custom_logging_string = 'Printf("MY_STELLAR_DATA_TEST_EXAMPLE %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));' custom_logging_string = 'Printf("MY_STELLAR_DATA_TEST_EXAMPLE %g %g %g %g\\n",((double)stardata->model.time),((double)stardata->star[0].mass),((double)stardata->model.probability),((double)stardata->model.dt));'
...@@ -784,7 +783,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -784,7 +783,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
Unittests to see if multiple threads output the ensemble information to files correctly Unittests to see if multiple threads output the ensemble information to files correctly
""" """
data_dir_value = binary_c_temp_dir data_dir_value = TMP_DIR
amt_cores_value = 2 amt_cores_value = 2
test_pop = Population() test_pop = Population()
...@@ -800,7 +799,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -800,7 +799,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
ensemble_dt=1000, ensemble_dt=1000,
) )
test_pop.set( test_pop.set(
data_dir=binary_c_temp_dir, data_dir=TMP_DIR,
ensemble_output_name="ensemble_output.json", ensemble_output_name="ensemble_output.json",
combine_ensemble_with_thread_joining=False, combine_ensemble_with_thread_joining=False,
) )
...@@ -858,7 +857,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -858,7 +857,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
Unittests to see if multiple threads correclty combine the ensemble data and store them in the grid Unittests to see if multiple threads correclty combine the ensemble data and store them in the grid
""" """
data_dir_value = binary_c_temp_dir data_dir_value = TMP_DIR
amt_cores_value = 2 amt_cores_value = 2
test_pop = Population() test_pop = Population()
...@@ -874,7 +873,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -874,7 +873,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
ensemble_dt=1000, ensemble_dt=1000,
) )
test_pop.set( test_pop.set(
data_dir=binary_c_temp_dir, data_dir=TMP_DIR,
combine_ensemble_with_thread_joining=True, combine_ensemble_with_thread_joining=True,
ensemble_output_name="ensemble_output.json", ensemble_output_name="ensemble_output.json",
) )
...@@ -915,7 +914,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -915,7 +914,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
Unittests to compare the method of storing the combined ensemble data in the object and writing them to files and combining them later. they have to be the same Unittests to compare the method of storing the combined ensemble data in the object and writing them to files and combining them later. they have to be the same
""" """
data_dir_value = binary_c_temp_dir data_dir_value = TMP_DIR
amt_cores_value = 2 amt_cores_value = 2
# First # First
...@@ -932,7 +931,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -932,7 +931,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
ensemble_dt=1000, ensemble_dt=1000,
) )
test_pop_1.set( test_pop_1.set(
data_dir=binary_c_temp_dir, data_dir=TMP_DIR,
combine_ensemble_with_thread_joining=True, combine_ensemble_with_thread_joining=True,
ensemble_output_name="ensemble_output.json", ensemble_output_name="ensemble_output.json",
) )
...@@ -971,7 +970,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n", ...@@ -971,7 +970,7 @@ Printf("TEST_CUSTOM_LOGGING_1 %30.12e %g %g %g %g\\n",
ensemble_dt=1000, ensemble_dt=1000,
) )
test_pop_2.set( test_pop_2.set(
data_dir=binary_c_temp_dir, data_dir=TMP_DIR,
ensemble_output_name="ensemble_output.json", ensemble_output_name="ensemble_output.json",
combine_ensemble_with_thread_joining=False, combine_ensemble_with_thread_joining=False,
) )
......
...@@ -14,8 +14,7 @@ from binarycpython.utils.grid_options_defaults import ( ...@@ -14,8 +14,7 @@ from binarycpython.utils.grid_options_defaults import (
grid_options_description_checker, grid_options_description_checker,
) )
binary_c_temp_dir = temp_dir() TMP_DIR = temp_dir("tests", "test_grid_options_defaults")
class test_grid_options_defaults(unittest.TestCase): class test_grid_options_defaults(unittest.TestCase):
""" """
...@@ -79,13 +78,13 @@ class test_grid_options_defaults(unittest.TestCase): ...@@ -79,13 +78,13 @@ class test_grid_options_defaults(unittest.TestCase):
""" """
input_1 = os.path.join( input_1 = os.path.join(
binary_c_temp_dir, "test_write_grid_options_to_rst_file_1.txt" TMP_DIR, "test_write_grid_options_to_rst_file_1.txt"
) )
output_1 = write_grid_options_to_rst_file(input_1) output_1 = write_grid_options_to_rst_file(input_1)
self.assertIsNone(output_1) self.assertIsNone(output_1)
input_2 = os.path.join( input_2 = os.path.join(
binary_c_temp_dir, "test_write_grid_options_to_rst_file_2.rst" TMP_DIR, "test_write_grid_options_to_rst_file_2.rst"
) )
output_2 = write_grid_options_to_rst_file(input_2) output_2 = write_grid_options_to_rst_file(input_2)
......
import unittest
import nbformat
import os
from nbconvert.preprocessors import ExecutePreprocessor
from binarycpython.utils.functions import temp_dir
TMP_DIR = temp_dir('testing', 'test_notebooks')
NOTEBOOKS_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '../../../examples'))
def run_notebook(notebook_path):
"""
Function to run notebooks and get the errors
"""
# https://www.blog.pythonlibrary.org/2018/10/16/testing-jupyter-notebooks/
nb_name, _ = os.path.splitext(os.path.basename(notebook_path))
dirname = os.path.dirname(notebook_path)
with open(notebook_path) as f:
nb = nbformat.read(f, as_version=4)
proc = ExecutePreprocessor(timeout=600, kernel_name='python3')
proc.allow_errors = True
proc.preprocess(nb, {'metadata': {'path': '/'}})
output_path = os.path.join(TMP_DIR, '{}_all_output.ipynb'.format(nb_name))
with open(output_path, mode='wt') as f:
nbformat.write(nb, f)
errors = []
for cell in nb.cells:
if 'outputs' in cell:
for output in cell['outputs']:
if output.output_type == 'error':
errors.append(output)
return nb, errors
class TestNotebook(unittest.TestCase):
"""
Class that contains the notebook test calls
"""
def test_notebook_api_functionality(self):
notebook_name = 'notebook_api_functionality.ipynb'
full_notebook_path = os.path.join(NOTEBOOKS_DIR, notebook_name)
nb, errors = run_notebook(full_notebook_path)
msg = "\nNotebook: {}\n\n".format(notebook_name) + "\n".join(["{}: {}\n{}".format(el['ename'], el['evalue'], '\n'.join(el['traceback'])) for el in errors])
self.assertEqual(errors, [], msg=msg)
def test_notebook_population(self):
notebook_name = 'notebook_population.ipynb'
full_notebook_path = os.path.join(NOTEBOOKS_DIR, notebook_name)
nb, errors = run_notebook(full_notebook_path)
msg = "\nNotebook: {}\n\n".format(notebook_name) + "\n".join(["{}: {}\n{}".format(el['ename'], el['evalue'], '\n'.join(el['traceback'])) for el in errors])
self.assertEqual(errors, [], msg=msg)
def test_notebook_individual_systems(self):
notebook_name = 'notebook_individual_systems.ipynb'
full_notebook_path = os.path.join(NOTEBOOKS_DIR, notebook_name)
nb, errors = run_notebook(full_notebook_path)
msg = "\nNotebook: {}\n\n".format(notebook_name) + "\n".join(["{}: {}\n{}".format(el['ename'], el['evalue'], '\n'.join(el['traceback'])) for el in errors])
self.assertEqual(errors, [], msg=msg)
def test_notebook_extra_features(self):
notebook_name = 'notebook_extra_features.ipynb'
full_notebook_path = os.path.join(NOTEBOOKS_DIR, notebook_name)
nb, errors = run_notebook(full_notebook_path)
msg = "\nNotebook: {}\n\n".format(notebook_name) + "\n".join(["{}: {}\n{}".format(el['ename'], el['evalue'], '\n'.join(el['traceback'])) for el in errors])
self.assertEqual(errors, [], msg=msg)
if __name__ == '__main__':
unittest.main()
...@@ -9,13 +9,7 @@ import matplotlib.pyplot as plt ...@@ -9,13 +9,7 @@ import matplotlib.pyplot as plt
from binarycpython.utils.plot_functions import * from binarycpython.utils.plot_functions import *
from binarycpython.utils.functions import Capturing from binarycpython.utils.functions import Capturing
# class test_(unittest.TestCase):
# """
# Unittests for function
# """
# def test_1(self):
# pass
class test_color_by_index(unittest.TestCase): class test_color_by_index(unittest.TestCase):
......
...@@ -1411,11 +1411,6 @@ class Population: ...@@ -1411,11 +1411,6 @@ class Population:
ensemble_json["ensemble"] = extract_ensemble_json_from_string( ensemble_json["ensemble"] = extract_ensemble_json_from_string(
ensemble_raw_output ensemble_raw_output
) # Load this into a dict so that we can combine it later ) # Load this into a dict so that we can combine it later
# Extra ensemble result manipulation:
# We need to reformat and multiply by a factor
ensemble_json["ensemble"] = self.format_ensemble_results(ensemble_json["ensemble"])
gc.collect()
else: else:
# If we do not allow this, automatically we will export this to the data_dir, in # If we do not allow this, automatically we will export this to the data_dir, in
# some formatted way # some formatted way
...@@ -1427,8 +1422,9 @@ class Population: ...@@ -1427,8 +1422,9 @@ class Population:
) )
# Write to file # Write to file
ensemble_output = extract_ensemble_json_from_string(ensemble_raw_output)
with open(output_file, "w") as f: with open(output_file, "w") as f:
f.write(ensemble_raw_output) f.write(json.dumps(self.format_ensemble_results(ensemble_output)))
print( print(
"Thread {}: Wrote ensemble results directly to file: {}".format( "Thread {}: Wrote ensemble results directly to file: {}".format(
......
%% Cell type:markdown id:a544d28c-c2e1-4c6a-b55b-8caec440743f tags: %% Cell type:markdown id:a544d28c-c2e1-4c6a-b55b-8caec440743f tags:
# Running individual systems with binarycpython # Running individual systems with binarycpython
This notebook will show you how to run single systems and analyze their results. This notebook will show you how to run single systems and analyze their results.
It can be useful to have some functions to quickly run a single system to e.g. inspect what evolutionary steps a specific system goes through, to plot the mass loss evolution of a single star, etc. It can be useful to have some functions to quickly run a single system to e.g. inspect what evolutionary steps a specific system goes through, to plot the mass loss evolution of a single star, etc.
%% Cell type:markdown id:dd5d9ec7-5791-45f1-afbd-225947e2a583 tags: %% Cell type:markdown id:dd5d9ec7-5791-45f1-afbd-225947e2a583 tags:
## Single system with run_wrapper ## Single system with run_wrapper
The simplest method to run a single system is to use the run_system wrapper. This function deals with setting up the argument string, makes sure all the required parameters are included and handles setting and cleaning up the custom logging functionality (see notebook_custom_logging). The simplest method to run a single system is to use the run_system wrapper. This function deals with setting up the argument string, makes sure all the required parameters are included and handles setting and cleaning up the custom logging functionality (see notebook_custom_logging).
As arguments to this function we can add any of the parameters that binary_c itself actually knows, as well as: As arguments to this function we can add any of the parameters that binary_c itself actually knows, as well as:
- custom_logging_code: string containing a print statement that binary_c can use to print information - custom_logging_code: string containing a print statement that binary_c can use to print information
- log_filename: path of the logfile that binary_c generates - log_filename: path of the logfile that binary_c generates
- parse_function: function that handles parsing the output of binary-c - parse_function: function that handles parsing the output of binary-c
%% Cell type:code id:e32dcdee tags:
``` python
import os
from binarycpython.utils.functions import temp_dir
TMP_DIR = temp_dir("notebooks", "notebook_individual_systems")
```
%% Cell type:code id:425efed3-d8e3-432d-829e-41d8ebe05162 tags: %% Cell type:code id:425efed3-d8e3-432d-829e-41d8ebe05162 tags:
``` python ``` python
from binarycpython.utils.run_system_wrapper import run_system from binarycpython.utils.run_system_wrapper import run_system
# help(run_system) # Uncomment to see the docstring # help(run_system) # Uncomment to see the docstring
``` ```
%% Cell type:code id:b2abab48-433d-4936-8434-14804c52c9f6 tags: %% Cell type:code id:b2abab48-433d-4936-8434-14804c52c9f6 tags:
``` python ``` python
output = run_system(M_1=1) output = run_system(M_1=1)
print(output) print(output)
``` ```
%% Output %% Output
SINGLE_STAR_LIFETIME 1 12462 SINGLE_STAR_LIFETIME 1 12461.9
%% Cell type:markdown id:f127a5e4-dc01-4472-9130-8a943c92e8a7 tags: %% Cell type:markdown id:f127a5e4-dc01-4472-9130-8a943c92e8a7 tags:
Lets try adding a log filename now: Lets try adding a log filename now:
%% Cell type:code id:029fc3f2-f09a-49af-a32b-248505738f2e tags: %% Cell type:code id:029fc3f2-f09a-49af-a32b-248505738f2e tags:
``` python ``` python
output = run_system(M_1=1, log_filename='/tmp/test_logfile.txt') log_filename = os.path.join(TMP_DIR, 'test_logfile.txt')
with open('/tmp/test_logfile.txt', 'r') as f: output = run_system(M_1=1, log_filename=log_filename, api_log_filename_prefix=TMP_DIR)
with open(log_filename, 'r') as f:
print(f.read()) print(f.read())
``` ```
%% Output %% Output
TIME M1 M2 K1 K2 SEP ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=67365 RANDOM_COUNT=0 TIME M1 M2 K1 K2 SEP PER ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=9935 RANDOM_COUNT=0
0.0000 1.000 0.000 1 15 -1 -1.00 0.000 0.000 "INITIAL " 0.0000 1.000 0.000 1 15 -1 -1 -1.00 0.000 0.000 "INITIAL "
11003.1302 1.000 0.000 2 15 -1 -1.00 0.000 0.000 "OFF_MS" 11003.1302 1.000 0.000 2 15 -1 -1 -1.00 0.000 0.000 "OFF_MS"
11003.1302 1.000 0.000 2 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 11003.1302 1.000 0.000 2 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
11582.2424 1.000 0.000 3 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 11582.2424 1.000 0.000 3 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
12325.1085 0.817 0.000 4 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 12325.1085 0.817 0.000 4 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
12457.1300 0.783 0.000 5 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 12457.1301 0.783 0.000 5 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
12460.8955 0.774 0.000 6 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 12460.9983 0.716 0.000 6 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
12460.8955 0.774 0.000 6 15 -1 -1.00 0.000 0.000 "shrinkAGB" 12460.9983 0.716 0.000 6 15 -1 -1 -1.00 0.000 0.000 "shrinkAGB"
12461.9514 0.523 0.000 11 15 -1 -1.00 0.000 0.000 "TYPE_CHNGE" 12461.9458 0.518 0.000 11 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
15000.0000 0.523 0.000 11 15 -1 -1.00 0.000 0.000 "MAX_TIME" 15000.0000 0.518 0.000 11 15 -1 -1 -1.00 0.000 0.000 "MAX_TIME"
%% Cell type:markdown id:606670f2-3e0a-43c7-a885-006b92fac9d2 tags: %% Cell type:markdown id:606670f2-3e0a-43c7-a885-006b92fac9d2 tags:
To get more useful output we can include a custom_logging snippet (see notebook_custom_logging): To get more useful output we can include a custom_logging snippet (see notebook_custom_logging):
%% Cell type:code id:e6a23b55-ca42-440d-83ac-e76a24a83a67 tags: %% Cell type:code id:e6a23b55-ca42-440d-83ac-e76a24a83a67 tags:
``` python ``` python
from binarycpython.utils.custom_logging_functions import binary_c_log_code from binarycpython.utils.custom_logging_functions import binary_c_log_code
# Create the print statement # Create the print statement
custom_logging_print_statement = """ custom_logging_print_statement = """
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %d\\n", Printf("EXAMPLE_MASSLOSS %30.12e %g %g %d\\n",
// //
stardata->model.time, // 1 stardata->model.time, // 1
stardata->star[0].mass, //2 stardata->star[0].mass, //2
stardata->common.zero_age.mass[0], //4 stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5 stardata->star[0].stellar_type //5
); );
""" """
# Generate entire shared lib code around logging lines # Generate entire shared lib code around logging lines
custom_logging_code = binary_c_log_code(custom_logging_print_statement) custom_logging_code = binary_c_log_code(custom_logging_print_statement)
output = run_system(M_1=1, custom_logging_code=custom_logging_code) output = run_system(M_1=1, custom_logging_code=custom_logging_code, api_log_filename_prefix=TMP_DIR)
print(output.splitlines()[:4]) print('\n'.join(output.splitlines()[:4]))
``` ```
%% Output %% Output
['EXAMPLE_MASSLOSS 0.000000000000e+00 1 1 1', 'EXAMPLE_MASSLOSS 0.000000000000e+00 1 1 1', 'EXAMPLE_MASSLOSS 1.000000000000e-06 1 1 1', 'EXAMPLE_MASSLOSS 2.000000000000e-06 1 1 1'] EXAMPLE_MASSLOSS 0.000000000000e+00 1 1 1
EXAMPLE_MASSLOSS 0.000000000000e+00 1 1 1
EXAMPLE_MASSLOSS 1.000000000000e-06 1 1 1
EXAMPLE_MASSLOSS 2.000000000000e-06 1 1 1
%% Cell type:markdown id:4c885143-db79-4fed-b4c4-0bd846e24f7d tags: %% Cell type:markdown id:4c885143-db79-4fed-b4c4-0bd846e24f7d tags:
Now we have some actual output, it is time to create a parse_function which parses the output. Adding a parse_function to the run_system will make run_system run the output of binary_c through the parse_function. Now we have some actual output, it is time to create a parse_function which parses the output. Adding a parse_function to the run_system will make run_system run the output of binary_c through the parse_function.
%% Cell type:code id:3822721f-217a-495b-962e-d57137b9e290 tags: %% Cell type:code id:3822721f-217a-495b-962e-d57137b9e290 tags:
``` python ``` python
def parse_function(output): def parse_function(output):
""" """
Example function to parse the output of binary_c Example function to parse the output of binary_c
""" """
# #
column_names = ['time', 'mass', 'initial_mass', 'stellar_type'] column_names = ['time', 'mass', 'initial_mass', 'stellar_type']
value_lines = [column_names] value_lines = [column_names]
# Loop over output # Loop over output
for line in output.splitlines(): for line in output.splitlines():
# Select the lines starting with the header we chose # Select the lines starting with the header we chose
if line.startswith("EXAMPLE_MASSLOSS"): if line.startswith("EXAMPLE_MASSLOSS"):
# Split the output and fetch the data # Split the output and fetch the data
split_line = line.split() split_line = line.split()
values = [float(el) for el in split_line[1:]] values = [float(el) for el in split_line[1:]]
value_lines.append(values) value_lines.append(values)
return value_lines return value_lines
# Catch output # Catch output
output = run_system(M_1=1, custom_logging_code=custom_logging_code, parse_function=parse_function) output = run_system(M_1=1, custom_logging_code=custom_logging_code, parse_function=parse_function)
print(output[:3]) print(output[:3])
``` ```
%% Output %% Output
[['time', 'mass', 'initial_mass', 'stellar_type'], [0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0]] [['time', 'mass', 'initial_mass', 'stellar_type'], [0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0]]
%% Cell type:markdown id:a551f07f-2eff-4425-9375-267579a581b3 tags: %% Cell type:markdown id:a551f07f-2eff-4425-9375-267579a581b3 tags:
This output can now be turned into e.g. an Numpy array or Pandas dataframe (my favorite: makes querying the data very easy) This output can now be turned into e.g. an Numpy array or Pandas dataframe (my favorite: makes querying the data very easy)
%% Cell type:code id:654a07ed-2a88-46ff-9da0-b7759580f9f3 tags: %% Cell type:code id:654a07ed-2a88-46ff-9da0-b7759580f9f3 tags:
``` python ``` python
import pandas as pd import pandas as pd
# Load data into dataframe # Load data into dataframe
example_df = pd.DataFrame(output) example_df = pd.DataFrame(output)
# Fix column headers # Fix column headers
example_df.columns = example_df.iloc[0] example_df.columns = example_df.iloc[0]
example_df = example_df.drop(example_df.index[0]) example_df = example_df.drop(example_df.index[0])
print(example_df) print(example_df)
``` ```
%% Output %% Output
0 time mass initial_mass stellar_type 0 time mass initial_mass stellar_type
1 0 1 1 1 1 0 1 1 1
2 0 1 1 1 2 0 1 1 1
3 1e-06 1 1 1 3 1e-06 1 1 1
4 2e-06 1 1 1 4 2e-06 1 1 1
5 3e-06 1 1 1 5 3e-06 1 1 1
... ... ... ... ... ... ... ... ... ...
1612 12461.8 0.577754 1 6 1617 12461.8 0.546683 1 6
1613 12462 0.522806 1 11 1618 12461.9 0.517749 1 11
1614 13462 0.522806 1 11 1619 13461.9 0.517749 1 11
1615 14462 0.522806 1 11 1620 14461.9 0.517749 1 11
1616 15000 0.522806 1 11 1621 15000 0.517749 1 11
[1616 rows x 4 columns] [1621 rows x 4 columns]
%% Cell type:markdown id:325c2ce6-f9a1-46b7-937f-84040e1252cf tags: %% Cell type:markdown id:325c2ce6-f9a1-46b7-937f-84040e1252cf tags:
## Single system via population object ## Single system via population object
When setting up your population object (see notebook_population), and configuring all the parameters, it is possible to run a single system using that same configuration. It will use the parse_function if set, and running a single system is a good method to test if everything works accordingly. When setting up your population object (see notebook_population), and configuring all the parameters, it is possible to run a single system using that same configuration. It will use the parse_function if set, and running a single system is a good method to test if everything works accordingly.
%% Cell type:code id:4a98ffca-1b72-4bb8-8df1-3bf3187d882f tags: %% Cell type:code id:4a98ffca-1b72-4bb8-8df1-3bf3187d882f tags:
``` python ``` python
from binarycpython.utils.grid import Population from binarycpython.utils.grid import Population
# help(Population) # Uncomment to see the docstring # help(Population) # Uncomment to see the docstring
``` ```
%% Cell type:markdown id:7e2c2ef0-3db2-46a6-8c85-9b6cf720eb6a tags: %% Cell type:markdown id:7e2c2ef0-3db2-46a6-8c85-9b6cf720eb6a tags:
First, let's try this without any custom logging or parsing functionality First, let's try this without any custom logging or parsing functionality
%% Cell type:code id:bff1cc2e-6b32-4ba0-879f-879ffbabd223 tags: %% Cell type:code id:bff1cc2e-6b32-4ba0-879f-879ffbabd223 tags:
``` python ``` python
# Create the population object # Create the population object
example_pop = Population() example_pop = Population()
# Set some parameters # Set some parameters
example_pop.set( example_pop.set(
verbosity=1 verbosity=1,
api_log_filename_prefix=TMP_DIR
) )
example_pop.set( example_pop.set(
M_1=10 M_1=10
) )
# get output and print # get output and print
output = example_pop.evolve_single() output = example_pop.evolve_single()
print(output) print(output)
``` ```
%% Output %% Output
adding: api_log_filename_prefix=/tmp/binary_c_python/notebooks/notebook_individual_systems to BSE_options
adding: M_1=10 to BSE_options adding: M_1=10 to BSE_options
Creating and loading custom logging functionality Creating and loading custom logging functionality
Running binary_c M_1 10 Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single Cleaning up the custom logging stuff. type: single
SINGLE_STAR_LIFETIME 10 27.7358 SINGLE_STAR_LIFETIME 10 28.4838
%% Cell type:markdown id:ae01fa35-f8b1-4a40-bfb2-b9e872cae0e7 tags: %% Cell type:markdown id:ae01fa35-f8b1-4a40-bfb2-b9e872cae0e7 tags:
Now lets add some actual output with the custom logging Now lets add some actual output with the custom logging
%% Cell type:code id:dd748bab-b57e-4129-8350-9ea11fa179d0 tags: %% Cell type:code id:dd748bab-b57e-4129-8350-9ea11fa179d0 tags:
``` python ``` python
custom_logging_print_statement = """ custom_logging_print_statement = """
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\\n", Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\\n",
// //
stardata->model.time, // 1 stardata->model.time, // 1
stardata->star[0].mass, //2 stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3 stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4 stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5 stardata->star[0].stellar_type //5
); );
""" """
example_pop.set(C_logging_code=custom_logging_print_statement) example_pop.set(C_logging_code=custom_logging_print_statement)
# get output and print # get output and print
output = example_pop.evolve_single() output = example_pop.evolve_single()
print(output.splitlines()[:4]) print('\n'.join(output.splitlines()[:4]))
``` ```
%% Output %% Output
adding: C_logging_code= adding: C_logging_code=
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\n", Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\n",
// //
stardata->model.time, // 1 stardata->model.time, // 1
stardata->star[0].mass, //2 stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3 stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4 stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5 stardata->star[0].stellar_type //5
); );
to grid_options to grid_options
Creating and loading custom logging functionality Creating and loading custom logging functionality
Running binary_c M_1 10 Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single Cleaning up the custom logging stuff. type: single
Removed /tmp/binary_c_python/custom_logging/libcustom_logging_eac2dfc438a14e5a9f5be98b1b6b4294.so Removed /tmp/binary_c_python/custom_logging/libcustom_logging_491813c1f1184f97951202e364eb3b55.so
['EXAMPLE_MASSLOSS 0.000000000000e+00 10 0 10 1', 'EXAMPLE_MASSLOSS 0.000000000000e+00 10 10 10 1', 'EXAMPLE_MASSLOSS 1.000000000000e-06 10 10 10 1', 'EXAMPLE_MASSLOSS 2.000000000000e-06 10 10 10 1'] EXAMPLE_MASSLOSS 0.000000000000e+00 10 0 10 1
EXAMPLE_MASSLOSS 0.000000000000e+00 10 10 10 1
EXAMPLE_MASSLOSS 1.000000000000e-06 10 10 10 1
EXAMPLE_MASSLOSS 2.000000000000e-06 10 10 10 1
%% Cell type:markdown id:588a7d9e-9d64-4b3b-8907-656b905286e8 tags: %% Cell type:markdown id:588a7d9e-9d64-4b3b-8907-656b905286e8 tags:
Lastly we can add a parse_function to handle parsing the output again. Lastly we can add a parse_function to handle parsing the output again.
Because the parse_function will now be part of the population object, it can access information of the object. We need to make a new parse function that is fit for an object: we the arguments now need to be (self, output). Returning the data is useful when running evolve_single(), but won't be used in a population evolution. Because the parse_function will now be part of the population object, it can access information of the object. We need to make a new parse function that is fit for an object: we the arguments now need to be (self, output). Returning the data is useful when running evolve_single(), but won't be used in a population evolution.
%% Cell type:code id:fec39154-cce6-438c-8c2c-509d76b00f34 tags: %% Cell type:code id:fec39154-cce6-438c-8c2c-509d76b00f34 tags:
``` python ``` python
import os import os
import json import json
import numpy as np import numpy as np
def object_parse_function(self, output): def object_parse_function(self, output):
""" """
Example parse function that can be added to the population object Example parse function that can be added to the population object
""" """
# We can access object instance information now. # We can access object instance information now.
# In this way we can store the results in a file for example. # In this way we can store the results in a file for example.
output_file = os.path.join(self.custom_options['output_dir'], 'example_output.json') output_file = os.path.join(self.custom_options['output_dir'], 'example_output.json')
# #
column_names = ['time', 'mass', 'initial_mass', 'stellar_type'] column_names = ['time', 'mass', 'initial_mass', 'stellar_type']
value_lines = [column_names] value_lines = [column_names]
# Loop over output # Loop over output
for line in output.splitlines(): for line in output.splitlines():
# Select the lines starting with the header we chose # Select the lines starting with the header we chose
if line.startswith("EXAMPLE_MASSLOSS"): if line.startswith("EXAMPLE_MASSLOSS"):
# Split the output and fetch the data # Split the output and fetch the data
split_line = line.split() split_line = line.split()
values = [float(el) for el in split_line[1:]] values = [float(el) for el in split_line[1:]]
value_lines.append(values) value_lines.append(values)
# Turn into an array # Turn into an array
values_array = np.array(value_lines[1:]) values_array = np.array(value_lines[1:])
# make dict and fill # make dict and fill
output_dict = {} output_dict = {}
for i in range(len(column_names)): for i in range(len(column_names)):
output_dict[column_names[i]] = list(values_array[:,i]) output_dict[column_names[i]] = list(values_array[:,i])
# Write to file # Write to file
with open(output_file, 'w') as f: with open(output_file, 'w') as f:
f.write(json.dumps(output_dict, indent=4)) f.write(json.dumps(output_dict, indent=4))
# Return something anyway # Return something anyway
return value_lines return value_lines
``` ```
%% Cell type:code id:57347512-fd4a-434b-b13c-5e6dbd3ac415 tags: %% Cell type:code id:57347512-fd4a-434b-b13c-5e6dbd3ac415 tags:
``` python ``` python
example_pop.set( example_pop.set(
parse_function=object_parse_function, parse_function=object_parse_function,
output_dir='/tmp/' output_dir=TMP_DIR,
api_log_filename_prefix=TMP_DIR
) )
output = example_pop.evolve_single() output = example_pop.evolve_single()
print(output[:4]) print(output[:4])
# Example of loading the data that was written # Example of loading the data that was written
with open(os.path.join(example_pop.custom_options['output_dir'], 'example_output.json')) as f: with open(os.path.join(example_pop.custom_options['output_dir'], 'example_output.json')) as f:
written_data = json.loads(f.read()) written_data = json.loads(f.read())
print(written_data.keys()) print(written_data.keys())
``` ```
%% Output %% Output
adding: parse_function=<function object_parse_function at 0x7f9265091598> to grid_options adding: parse_function=<function object_parse_function at 0x7fa3136e5378> to grid_options
<<<< Warning: Key does not match previously known parameter: adding: output_dir=/tmp/ to custom_options >>>> <<<< Warning: Key does not match previously known parameter: adding: output_dir=/tmp/binary_c_python/notebooks/notebook_individual_systems to custom_options >>>>
adding: api_log_filename_prefix=/tmp/binary_c_python/notebooks/notebook_individual_systems to BSE_options
Creating and loading custom logging functionality Creating and loading custom logging functionality
Running binary_c M_1 10 Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single Cleaning up the custom logging stuff. type: single
Removed /tmp/binary_c_python/custom_logging/libcustom_logging_e9c2bec7f15541eb847fc6013e48e7ed.so Removed /tmp/binary_c_python/custom_logging/libcustom_logging_83729c10ca52451cb773d29d6b28ea96.so
[['time', 'mass', 'initial_mass', 'stellar_type'], [0.0, 10.0, 0.0, 10.0, 1.0], [0.0, 10.0, 10.0, 10.0, 1.0], [1e-06, 10.0, 10.0, 10.0, 1.0]] [['time', 'mass', 'initial_mass', 'stellar_type'], [0.0, 10.0, 0.0, 10.0, 1.0], [0.0, 10.0, 10.0, 10.0, 1.0], [1e-06, 10.0, 10.0, 10.0, 1.0]]
dict_keys(['time', 'mass', 'initial_mass', 'stellar_type']) dict_keys(['time', 'mass', 'initial_mass', 'stellar_type'])
%% Cell type:markdown id:ddc06da3-fc68-4c6f-8067-14ea862b964d tags: %% Cell type:markdown id:ddc06da3-fc68-4c6f-8067-14ea862b964d tags:
## Single system via API functionality ## Single system via API functionality
It is possible to construct your own functionality to run a single system by directly calling the API function to run a system. Under the hood all the other functions and wrappers actually use this API. It is possible to construct your own functionality to run a single system by directly calling the API function to run a system. Under the hood all the other functions and wrappers actually use this API.
There are less failsafes for this method, so this make sure the input is correct and binary_c knows all the arguments you pass in. There are less failsafes for this method, so this make sure the input is correct and binary_c knows all the arguments you pass in.
for more details on this API function see `notebook_api_functions` for more details on this API function see `notebook_api_functions`
%% Cell type:markdown id:56886792-d379-4eac-b0d4-54508edb39c7 tags: %% Cell type:markdown id:56886792-d379-4eac-b0d4-54508edb39c7 tags:
First we must construct the argument string that we pass to binary_c First we must construct the argument string that we pass to binary_c
%% Cell type:code id:ec48125c-6bf5-48f4-9357-8261800b5d8b tags: %% Cell type:code id:ec48125c-6bf5-48f4-9357-8261800b5d8b tags:
``` python ``` python
# For a binary system we need to pass in these arguments # For a binary system we need to pass in these arguments
M_1 = 15.0 # Msun M_1 = 15.0 # Msun
M_2 = 14.0 # Msun M_2 = 14.0 # Msun
separation = 0 # 0 = ignored, use period separation = 0 # 0 = ignored, use period
orbital_period = 4530.0 # days orbital_period = 4530.0 # days
eccentricity = 0.0 eccentricity = 0.0
metallicity = 0.02 metallicity = 0.02
max_evolution_time = 15000 # Myr. You need to include this argument. max_evolution_time = 15000 # Myr. You need to include this argument.
api_log_filename_prefix = TMP_DIR
# Here we set up the argument string that is passed to the bindings # Here we set up the argument string that is passed to the bindings
argstring = """ argstring = """
binary_c M_1 {M_1} M_2 {M_2} separation {separation} orbital_period {orbital_period} eccentricity {eccentricity} metallicity {metallicity} max_evolution_time {max_evolution_time} binary_c M_1 {M_1} M_2 {M_2} separation {separation} orbital_period {orbital_period} eccentricity {eccentricity} metallicity {metallicity} max_evolution_time {max_evolution_time} api_log_filename_prefix {api_log_filename_prefix}
""".format( """.format(
M_1=M_1, M_1=M_1,
M_2=M_2, M_2=M_2,
separation=separation, separation=separation,
orbital_period=orbital_period, orbital_period=orbital_period,
eccentricity=eccentricity, eccentricity=eccentricity,
metallicity=metallicity, metallicity=metallicity,
max_evolution_time=max_evolution_time, max_evolution_time=max_evolution_time,
api_log_filename_prefix=TMP_DIR
).strip() ).strip()
from binarycpython import _binary_c_bindings from binarycpython import _binary_c_bindings
output = _binary_c_bindings.run_system(argstring) output = _binary_c_bindings.run_system(argstring)
print(output) print(output)
``` ```
%% Output %% Output
SINGLE_STAR_LIFETIME 15 14.2383 SINGLE_STAR_LIFETIME 15 14.9947
%% Cell type:markdown id:55c8ea24-0fc0-452c-8121-1e7667433479 tags: %% Cell type:markdown id:55c8ea24-0fc0-452c-8121-1e7667433479 tags:
As we can see above, the output is rather empty. But if SINGLE_STAR_LIFETIME is printed we know we caught the output correctly. To get actual output we should have timesteps printed in the `log_every_timestep.c` in binary_c, or add some custom_logging (see notebook_custom_logging). As we can see above, the output is rather empty. But if SINGLE_STAR_LIFETIME is printed we know we caught the output correctly. To get actual output we should have timesteps printed in the `log_every_timestep.c` in binary_c, or add some custom_logging (see notebook_custom_logging).
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment