Profile Interpolation
We demonstrate the profile interpolator which delivers predictions on internal stellar structure at the end of MESA evolution.
To use the profile interpolator we first import the ProfileInterpolator
and CompileData
objects from the POSYDON library.
from posydon.interpolation.profile_interpolation import ProfileInterpolator, CompileData
Extracting Profile Data from .h5 Files for Training Interpolators
To extract profile data from existing grids, we pass arguments train_path
and test_path
pointing to .h5 files containing instances of the PSyGrid
class from which the training and testing grids can be loaded. These can be constructed by running one’s own simulations or by loading a precomputed simulation stored in the data directory of the POSYDON repository. The profile_names
argument denotes which profiles will be extracted from the grid and saved to filename
using the function save
. The Boolean argument hms_s2
should be set to True only to extract star 2 profiles from the HMS-HMS grid.
compiler = CompileData(train_path = '/path/to/training/grid.h5',
test_path = '/path/to/testing/grid.h5',
hms_s2 = False,
profile_names=['radius','logRho',
'x_mass_fraction_H','y_mass_fraction_He',
'z_mass_fraction_metals','omega','energy'])
compiler.save(filename = '/path/for/profiles/datafile.pkl')
Loading a Pretrained Interpolator
To load a pretrained interpolator we instantiate a ProfileInterpolator
object instance and then use the load
function which specifies the path to a .pkl file from which the pretrained interpolator can be loaded.
model = ProfileInterpolator()
model.load(filename = "/path/to/profile/interpolator.pkl")
Training the Interpolator
The interpolator is trained on profiles stored in a .pkl file (passed with argument filename
) generated with the CompileData
class. The function load_profiles
also randomly splits the training data into a training set and validation set based on the argument valid_split
, which specifies the percentage of the training data that should be used for validation. The profile interpolation is anchored to POSYDON’s IF interpolation, and so we pass the name of the interpolator file to the train
function using the IF_interpolator
argument. The four following arguments specify the numbers of epochs and level of patience for callback that will be used for training the neural networks in the density and composition models. The loss_history
argument provides an option to return the loss histories for the composition and density model training. Once again, the Boolean argument hms_s2
should be set to True to build an interpolator for star 2 profiles from the HMS-HMS grid.
model = ProfileInterpolator()
model.load_profiles(filename = "/path/to/profiles/datafile.pkl",
valid_split=0.2)
model.train(IF_interpolator = "/path/to/IFinterpolator.pkl",
density_epochs=3000,
density_patience=200,
comp_bounds_epochs=500,
comp_bounds_patience=50,
loss_history=False,
hms_s2=False)
Using the Interpolator
Once the interpolator has been trained or loaded from a .pkl file it can be used to predict profiles for sets of initial conditions passed through argument inputs
. These initial conditions must be in log space and in shape (N,3) for N binaries. The order of the coordinates is star 1 mass, star 2 mass, period. The prediction function returns four arrays containing the profiles’ coordinates along mass enclosed, log density, Hydrogen mass fraction, and Helium mass fraction. All profiles share the same coordinates.
mass_coords, density_profiles, h_profiles, he_profiles = model.predict(inputs)
Finally a trained interpolator can be easily saved by specifying a path to a .pkl file where the interpolator will be saved to.
model.save(filename = "path/for/profile/interpolator.pkl")
Evaluating on Testing Data
To evaluate the interpolator on the testing grid, we can pull the testing data out of the ProfileInterpolator
class as follows:
test_initial = model.test_initial
test_mass_coords = np.transpose(np.array(model.test_scalars["total_mass"])*np.linspace(0,1,200)[:,np.newaxis])
test_density_profiles = model.test_profiles[:,model.names.index("logRho")]
test_H_profiles = model.test_profiles[:,model.names.index("x_mass_fraction_H")]
test_He_profiles = model.test_profiles[:,model.names.index("y_mass_fraction_He")]