Red giant example#
Bayesian inference of stellar parameters using an emulator trained on MESA/GYRE models with global asteroseismic data of red giants from the NASA Kepler mission
#### inference of a population of observed red giant's stellar parameters
#### using an emulator neural network trained on a grid of MESA/GYRE models
import seistron
Observations#
## load the observed data
observations = seistron.data.red_giants.yu_2018() # Ji Yu 2018 data
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[2], line 2
1 ## load the observed data
----> 2 observations = seistron.data.red_giants.yu_2018() # Ji Yu 2018 data
AttributeError: module 'seistron.data.red_giants' has no attribute 'yu_2018'
seistron.visualize.hr_diagram(observations, cbar='[Fe/H]') # plot an HRD
seistron.visualize.kiel_diagram(observations)
seistron.visualize.jcd_diagram(observations, cbar='Teff')
Theoretical models#
## load the theoretical models
model_grid = seistron.models.red_giants.li_rg() # Yaguang Li's red giants
seistron.visualize.hr_diagram(models=model_grid, cbar='M')
seistron.visualize.hr_diagram(observations, models=model_grid)
Emulator#
## train or load the emulator
pretrained_model_filename = 'transformer_rg.tron' # save or load here
# emulator = seistron.emulate.transformer.train(
# model_grid,
# inputs=model_grid.inputs,
# outputs=model_grid.outputs) # need a GPU or computing cluster
# emulator.save_pretrained(emulator, save_filename=pretrained_model_filename)
emulator = seistron.emulator.load_pretrained(pretrained_model_filename)
seistron.visualize.show_crossval_score(emulator) # visualize emulator accuracy
seistron.visualize.compare_emulators([
emulator,
seistron.emulator.linear(models=model_grid),
seistron.emulator.random_forest(models=model_grid, cv=True)
])
# for each output column, plot 1-to-1 line between the predicted and actual, and the residuals as a function of the actual
seistron.visualize.show_residuals(emulator,
only=['Delta_nu', 'nu_max', 'Teff'])
emulator.summarize() # print std of residuals, which is representative of systematic interpolation errors that should be propagated
Inference#
## apply the emulator to do inference on real data
## first, do it for just one star to obtain posteriors for its mass, age, etc
priors = {'M': seistron.sample.priors.kroupa_IMF,
'age': seistron.sample.priors.flat([0, 13.8])}
example_star = observations.iloc[0]
MAP_one = seistron.sample.maximum_a_posteriori(example_star, priors=priors,
method='nelder-mead') # need a sensible starting point
samples = seistron.sample.do_one( # better to run this on a cluster like below
data=example_star,
emulator=emulator,
method='HMC',
num_samples=1e7,
priors=priors,
starting_values=MAP_one)
seistron.visualize.corner(samples) # show a nice corner plot
seistron.sample.summarize(samples) # print means, standard deviations, and χ2
Mock data test#
## do a test using mock data based on one of the models
# user-specifiable noise levels for observables
noise = {'Delta_nu': 0.1, # in muHz
'nu_max': 2.0, # in muHz
'Teff': 50.0, # in K
'logg': 0.05}
# apply noise to the first model in the data set and try to recover its params
mock_test = emulator.generate_mock_data(model_grid.iloc[0], noise)
MAP_test = seistron.sample.maximum_a_posteriori(mock_test,
priors=priors, method='nelder-mead')
samples_test = seistron.sample.do_one(mock_first, emulator=emulator,
num_samples=1e4, priors=priors, starting_values=MAP_test)
seistron.visualize.summarize(samples_test)
# see how well the inferences scale with increased noise on the observables
noise_factors = {'Delta_nu': [0.1, 0.3, 1, 3, 10]}
noise_test = seistron.sample.noise_test(mock_first,
emulator=emulator, num_samples=1e4, priors=priors,
starting_values=MAP_test, noise=noise, noise_factors=noise_factors)
seistron.visualize.noise_test(noise_test)
# perhaps we want some wrapper that automates the MAP/sampling/visualizing/summarizing/etc so that we can do it all in one go
Hierarchical Bayes#
## hierarchical Bayes for one correlated (shared) parameter while characterizing all the observations of all the stars simultaneously
MAP_all = seistron.sample.maximum_a_posteriori(observations, priors=priors,
method='nelder-mead')
samples = seistron.sample.hierarchical( # with access to a cluster
data=observations,
emulator=emulator,
method='HMC',
num_samples=1e10,
priors=priors,
correlate={'Y': ['Z', 'age'], # galactic chemical enrichment
'alpha_MLT': ['Teff', 'logg', 'Z'], # convection
'alpha_ov': ['M', 'age', 'Z']},
correlation_type={'Y': 'linear',
'alpha_MLT': 'linear',
'alpha_ov': 'gaussian_process'},
starting_values=MAP_all,
nproc=128, # number of processes for parallelism
cluster='grace')
seistron.visualize.corner(samples,
only=['Teff', 'logg', 'Z', 'alpha_MLT'])
## visualize draws from the posterior for one star in the data set
seistron.visualize.posterior_samples(example_star, samples)
seistron.visualize.hr_diagram(example_star,
models=model_grid, samples=samples)
Hierarchical Bayes mock data test#
## mock data test: make mock data out of each of the models in the data set and test our ability to recover correlated parameters
# still need to brainstorm a good way to implement this
cov_params = lambda inputs: inputs['Y'] = 1.4 * inputs['Z'] + 0.2473
mock_correlated = generate_correlated_mock_data(n_stars=50,
cov_params=cov_params, noise_dict=noise)
#samples = seistron.sample.hierarchical...