Skip to content
Snippets Groups Projects
Commit d7673a57 authored by dh00601's avatar dh00601
Browse files

rebuilt the reports and the docs

parent 15fbbaba
No related branches found
No related tags found
No related merge requests found
Showing
with 295 additions and 822 deletions
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="142" height="20">
<linearGradient id="s" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="r">
<rect width="142" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#r)">
<rect width="99" height="20" fill="#555"/>
<rect x="99" width="43" height="20" fill="#4c1"/>
<rect width="142" height="20" fill="url(#s)"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="110">
<text x="505" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="890">docstr-coverage</text>
<text x="505" y="140" transform="scale(.1)" textLength="890">docstr-coverage</text>
<text x="1195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">100%</text>
<text x="1195" y="140" transform="scale(.1)">100%</text>
</g>
</svg>
\ No newline at end of file
......@@ -15,7 +15,7 @@
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="31.5" y="14">coverage</text>
<text x="80" y="15" fill="#010101" fill-opacity=".3">72%</text>
<text x="80" y="14">72%</text>
<text x="80" y="15" fill="#010101" fill-opacity=".3">71%</text>
<text x="80" y="14">71%</text>
</g>
</svg>
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
File added
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
%% Cell type:markdown id:879b596b-d70c-4f90-b668-563b4ad93ffc tags:
# Tutorial: Using custom logging routines with binary_c-python
In this notebook you'll learn how to use the custom logging functionality
%% Cell type:code id:696ecbb9-1efd-48f4-a57e-2cf6dfe416f1 tags:
``` python
from binarycpython import _binary_c_bindings
from binarycpython.utils.custom_logging_functions import (
autogen_C_logging_code,
binary_c_log_code,
create_and_load_logging_function,
)
from binarycpython.utils.run_system_wrapper import run_system
from binarycpython.utils.grid import Population
from binarycpython import Population
```
%% Cell type:markdown id:d4d721cc-df4f-4ac2-b6f9-62e85ca0c1e5 tags:
The custom logging functionality allows us to decide the output of binary_c _without_ modifying the actual sourcecode of binary_c (i.e. editing `src/logging/log_every_timestep` in binary_c). Rather, we can create a logging routine from within python.
Technically, the following steps are taken:
- User creates a logging print statement from within python
- The logging print statement string gets wrapped into a proper c-function by `binary_c_log_code`
- The c-function string gets compiled and loaded into memory by `create_and_load_logging_function`
- The memory adress of the compiled and loaded print function can now be passed to C
- binary_c uses the custom print function
The custom logging functionality can be used when running systems via `run_system()`, via `Population.evolve()` and `Population.evolve_single()`, and directly via the API
Within the logging statement we can access information from the stardata object, as well as use logical statements to determine when to log information. What we cannot do, however, is access functions that are not _publicly available_. For very elaborate printing routines it is still advised to actually hardcode the print statement into binary_c itself.
%% Cell type:markdown id:be137151-bb57-43d7-bab1-0167512ac727 tags:
## Usage
%% Cell type:markdown id:ac4e5f4c-81e6-4980-b852-aca84ca74f4c tags:
There are two methods to create the C-code that will be compiled:
- Automatically generate the print statement and use the wrapper to generate the full function string, by using `autogen_C_logging_code`
- Create your custom print statement and use the wrapper to generate the full function string, by writing out the print statement. Here the logging statement obviously has to be valid C code
%% Cell type:code id:236cf821-09ac-4237-9b8f-6e36d2edf446 tags:
``` python
# generate logging lines. Here you can choose whatever you want to have logged, and with what header
# this generates working print statements
logging_line = autogen_C_logging_code(
{
"MY_STELLAR_DATA": ["model.time", "star[0].mass"],
}
)
print(logging_line)
```
%% Output
Printf("MY_STELLAR_DATA %g %g\n",((double)stardata->model.time),((double)stardata->star[0].mass));
%% Cell type:code id:feb423d5-5cc3-433c-9801-f8017abbc03a tags:
``` python
# You can also decide to `write` your own logging_line, which allows you to write a more complex logging statement with conditionals.
logging_line = 'Printf("MY_STELLAR_DATA time=%g mass=%g\\n", stardata->model.time, stardata->star[0].mass)'
print(logging_line)
```
%% Output
Printf("MY_STELLAR_DATA time=%g mass=%g\n", stardata->model.time, stardata->star[0].mass)
%% Cell type:code id:2f5defbf-c623-49ed-a238-fba52a563a58 tags:
``` python
# Generate the entire 'script' by wrapping the logging line
custom_logging_code = binary_c_log_code(logging_line)
print(custom_logging_code)
```
%% Output
#pragma push_macro("Max")
#pragma push_macro("Min")
#undef Max
#undef Min
#include "binary_c.h"
// add visibility __attribute__ ((visibility ("default"))) to it
void binary_c_API_function custom_output_function(struct stardata_t * stardata);
void binary_c_API_function custom_output_function(struct stardata_t * stardata)
{
// struct stardata_t * stardata = (struct stardata_t *)x;
Printf("MY_STELLAR_DATA time=%g mass=%g\n", stardata->model.time, stardata->star[0].mass);
}
#undef Max
#undef Min
#pragma pop_macro("Min")
#pragma pop_macro("Max")
%% Cell type:markdown id:efa7f1e9-247e-4196-a883-bcff05265d02 tags:
Combining the above with e.g. run_system() (see notebook_individual_systems for more examples):
%% Cell type:code id:dcd74bbc-478b-43e4-b495-8c456e8d1d88 tags:
``` python
# logging statement
logging_line = 'Printf("MY_STELLAR_DATA time=%g mass=%g\\n", stardata->model.time, stardata->star[0].mass)'
# Entire script
custom_logging_code = binary_c_log_code(logging_line)
# Run system
output = run_system(M_1=2, custom_logging_code=custom_logging_code)
# print (abridged) output
print("\n".join(output.splitlines()[:4]))
```
%% Output
MY_STELLAR_DATA time=0 mass=2
MY_STELLAR_DATA time=0 mass=2
MY_STELLAR_DATA time=1e-06 mass=2
MY_STELLAR_DATA time=2e-06 mass=2
%% Cell type:markdown id:1998ee8f-8c0a-462b-b1e0-54f5963902cc tags:
### Using custom logging with the population object
Custom logging can be used for a whole population by setting the print statement (so not the entire logging script) in `C_logging_code`
%% Cell type:code id:77bd09b0-1a94-499d-97db-a1f991c67c12 tags:
``` python
# Set up population
pop = Population()
# Set some BSE parameters
pop.set(
M_1=5
)
# Example logging that prints only if the star is post main-sequence
example_logging_string_post_MS = """
if(stardata->star[0].stellar_type>MS)
{
Printf("EXAMPLE_POST_MS %30.12e %g %g %g %g %d %d\\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->star[0].radius, //4
stardata->previous_stardata->star[0].radius, //5
stardata->star[0].stellar_type, //6
stardata->previous_stardata->star[0].stellar_type //7
);
};
"""
# Set the logging
pop.set(
C_logging_code=example_logging_string_post_MS
)
out = pop.evolve_single()
# Print (abridged) output
print('\n'.join(out.splitlines()[:4]))
```
%% Output
EXAMPLE_POST_MS 1.044142002936e+02 4.99194 4.99194 6.13567 6.13567 2 1
EXAMPLE_POST_MS 1.044572277695e+02 4.99192 4.99194 7.51803 6.13567 2 2
EXAMPLE_POST_MS 1.044654032097e+02 4.99192 4.99192 7.81395 7.51803 2 2
EXAMPLE_POST_MS 1.045084306856e+02 4.99191 4.99192 9.57443 7.81395 2 2
%% Cell type:markdown id:93397ff3-9b71-470d-8bc4-08fe5b1a5dca tags:
### Using custom logging when running directly from the API
When running a system directly with the API we need to manually load the custom logging into memory (via `create_and_load_logging_function`) and pass the memory address to the binary_c binding via `_binary_c_bindings.run_system(argstring, custom_logging_func_memaddr=custom_logging_memaddr)`
%% Cell type:code id:30142286-34ce-433e-82c8-565e2160ff5b tags:
``` python
# generate logging lines
logging_line = autogen_C_logging_code(
{
"MY_STELLAR_DATA": ["model.time", "star[0].mass"],
}
)
# Generate code around logging lines
custom_logging_code = binary_c_log_code(logging_line)
# Generate library and get memaddr
custom_logging_memaddr, shared_lib_filename = create_and_load_logging_function(
custom_logging_code
)
#
m1 = 15.0 # Msun
m2 = 14.0 # Msun
separation = 0 # 0 = ignored, use period
orbital_period = 4530.0 # days
eccentricity = 0.0
metallicity = 0.02
max_evolution_time = 15000
argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g}".format(
m1,
m2,
separation,
orbital_period,
eccentricity,
metallicity,
max_evolution_time,
)
output = _binary_c_bindings.run_system(
argstring, custom_logging_func_memaddr=custom_logging_memaddr
)
# print (abridged) output
print('\n'.join(output.splitlines()[:4]))
```
%% Output
MY_STELLAR_DATA 0 15
MY_STELLAR_DATA 0 15
MY_STELLAR_DATA 1e-06 15
MY_STELLAR_DATA 2e-06 15
%% Cell type:markdown id:39c76b1d-d968-4eef-b5ae-2542ed9557c3 tags:
## Examples of logging strings
Below are some examples of logging strings
%% Cell type:markdown id:2ac4af72-6dab-4cc9-986e-5b5b1fa31b73 tags:
### Compact object
This logging will print the timestep when the star becomes a compact object. After it does, we change the maximum time to be the current time, effectively terminating the evolution
%% Cell type:code id:6f0edc65-a788-4706-a0c5-2ace030765ec tags:
``` python
example_logging_string_CO = """
if(stardata->star[0].stellar_type>=NS)
{
if (stardata->model.time < stardata->model.max_evolution_time)
{
Printf("EXAMPLE_LOG_CO %30.12e %g %g %g %g %d %d\\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->star[0].radius, //4
stardata->previous_stardata->star[0].radius, //5
stardata->star[0].stellar_type, //6
stardata->previous_stardata->star[0].stellar_type //7
);
};
/* Kill the simulation to save time */
stardata->model.max_evolution_time = stardata->model.time - stardata->model.dtm;
};
"""
# Entire script
custom_logging_code = binary_c_log_code(example_logging_string_CO)
# Run system
output = run_system(M_1=10, custom_logging_code=custom_logging_code)
# print (abridged) output
print("\n".join(output.splitlines()[:4]))
```
%% Output
SINGLE_STAR_LIFETIME 10 28.4838
EXAMPLE_LOG_CO 2.848380621869e+01 1.33469 9.1865 1.72498e-05 724.338 13 5
%% Cell type:markdown id:51c51592-6406-43bd-a879-10ace64aaf28 tags:
### Logging mass evolution and the supernova
This logging code prints the mass evolution and the moment the star goes supernova
%% Cell type:code id:8f58fdf9-3e76-4c18-a1c5-eed0980d4133 tags:
``` python
example_logging_string_CO = """
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d %g\\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type, //5
stardata->model.probability //6
);
if(stardata->star[0].SN_type != SN_NONE)
{
if (stardata->model.time < stardata->model.max_evolution_time)
{
Printf("EXAMPLE_SN %30.12e " // 1
"%g %g %g %d " // 2-5
"%d %d %g %g " // 6-9
"%g %g\\n", // 10-13
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4
stardata->star[0].SN_type, //5
stardata->star[0].stellar_type, //6
stardata->previous_stardata->star[0].stellar_type, //7
stardata->model.probability, //8
stardata->previous_stardata->star[0].core_mass[ID_core(stardata->previous_stardata->star[0].stellar_type)], // 9
stardata->previous_stardata->star[0].core_mass[CORE_CO], // 10
stardata->previous_stardata->star[0].core_mass[CORE_He] // 11
);
};
/* Kill the simulation to save time */
stardata->model.max_evolution_time = stardata->model.time - stardata->model.dtm;
};
"""
# Entire script
custom_logging_code = binary_c_log_code(example_logging_string_CO)
# Run system
output = run_system(M_1=20, custom_logging_code=custom_logging_code)
# print (abridged) output
print("\n".join(output.splitlines()[-2:]))
```
%% Output
EXAMPLE_MASSLOSS 1.050651207308e+01 1.59452 9.34213 20 13 1
EXAMPLE_SN 1.050651207308e+01 1.59452 9.34213 20 12 13 5 1 6.55458 4.71662 6.55458
%% Cell type:code id:c708268f-0b0c-48ea-9155-ec632a0acc3a tags:
``` python
```
......
%% Cell type:code id:d4799c94-afd8-41db-ab82-e0a6e278ed77 tags:
``` python
```
%% Cell type:markdown id:d5c04b77-f0be-4b33-8c03-c72eb846527c tags:
# Tutorial: Extra features and functionality of binary_c-python
In this notebook we'll go over some of the extra features and functionality that was not covered in the other notebooks.
Within the module `binarycpython.utils.functions` there are many functions that can be useful when using binarycpython. We can see which functions are in there, again by using the `help()`
%% Cell type:code id:de73a2c1-7acd-4b55-a4c4-ee6a7e0758d0 tags:
``` python
from binarycpython import Population
from binarycpython.utils.functions import (
get_help,
get_help_all,
get_help_super,
return_binary_c_version_info,
get_defaults
)
# help(binarycpython.utils.functions)
```
%% Cell type:markdown id:88b93969-b6aa-41b7-8f4d-2eee38d7a756 tags:
## getting extra information about binary_c parameters
There are several functions that can be used to get information about the parameters in binary_c:
- `get_help(parameter)`: Function to get information about the specific input parameter. Prints the output on default but returns a dictionary containing the information.
- `get_help_all(print_help=True)`: Function to get information about all the parameters. Prints the output on default but returns a dictionary containing the information.
- `get_help_super()`: Function to get even more information about all the parameters. Does not print the output on default but returns a dictionary containing the information.
- `get_defaults()`: Function that will get all the default values for the parameters. Returns a dictionary
%% Cell type:code id:7cfe1832-7fec-4817-b633-5b275c65667f tags:
``` python
get_help('M_1')
```
%% Output
parameter_name:
M_1
parameter_value_input_type:
Float
description:
The initial mass of star one (in solar units, internally this is star index 0).
default:
0
{'parameter_name': 'M_1',
'parameter_value_input_type': 'Float',
'description': 'The initial mass of star one (in solar units, internally this is star index 0).',
'default': '0'}
%% Cell type:code id:af62a066-ef70-4b59-877e-2b5a6bafcfc2 tags:
``` python
# get_help_all()
```
%% Cell type:code id:b85f1956-ee69-444a-a212-cd7473007bf1 tags:
``` python
# get_help_super()
```
%% Cell type:code id:e22b7a47-2748-406e-bba4-e92825ea9b47 tags:
``` python
# get_defaults()
```
%% Cell type:markdown id:c89ef423-82b9-49ed-8cf9-94c9ce41a82a tags:
## Build information of binary_c
Sometimes we want to know with which settings binary_c has been built. We can use the function `return_binary_c_version_info` for this.
This function will parse the version info of binary_c and return a dictionary with all the settings.
It can be useful to fetch the information with which the current version of binary_c has been configured with. We can do that through the Population object, by calling the instance method `return_binary_c_version_info`. This function will parse the version info of binary_c and return a dictionary with all the settings.
%% Cell type:code id:4dae05bd-6a66-4b1f-be4a-d092627dfe37 tags:
``` python
version_info_dict = return_binary_c_version_info(parsed=True)
print(version_info_dict.keys())
version_info = Population().return_binary_c_version_info(parsed=True)
print(version_info.keys())
```
%% Output
dict_keys(['networks', 'isotopes', 'argpairs', 'ensembles', 'ensemble_filters', 'macros', 'elements', 'dt_limits', 'nucleosynthesis_sources', 'miscellaneous'])
dict_keys(['networks', 'isotopes', 'argpairs', 'ensembles', 'ensemble_filters', 'macros', 'elements', 'dt_limits', 'units', 'nucleosynthesis_sources', 'miscellaneous'])
%% Cell type:markdown id:708c7253-9d9d-4705-969b-23f29695517d tags:
## Example parse function
TODO: In the functions module there is an example parse function that can be used in conjunction with run_system.
%% Cell type:code id:8656614a-09da-486f-b299-61cc6092187c tags:
``` python
```
%% Cell type:markdown id:6fac26d0-a0d2-40c7-915d-0883247cd24d tags:
## Dictionary modification
- merge_dicts
- update_dicts
- multiply_values_dict
TODO:
%% Cell type:markdown id:b3c259ef-9f89-4b26-9ce3-45af625bc398 tags:
## Getting help
%% Cell type:code id:bf3c1e28-1662-47a7-abab-aa6fb0ef0882 tags:
``` python
```
......
%% Cell type:markdown id:a544d28c-c2e1-4c6a-b55b-8caec440743f tags:
# Tutorial: Running individual systems with binary_c-python
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, for example, inspect what evolutionary steps a specific system goes through, to plot the mass loss evolution of a single system, etc.
%% Cell type:markdown id:dd5d9ec7-5791-45f1-afbd-225947e2a583 tags:
## Single system with run_system_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).
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 Printf statement that binary_c can use to print information
- log_filename: path of the logfile that binary_c generates
- 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:
``` python
from binarycpython.utils.run_system_wrapper import run_system
# help(run_system) # Uncomment to see the docstring
```
%% Cell type:code id:b2abab48-433d-4936-8434-14804c52c9f6 tags:
``` python
output = run_system(M_1=1)
print(output)
```
%% Output
SINGLE_STAR_LIFETIME 1 12461.2
SINGLE_STAR_LIFETIME 1 12461.1
%% Cell type:markdown id:f127a5e4-dc01-4472-9130-8a943c92e8a7 tags:
Lets try adding a log filename now:
%% Cell type:code id:029fc3f2-f09a-49af-a32b-248505738f2e tags:
``` python
log_filename = os.path.join(TMP_DIR, 'test_logfile.txt')
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())
```
%% Output
TIME M1 M2 K1 K2 SEP PER ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=62172 RANDOM_COUNT=0
TIME M1 M2 K1 K2 SEP PER ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=22065 RANDOM_COUNT=0
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 -1.00 0.000 0.000 "OFF_MS"
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 -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.1301 0.783 0.000 5 15 -1 -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.9983 0.716 0.000 6 15 -1 -1 -1.00 0.000 0.000 "shrinkAGB"
12461.1627 0.645 0.000 11 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
15000.0000 0.645 0.000 11 15 -1 -1 -1.00 0.000 0.000 "MAX_TIME"
12460.8955 0.774 0.000 6 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
12460.8955 0.774 0.000 6 15 -1 -1 -1.00 0.000 0.000 "shrinkAGB"
12461.1490 0.678 0.000 11 15 -1 -1 -1.00 0.000 0.000 "TYPE_CHNGE"
15000.0000 0.678 0.000 11 15 -1 -1 -1.00 0.000 0.000 "MAX_TIME"
%% 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):
%% Cell type:code id:e6a23b55-ca42-440d-83ac-e76a24a83a67 tags:
``` python
from binarycpython.utils.custom_logging_functions import binary_c_log_code
# Create the print statement
custom_logging_print_statement = """
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %d\\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5
);
"""
# Generate entire shared lib code around logging lines
custom_logging_code = binary_c_log_code(custom_logging_print_statement)
output = run_system(M_1=1, custom_logging_code=custom_logging_code, api_log_filename_prefix=TMP_DIR)
print('\n'.join(output.splitlines()[:4]))
```
%% 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
%% 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.
%% Cell type:code id:3822721f-217a-495b-962e-d57137b9e290 tags:
``` python
def parse_function(output):
"""
Example function to parse the output of binary_c
"""
#
column_names = ['time', 'mass', 'initial_mass', 'stellar_type']
value_lines = [column_names]
# Loop over output
for line in output.splitlines():
# Select the lines starting with the header we chose
if line.startswith("EXAMPLE_MASSLOSS"):
# Split the output and fetch the data
split_line = line.split()
values = [float(el) for el in split_line[1:]]
value_lines.append(values)
return value_lines
# Catch output
output = run_system(M_1=1, custom_logging_code=custom_logging_code, parse_function=parse_function)
print(output[:3])
```
%% Output
[['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:
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:
``` python
import pandas as pd
# Load data into dataframe
example_df = pd.DataFrame(output)
# Fix column headers
example_df.columns = example_df.iloc[0]
example_df = example_df.drop(example_df.index[0])
print(example_df)
```
%% Output
0 time mass initial_mass stellar_type
1 0.0 1.0 1.0 1.0
2 0.0 1.0 1.0 1.0
3 0.000001 1.0 1.0 1.0
4 0.000002 1.0 1.0 1.0
5 0.000003 1.0 1.0 1.0
... ... ... ... ...
1345 12461.080763 0.71617 1.0 6.0
1346 12461.162734 0.644553 1.0 11.0
1347 13461.162734 0.644553 1.0 11.0
1348 14461.162734 0.644553 1.0 11.0
1349 15000.0 0.644553 1.0 11.0
1250 12461.061259 0.718593 1.0 6.0
1251 12461.149038 0.678026 1.0 11.0
1252 13461.149038 0.678026 1.0 11.0
1253 14461.149038 0.678026 1.0 11.0
1254 15000.0 0.678026 1.0 11.0
[1349 rows x 4 columns]
[1254 rows x 4 columns]
%% Cell type:markdown id:325c2ce6-f9a1-46b7-937f-84040e1252cf tags:
## 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.
%% Cell type:code id:4a98ffca-1b72-4bb8-8df1-3bf3187d882f tags:
``` python
from binarycpython.utils.grid import Population
# help(Population) # Uncomment to see the docstring
```
%% Cell type:markdown id:7e2c2ef0-3db2-46a6-8c85-9b6cf720eb6a tags:
First, let's try this without any custom logging or parsing functionality
%% Cell type:code id:bff1cc2e-6b32-4ba0-879f-879ffbabd223 tags:
``` python
# Create the population object
example_pop = Population()
# Set some parameters
example_pop.set(
verbosity=1,
api_log_filename_prefix=TMP_DIR
)
example_pop.set(
M_1=10
)
# get output and print
output = example_pop.evolve_single()
print(output)
```
%% Output
adding: api_log_filename_prefix=/tmp/binary_c_python-izzard/notebooks/notebook_individual_systems to BSE_options
adding: M_1=10 to BSE_options
Creating and loading custom logging functionality
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-izzard/notebooks/notebook_individual_systems
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-david/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single
SINGLE_STAR_LIFETIME 10 28.4838
%% Cell type:markdown id:ae01fa35-f8b1-4a40-bfb2-b9e872cae0e7 tags:
Now lets add some actual output with the custom logging
%% Cell type:code id:dd748bab-b57e-4129-8350-9ea11fa179d0 tags:
``` python
custom_logging_print_statement = """
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5
);
"""
example_pop.set(C_logging_code=custom_logging_print_statement)
# get output and print
output = example_pop.evolve_single()
print('\n'.join(output.splitlines()[:4]))
```
%% Output
adding: C_logging_code=
Printf("EXAMPLE_MASSLOSS %30.12e %g %g %g %d\n",
//
stardata->model.time, // 1
stardata->star[0].mass, //2
stardata->previous_stardata->star[0].mass, //3
stardata->common.zero_age.mass[0], //4
stardata->star[0].stellar_type //5
);
to grid_options
Creating and loading custom logging functionality
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-izzard/notebooks/notebook_individual_systems
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-david/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single
Removed /tmp/binary_c_python-izzard/custom_logging/libcustom_logging_dafa15d2b1e64e19972ac0e9eb5c9a55.so
Removed /tmp/binary_c_python-david/custom_logging/libcustom_logging_34a350b8f15c4d149deab88632948c99.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
%% Cell type:markdown id:588a7d9e-9d64-4b3b-8907-656b905286e8 tags:
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:
``` python
import os
import json
import numpy as np
def object_parse_function(self, output):
"""
Example parse function that can be added to the population object
"""
# We can access object instance information now.
# 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')
#
column_names = ['time', 'mass', 'initial_mass', 'stellar_type']
value_lines = [column_names]
# Loop over output
for line in output.splitlines():
# Select the lines starting with the header we chose
if line.startswith("EXAMPLE_MASSLOSS"):
# Split the output and fetch the data
split_line = line.split()
values = [float(el) for el in split_line[1:]]
value_lines.append(values)
# Turn into an array
values_array = np.array(value_lines[1:])
# make dict and fill
output_dict = {}
for i in range(len(column_names)):
output_dict[column_names[i]] = list(values_array[:,i])
# Write to file
with open(output_file, 'w') as f:
f.write(json.dumps(output_dict, indent=4))
# Return something anyway
return value_lines
```
%% Cell type:code id:57347512-fd4a-434b-b13c-5e6dbd3ac415 tags:
``` python
example_pop.set(
parse_function=object_parse_function,
output_dir=TMP_DIR,
api_log_filename_prefix=TMP_DIR
)
output = example_pop.evolve_single()
print(output[:4])
# Example of loading the data that was written
with open(os.path.join(example_pop.custom_options['output_dir'], 'example_output.json')) as f:
written_data = json.loads(f.read())
print(written_data.keys())
```
%% Output
adding: parse_function=<function object_parse_function at 0x149c2e81ec10> to grid_options
<<<< Warning: Key does not match previously known parameter: adding: output_dir=/tmp/binary_c_python-izzard/notebooks/notebook_individual_systems to custom_options >>>>
adding: api_log_filename_prefix=/tmp/binary_c_python-izzard/notebooks/notebook_individual_systems to BSE_options
adding: parse_function=<function object_parse_function at 0x7f35b603e9d0> to grid_options
<<<< Warning: Key does not match previously known parameter: adding: output_dir=/tmp/binary_c_python-david/notebooks/notebook_individual_systems to custom_options >>>>
Creating and loading custom logging functionality
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-izzard/notebooks/notebook_individual_systems
Running binary_c M_1 10 api_log_filename_prefix /tmp/binary_c_python-david/notebooks/notebook_individual_systems
Cleaning up the custom logging stuff. type: single
Removed /tmp/binary_c_python-izzard/custom_logging/libcustom_logging_0639ee205c7d4782b4a27378f5d890bd.so
Removed /tmp/binary_c_python-david/custom_logging/libcustom_logging_446fe4cddfa94946bcafd55591ef3730.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]]
dict_keys(['time', 'mass', 'initial_mass', 'stellar_type'])
%% Cell type:markdown id:ddc06da3-fc68-4c6f-8067-14ea862b964d tags:
## 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.
There are fewer 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`
%% Cell type:markdown id:56886792-d379-4eac-b0d4-54508edb39c7 tags:
First we must construct the argument string that we pass to binary_c
%% Cell type:code id:ec48125c-6bf5-48f4-9357-8261800b5d8b tags:
``` python
# For a binary system we need to pass in these arguments
M_1 = 15.0 # Msun
M_2 = 14.0 # Msun
separation = 0 # 0 = ignored, use period
orbital_period = 4530.0 # days
eccentricity = 0.0
metallicity = 0.02
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
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} api_log_filename_prefix {api_log_filename_prefix}
""".format(
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=TMP_DIR
).strip()
from binarycpython import _binary_c_bindings
output = _binary_c_bindings.run_system(argstring)
print(output)
```
%% Output
SINGLE_STAR_LIFETIME 15 14.9927
%% 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).
......
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