PSyGrid object
The PSyGrid
object contains the data coming from detailed MESA
simulations.
Import the PSyGrid
module with:
from posydon.grids.psygrid import PSyGrid
Initializing a PSyGrid object
You can instantiate a new PSyGrid
object with
mygrid = PSyGrid()
This calls the initializer, which can take two optional arguments
filepath
: this is the path to the associatedh5
file; if the file exists, the initializer will load the contained PSyGrid objectverbose
: this is a boolean indicating whether detailed output should be, given when calling functions of thePSyGrid
object
Creating a PSyGrid object
The create
function of a PSyGrid
object will read MESA output
data into the PSyGrid
object. It has a required argument,
MESA_grid_path
, which is the path to the directory containing the MESA
runs. There are several optional arguments as well:
Argument |
Default |
Description |
---|---|---|
psygrid_path |
None |
the path to the associated |
overwrite |
False |
if |
slim |
False |
if |
warn |
“end” |
if if if |
fmt |
“posydon” |
grid format; only |
**grid_kwargs |
further grid configuration properties can be specified in a dictionary |
The PSyGrid
object has the following grid configuration properties:
Property |
Default |
Description |
---|---|---|
‘description’ |
“” |
description text |
‘max_number_of_runs’ |
None |
the maximum number of runs |
‘format’ |
“hdf5” |
file format; only |
‘compression’ |
“gzip9” |
the compression (of the hdf5 file) |
‘history_DS_error’ |
None |
the maximum error allowed when downsampling the history |
‘history_DS_exclude’ |
default list |
the history columns to exclude from downsampling (default list = [“model_number”, “age”, “star_age”]) |
‘profile_DS_error’ |
None |
the maximum error allowed when downsampling the final profile |
‘profile_DS_interval’ |
None |
the maximum change in an downsampled interval relative to the change from initial to final |
‘profile_DS_exclude’ |
default list |
the profile columns to exclude from downsampling (default list = [“mass”, “star_mass”]) |
‘star1_history_saved_columns’ |
“minimum” |
specifies which history columns of star 1 should be read if if if a tuple of column names, read only those columns if a list of column names, read the default and those columns |
‘star2_history_saved_columns’ |
“minimum” |
specifies which history columns of star 2 should be read (same options as star1_history_saved_columns) |
‘binary_history_saved_columns’ |
“minimum” |
specifies which binary history columns should be read (same options as star1_history_saved_columns) |
‘star1_profile_saved_columns’ |
“minimum” |
specifies which profile columns of star 1 should be read (same options as star1_history_saved_columns) |
‘star2_profile_saved_columns’ |
“minimum” |
specifies which profile columns of star 2 should be read (same options as star1_history_saved_columns) |
‘initial_value_columns’ |
None |
history columns from which to store initial values (currently not in use, instead all specified history columns are used as well as the abundances X, Y, and Z) |
‘final_value_columns’ |
None |
history columns from which to store final values (currently not in use, instead all specified history columns are used as well as termination flags and for binaries the interpolation class) |
‘start_at_RLO’ |
False |
specifies whether to crop the history to start at RLO |
‘stop_before_carbon_depletion’ |
False |
specifies whether to crop the history of massive stars (>100 Msun) to stop at 10% central carbon and after helium is depleted |
‘binary’ |
True |
specifies whether a grid evolved binaries; put |
‘eep’ |
None |
path to directory with EEP files (for single stars only) |
‘initial_RLO_fix’ |
False |
specifies whether the boundary of initial RLO should be determined to flag all systems below as initial RLO independent of the MESA output |
‘He_core_fix’ |
True |
specifies to ensure that the helium core is always larger or equal to the carbon-oxygen core |
‘accept_missing_profile’ |
False |
specifies whether try to include all data from MESA runs without final profiles |
You can read the MESA data into an existing PSyGrid
object, which may
overwrite data:
mygrid.create(MESA_grid_path=".")
Alternatively, you can combine the initialization with creation of the grid based on MESA data:
mygrid = PSyGrid().create(MESA_grid_path=".")
Loading a PSyGrid object
You can load an existing h5
file (e.g. “myPSyGrid.h5”) into a
PSyGrid
object:
mygrid.load(filepath="myPSyGrid.h5")
It may be more convenient to load the file directly when initializing the
PSyGrid
object
mygrid = PSyGrid(filepath="myPSyGrid.h5")
Contents of a PSyGrid object
Print a PSyGrid object
You can check the contents of the PSyGrid
object with a print command:
print(mygrid)
This will provide a summary, which tell you:
to which hdf5 file it is connected
how many runs are in the grid and how many have
a binary history
a history of star 1
a history of star 2
a final profile of star 1
a final profile of star 2
which histories/profile fields are included in the last run
which initial and final values are stored in the grid
information about the grid configuration
a shorthand list of the MESA directories (the locations of the data the runs where extracted from)
To access single runs, it is important to know how many are there to avoid calling a nonexisting run. You can find the number of runs with:
len(mygrid)
Note
Alternatively, you can request the length internally with
mygrid.n_runs
.
Accessing data in a PSyGrid object
The first data you may want to check are the
grid configuration properties. You can get a list
of the properties available for your PSyGrid
object with
mygrid.config.keys()
You can access the value of any grid configuration property “PROPERTY” with
mygrid.config[PROPERTY]
.
Next, you can look at the initial and final values of the runs. All the values
are available at mygrid.initial_values
and mygrid.final_values
,
respectively. To get a tuple of all the available values use
mygrid.initial_values.dtype.names
mygrid.final_values.dtype.names
You can access the initial value of any physical grid property “PHYS” with
mygrid.initial_values[PHYS]
. It will return a numpy array with the
values of this property for all the runs.
Note that these physical properties of the binaries in the grid are different
from the grid configuration properties listed above.
Then, you can find the initial mass of star 1 in the third MESA run with
mygrid.initial_values['star_1_mass'][2]
Note
Remember that the first run has the index 0
and the last one
len(mygrid)-1
.
Each grid property will have the same number and order of MESA run entries in the initial and final values. This holds for the list of MESA directories from which the runs are extracted, too.
mygrid.MESA_dirs
You can retrieve individual runs by index. mygrid[IDX]
is a
PSyRunView
object, which contains the data of the run of index
IDX
. The PSyRunView
object contains seven components:
Component |
Description |
---|---|
‘initial_values’ |
all initial values of the run |
‘final_values’ |
all final values of the run including termination flags |
‘binary_history’ |
the binary history |
‘history1’ |
the history of star 1 |
‘history2’ |
the history of star 2 |
‘final_profile1’ |
the final profile of star 1 |
‘final_profile2’ |
the final profile of star 2 |
Again, you can check for the contents of the individual runs with
dtype.names
, e.g.
myrun = mygrid[0]
myrun['binary_history'].dtype.names
The example above finds the initial mass of star 1 in the third MESA run by
indexing the list mygrid.initial_values
.
You can get the same value from the list of initial values associated with a
single MESA run:
mygrid[2]['initial_values']['star_1_mass']
You can get something close to the initial value with:
mygrid[2]['binary_history']['star_1_mass'][0]
But this will not give the initial value, while it is close to it. This is because MESA has a slightly different value in the first line of the history files compared to the given initial value. The final values and the derived initial values instead are the same as the last or first values in the corresponding history.
Note
For efficiency reasons not all the PSyGrid
object is loaded into
RAM. Instead parts are reads from the associated hdf5 file if needed.
For this reason, it is discouraged to refer to the same values
more than once in a code. If you need the same value more often, you should
store it in a local variable.
Plot a PSyGrid object
Beside getting the values itself there are plotting functionalities available
to display the content of a PSyGrid
object. There are three main
plotting functionalities:
plot
: This creates a one dimensional plot from thePSyGrid
. An example can be found in the tutorials. The code details are available in thePSyGrid.plot
code and thevisualization
library.plot2D
: This creates a two dimensional representation from thePSyGrid
. Again, an example can be found in the tutorials. The code details are available in thePSyGrid.plot
code and thevisualization
library.HR
: This is similar toplot
but specialized for producing Hertzsprung–Russell diagrams.
Work on/with a PSyGrid object
Loop over a PSyGrid object
Similarly to accessing a single value in the PSyGrid
object, we can
loop over a PSyGrid
object, which will loop over the individual runs
in the PSyGrid
object. Hence the following two code snippets will
produce the same output. The first one loops through the numpy array of the
initial companion masses:
for mass in mygrid.initial_values['star_2_mass']:
print(mass)
while the second one loops through the runs and prints the initial companion mass of each one:
for run in mygrid:
print(run['initial_values']['star_2_mass'])
Expand a PSyGrid object
Because of the complexity of the PSyGrid
object, we encourage users
to only use our dedicated functions to add content to the object. There is a
function to add an extra column to the final_values
. Here is an example
of how to add a new column that contains the final orbital period, in units of
years instead of days:
new_column_data = mygrid.final_values['period_days']/365.25
mygrid.add_column('period_years', new_column_data, where='final_values', overwrite=False)
The four arguments are a string with the name of the new field, the data to be
stored in the column, the component of the PSyGrid
object to which the
column will be added, and a boolean indicating whether the column should
overwrite any existing column with the same name.
Warning
The new data has to have as many entries as the PSyGrid
object has
runs.
Note
Currently, the parameter where
only supports the value
‘final_values’.
Join two or more PSyGrid objects
There are different reasons why you might have several PSyGrid
objects
that you would like to combine into a single grid later, e.g. adding reruns.
POSYDON has a function called join_grids
to do this for you.
To avoid too many conflicts with possible modifications of already loaded
PSyGrid
objects, this function is not part of the PSyGrid
object class. Instead, it takes as an argument the list of
paths to the hdf5 files containing PSyGrid
objects to be combined to a
new one, and then a path to the hdf5 file of the new grid to be generated.
The join_grids
function will check whether the grids are compatible
and join them if possible. Additionally, you can optionally specify the
arguments compression
, description
, and verbose
.
Argument |
Default |
Description |
---|---|---|
input_paths |
None |
list of the paths to the grid files to be joined |
output_path |
None |
path for the new grid file containing the joined grid. |
compression |
‘gzip9’ |
compression details |
description |
‘joined’ |
description of the new joined grid |
verbose |
True |
whether the function reports by printing to standard output. |
Note
If there are common systems in two or more grids, this routine will only
put the last run with same initial conditions in the newly combined
PSyGrid
object.
We recommend that you use the post-processing pipeline to create and join grids.
Get reruns from a PSyGrid object
Usually, not all runs of a grid will be successfully run in MESA. You
may want to rerun some of them with changed parameters. The function
rerun
exports runs from a PSyGrid
object to be run again.
There are two options:
1. Write your own logic and create a numpy array with the indices of the systems that you would like to run again. 2. Specify which termination flag(s) necessitate a rerun of the system.
Argument |
Default |
Description |
---|---|---|
path_to_file |
‘./’ |
where to create the file(s) for the rerun |
runs_to_rerun |
None |
a list containing the indices of the runs in the |
termination_flags |
None |
a single termination flag code, or a list of them |
new_mesa_flag |
None |
dictionary with the names and the values of MESA parameters to be changed for the inlists of the new runs |
flags_to_check |
None |
a termination flag key or a list of them (if |
Note
If both runs_to_rerun
and termination_flags
are given, all
systems matching at least one of the two conditions will be selected for
rerun.
The post-processing pipeline provides some pre-defined rerun options.
Close associated hdf5 file
Finally, you can close the hdf5 file, which is recommended to ensure that all
your changes on the PSyGrid
object are safely written into the file.
mygrid.close()
This is also done if you call the destructor of the
PSyGrid
object.
del mygrid
The code summary of the PSyGrid
object can be found at the
psygrid
reference page.