Tutorial 2: Generating Age Probability Distributions for Stars with Gaia Data

In the previous tutorial, we’ve calibrated the age–action spline model using a calibration sample of red giant branch stars with independent, asteroseismic ages.

Now, let’s use that spline model to generate age probabilities for other stars.

[1]:
import numpy as np
import matplotlib.pyplot as plt
import zoomies

%load_ext autoreload
%autoreload 2

Query Gaia

You will need to download the Gaia DR3 data for any stars you’re interested in. You can perform a mass query at https://gea.esac.esa.int/archive/ and read in the resulting table, or you can use astroquery to download the data right from your notebook, as we’ll do here:

[5]:
# Install astroquery if you haven't already!
from astroquery.gaia import Gaia
Gaia.MAIN_GAIA_TABLE = "gaiadr3.gaia_source"
[6]:
# Do your Gaia query or input a table of Gaia data

import astropy.units as u
from astropy.coordinates import SkyCoord

coord = SkyCoord(ra=280, dec=60, unit=(u.degree, u.degree), frame='icrs')
width = u.Quantity(0.5, u.deg)
height = u.Quantity(0.5, u.deg)

r = Gaia.query_object_async(coordinate=coord, width=width, height=height)
INFO: Query finished. [astroquery.utils.tap.core]
[7]:
# Filtering out stars without radial velocity
r = r[~r['radial_velocity'].mask]

Here’s the Gaia data for the couple of stars we’re interested in, as an astropy table:

[8]:
r
[8]:
Table length=2
distsolution_iddesignationsource_idrandom_indexref_epochrara_errordecdec_errorparallaxparallax_errorparallax_over_errorpmpmrapmra_errorpmdecpmdec_errorra_dec_corrra_parallax_corrra_pmra_corrra_pmdec_corrdec_parallax_corrdec_pmra_corrdec_pmdec_corrparallax_pmra_corrparallax_pmdec_corrpmra_pmdec_corrastrometric_n_obs_alastrometric_n_obs_acastrometric_n_good_obs_alastrometric_n_bad_obs_alastrometric_gof_alastrometric_chi2_alastrometric_excess_noiseastrometric_excess_noise_sigastrometric_params_solvedastrometric_primary_flagnu_eff_used_in_astrometrypseudocolourpseudocolour_errorra_pseudocolour_corrdec_pseudocolour_corrparallax_pseudocolour_corrpmra_pseudocolour_corrpmdec_pseudocolour_corrastrometric_matched_transitsvisibility_periods_usedastrometric_sigma5d_maxmatched_transitsnew_matched_transitsmatched_transits_removedipd_gof_harmonic_amplitudeipd_gof_harmonic_phaseipd_frac_multi_peakipd_frac_odd_winruwescan_direction_strength_k1scan_direction_strength_k2scan_direction_strength_k3scan_direction_strength_k4scan_direction_mean_k1scan_direction_mean_k2scan_direction_mean_k3scan_direction_mean_k4duplicated_sourcephot_g_n_obsphot_g_mean_fluxphot_g_mean_flux_errorphot_g_mean_flux_over_errorphot_g_mean_magphot_bp_n_obsphot_bp_mean_fluxphot_bp_mean_flux_errorphot_bp_mean_flux_over_errorphot_bp_mean_magphot_rp_n_obsphot_rp_mean_fluxphot_rp_mean_flux_errorphot_rp_mean_flux_over_errorphot_rp_mean_magphot_bp_rp_excess_factorphot_bp_n_contaminated_transitsphot_bp_n_blended_transitsphot_rp_n_contaminated_transitsphot_rp_n_blended_transitsphot_proc_modebp_rpbp_gg_rpradial_velocityradial_velocity_errorrv_method_usedrv_nb_transitsrv_nb_deblended_transitsrv_visibility_periods_usedrv_expected_sig_to_noiserv_renormalised_gofrv_chisq_pvaluerv_time_durationrv_amplitude_robustrv_template_teffrv_template_loggrv_template_fe_hrv_atm_param_originvbroadvbroad_errorvbroad_nb_transitsgrvs_maggrvs_mag_errorgrvs_mag_nb_transitsrvs_spec_sig_to_noisephot_variable_flaglbecl_lonecl_latin_qso_candidatesin_galaxy_candidatesnon_single_starhas_xp_continuoushas_xp_sampledhas_rvshas_epoch_photometryhas_epoch_rvhas_mcmc_gspphothas_mcmc_mscin_andromeda_surveyclassprob_dsc_combmod_quasarclassprob_dsc_combmod_galaxyclassprob_dsc_combmod_starteff_gspphotteff_gspphot_lowerteff_gspphot_upperlogg_gspphotlogg_gspphot_lowerlogg_gspphot_uppermh_gspphotmh_gspphot_lowermh_gspphot_upperdistance_gspphotdistance_gspphot_lowerdistance_gspphot_upperazero_gspphotazero_gspphot_lowerazero_gspphot_upperag_gspphotag_gspphot_lowerag_gspphot_upperebpminrp_gspphotebpminrp_gspphot_lowerebpminrp_gspphot_upperlibname_gspphot
yrdegmasdegmasmasmasmas / yrmas / yrmas / yrmas / yrmas / yrmas1 / um1 / um1 / ummasdegdegdegdegdegelectron / selectron / smagelectron / selectron / smagelectron / selectron / smagmagmagmagkm / skm / sdkm / sKlog(cm.s**-2)dexkm / skm / smagmagdegdegdegdegKKKlog(cm.s**-2)log(cm.s**-2)log(cm.s**-2)dexdexdexpcpcpcmagmagmagmagmagmagmagmagmag
float64int64objectint64int64float64float64float32float64float32float64float32float32float32float64float32float64float32float32float32float32float32float32float32float32float32float32float32int16int16int16int16float32float32float32float32int16boolfloat32float32float32float32float32float32float32float32int16int16float32int16int16int16float32float32int16int16float32float32float32float32float32float32float32float32float32boolint16float64float32float32float32int16float64float32float32float32int16float64float32float32float32float32int16int16int16int16int16float32float32float32float32float32int16int16int16int16float32float32float32float32float32float32float32float32int16float32float32int16float32float32int16float32objectfloat64float64float64float64boolboolint16boolboolboolboolboolboolboolboolfloat32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32object
0.032942025746286971636148068921376768Gaia DR3 215490161057384486421549016105738448642410234602016.0280.06569008069570.01639790660.002572292737290.018328581.43959736110078480.01770353781.316944.034647-3.7813763922463550.020791428-1.40697141521361370.021559382-0.13987689-0.17148478-0.162723420.065358840.287555780.00486031-0.20837094-0.15121393-0.09816643-0.008488968313931211.5664704355.762760.0711188241.683124331False1.517273--------------36260.03028327391600.001720665414.2530775001.0627708----------------False33226596.066251972676.2738054239.22414.6253233413216.77279195335914.825079891.5144715.0357283218934.1246063513523.005768823.016414.0547831.2088591000100.98094560.410405160.5705404-58.99813.52119642201165.3412848----848.42834--5250.04.00.0111------13.7030530.1182352321--NOT_AVAILABLE89.6127865623945924.619597593406176309.1973108757241682.05259222492064FalseFalse0TrueTrueFalseFalseFalseTrueTrueFalse1.0310119e-135.149859e-130.99989325379.09035362.1525393.74854.57334.56484.58060.04850.03050.0648652.7858646.5188660.39860.13920.12650.150.11370.10330.12260.06030.05480.065MARCS
0.0343783043817205561636148068921376768Gaia DR3 2154901988530967552215490198853096755214048103412016.0280.01940415423160.01553135560.032988717449370.017716120.53690071918498550.01755810230.5785184.8870983-4.87687872053102640.019893862-0.315882927669080440.021310652-0.10731452-0.23620193-0.114977560.059396050.29391325-0.023874374-0.18965203-0.24747391-0.0370514360.10042425280027730.33902383288.023040.039116110.5526467631False1.5930966--------------32250.030482063361500.0004068181732.448666101.01333950.206638220.09302230.081541830.031603187-136.634484.5168.5428258.555851False30030990.8141551481759.85831453143.62214.4592853217775.65635581424420.999525846.4789414.7139783319015.99151036049419.759075962.392814.0500981.1871791000000.66387940.254693030.4091863629.45335210.5614752143133.9535046----788.70197--6000.02.5-0.75111------14.0517520.1364768912--NOT_AVAILABLE89.640190921636124.648574475550223309.1632547915814482.09051468241744FalseFalse0TrueTrueFalseFalseFalseTrueTrueFalse1.0282279e-135.135947e-130.99992086483.5866460.97366514.44734.09764.07614.1173-0.4975-0.517-0.4791753.88711703.021810.71330.18910.17820.20410.16440.15480.17760.0890.08380.0961MARCS

Calculate Jz

You now need to calculate ln(Jz) (log of vertical action) for each Gaia star. The star must have a radial velocity. (Make sure you check the number of stars that have radial velocities from Gaia for the sample you’re interested in.)

TODO: You must input a table with at least two rows. It doesn’t work if you just input one row of Gaia data.

[9]:
# This function returns a table with three new
# columns for the action angles at the end: Jz, Jphi, and Jtheta

# This line may take a while for very large tables.

r_actions = zoomies.calc_jz(r)
r_actions
/opt/anaconda3/envs/zoomies_test_3/lib/python3.14/site-packages/gala/potential/potential/builtin/special.py:257: GalaFutureWarning: The MilkyWayPotential2022 class will be deprecated soon. Instead, use: MilkyWayPotential(version="v2") to get what is currently the MilkyWayPotential2022 class. Or, to always use the latest Milky Way model in Gala, you can call the class with no arguments MilkyWayPotential() or specify MilkyWayPotential(version="latest")
  warnings.warn(
Calculating actions with galpy...
[9]:
Table length=2
distsolution_iddesignationsource_idrandom_indexref_epochrara_errordecdec_errorparallaxparallax_errorparallax_over_errorpmpmrapmra_errorpmdecpmdec_errorra_dec_corrra_parallax_corrra_pmra_corrra_pmdec_corrdec_parallax_corrdec_pmra_corrdec_pmdec_corrparallax_pmra_corrparallax_pmdec_corrpmra_pmdec_corrastrometric_n_obs_alastrometric_n_obs_acastrometric_n_good_obs_alastrometric_n_bad_obs_alastrometric_gof_alastrometric_chi2_alastrometric_excess_noiseastrometric_excess_noise_sigastrometric_params_solvedastrometric_primary_flagnu_eff_used_in_astrometrypseudocolourpseudocolour_errorra_pseudocolour_corrdec_pseudocolour_corrparallax_pseudocolour_corrpmra_pseudocolour_corrpmdec_pseudocolour_corrastrometric_matched_transitsvisibility_periods_usedastrometric_sigma5d_maxmatched_transitsnew_matched_transitsmatched_transits_removedipd_gof_harmonic_amplitudeipd_gof_harmonic_phaseipd_frac_multi_peakipd_frac_odd_winruwescan_direction_strength_k1scan_direction_strength_k2scan_direction_strength_k3scan_direction_strength_k4scan_direction_mean_k1scan_direction_mean_k2scan_direction_mean_k3scan_direction_mean_k4duplicated_sourcephot_g_n_obsphot_g_mean_fluxphot_g_mean_flux_errorphot_g_mean_flux_over_errorphot_g_mean_magphot_bp_n_obsphot_bp_mean_fluxphot_bp_mean_flux_errorphot_bp_mean_flux_over_errorphot_bp_mean_magphot_rp_n_obsphot_rp_mean_fluxphot_rp_mean_flux_errorphot_rp_mean_flux_over_errorphot_rp_mean_magphot_bp_rp_excess_factorphot_bp_n_contaminated_transitsphot_bp_n_blended_transitsphot_rp_n_contaminated_transitsphot_rp_n_blended_transitsphot_proc_modebp_rpbp_gg_rpradial_velocityradial_velocity_errorrv_method_usedrv_nb_transitsrv_nb_deblended_transitsrv_visibility_periods_usedrv_expected_sig_to_noiserv_renormalised_gofrv_chisq_pvaluerv_time_durationrv_amplitude_robustrv_template_teffrv_template_loggrv_template_fe_hrv_atm_param_originvbroadvbroad_errorvbroad_nb_transitsgrvs_maggrvs_mag_errorgrvs_mag_nb_transitsrvs_spec_sig_to_noisephot_variable_flaglbecl_lonecl_latin_qso_candidatesin_galaxy_candidatesnon_single_starhas_xp_continuoushas_xp_sampledhas_rvshas_epoch_photometryhas_epoch_rvhas_mcmc_gspphothas_mcmc_mscin_andromeda_surveyclassprob_dsc_combmod_quasarclassprob_dsc_combmod_galaxyclassprob_dsc_combmod_starteff_gspphotteff_gspphot_lowerteff_gspphot_upperlogg_gspphotlogg_gspphot_lowerlogg_gspphot_uppermh_gspphotmh_gspphot_lowermh_gspphot_upperdistance_gspphotdistance_gspphot_lowerdistance_gspphot_upperazero_gspphotazero_gspphot_lowerazero_gspphot_upperag_gspphotag_gspphot_lowerag_gspphot_upperebpminrp_gspphotebpminrp_gspphot_lowerebpminrp_gspphot_upperlibname_gspphotJzJphiJr
yrdegmasdegmasmasmasmas / yrmas / yrmas / yrmas / yrmas / yrmas1 / um1 / um1 / ummasdegdegdegdegdegelectron / selectron / smagelectron / selectron / smagelectron / selectron / smagmagmagmagkm / skm / sdkm / sKlog(cm.s**-2)dexkm / skm / smagmagdegdegdegdegKKKlog(cm.s**-2)log(cm.s**-2)log(cm.s**-2)dexdexdexpcpcpcmagmagmagmagmagmagmagmagmagkm kpc / skm kpc / skm kpc / s
float64int64objectint64int64float64float64float32float64float32float64float32float32float32float64float32float64float32float32float32float32float32float32float32float32float32float32float32int16int16int16int16float32float32float32float32int16boolfloat32float32float32float32float32float32float32float32int16int16float32int16int16int16float32float32int16int16float32float32float32float32float32float32float32float32float32boolint16float64float32float32float32int16float64float32float32float32int16float64float32float32float32float32int16int16int16int16int16float32float32float32float32float32int16int16int16int16float32float32float32float32float32float32float32float32int16float32float32int16float32float32int16float32objectfloat64float64float64float64boolboolint16boolboolboolboolboolboolboolboolfloat32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32float32objectfloat64float64float64
0.032942025746286971636148068921376768Gaia DR3 215490161057384486421549016105738448642410234602016.0280.06569008069570.01639790660.002572292737290.018328581.43959736110078480.01770353781.316944.034647-3.7813763922463550.020791428-1.40697141521361370.021559382-0.13987689-0.17148478-0.162723420.065358840.287555780.00486031-0.20837094-0.15121393-0.09816643-0.008488968313931211.5664704355.762760.0711188241.683124331False1.517273--------------36260.03028327391600.001720665414.2530775001.0627708----------------False33226596.066251972676.2738054239.22414.6253233413216.77279195335914.825079891.5144715.0357283218934.1246063513523.005768823.016414.0547831.2088591000100.98094560.410405160.5705404-58.99813.52119642201165.3412848----848.42834--5250.04.00.0111------13.7030530.1182352321--NOT_AVAILABLE89.6127865623945924.619597593406176309.1973108757241682.05259222492064FalseFalse0TrueTrueFalseFalseFalseTrueTrueFalse1.0310119e-135.149859e-130.99989325379.09035362.1525393.74854.57334.56484.58060.04850.03050.0648652.7858646.5188660.39860.13920.12650.150.11370.10330.12260.06030.05480.065MARCS3.530247057416689-1627.311560153028524.777721413012102
0.0343783043817205561636148068921376768Gaia DR3 2154901988530967552215490198853096755214048103412016.0280.01940415423160.01553135560.032988717449370.017716120.53690071918498550.01755810230.5785184.8870983-4.87687872053102640.019893862-0.315882927669080440.021310652-0.10731452-0.23620193-0.114977560.059396050.29391325-0.023874374-0.18965203-0.24747391-0.0370514360.10042425280027730.33902383288.023040.039116110.5526467631False1.5930966--------------32250.030482063361500.0004068181732.448666101.01333950.206638220.09302230.081541830.031603187-136.634484.5168.5428258.555851False30030990.8141551481759.85831453143.62214.4592853217775.65635581424420.999525846.4789414.7139783319015.99151036049419.759075962.392814.0500981.1871791000000.66387940.254693030.4091863629.45335210.5614752143133.9535046----788.70197--6000.02.5-0.75111------14.0517520.1364768912--NOT_AVAILABLE89.640190921636124.648574475550223309.1632547915814482.09051468241744FalseFalse0TrueTrueFalseFalseFalseTrueTrueFalse1.0282279e-135.135947e-130.99992086483.5866460.97366514.44734.09764.07614.1173-0.4975-0.517-0.4791753.88711703.021810.71330.18910.17820.20410.16440.15480.17760.0890.08380.0961MARCS49.70225373350188-2209.785015351312783.49405970242807

Age-Jz Relation Calibrated on RGB ages

We previously calibrated an age–vertical action spline model in Tutorial 1, and saved it in the "RGB_spline_model" directory. Let’s read that model back in here.

Alternatively, you can download the folder from Zenodo: 10.5281/zenodo.10048927

[10]:
spline_direct = "../RGB_spline_model/"

# Reading the pre-calibrated spline model back in
RGB_spline = zoomies.read(directory=spline_direct)

The KinematicAgeSpline.evaluate_ages() function evaluates dynamical ages for the ln(Jz) values in our table.

[11]:
# this function evaluates age predictions for a set of ln(Jz) values.

eval_grid, starRGB_eval_pdf = RGB_spline.evaluate_ages(np.log(r_actions['Jz']), eval_grid=np.linspace(0, 14, 1000))
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 1515.01it/s]

This is the age probabiltiy distribution for the first star in our Gaia table:

[12]:
plt.plot(eval_grid, starRGB_eval_pdf[0])

plt.xlabel('Age gyr')
plt.ylabel('PDF')
plt.title('lnJz = ' + str((np.log(r_actions['Jz'][0]))))
[12]:
Text(0.5, 1.0, 'lnJz = 1.2613678564329032')
../_images/tutorials_get_age_predictions_19_1.png

And here it is for the second star:

[13]:
# this is the age prediction for the second star in the table

plt.plot(eval_grid, starRGB_eval_pdf[1])

plt.xlabel('Age gyr')
plt.ylabel('PDF')

plt.title('lnJz = ' + str((np.log(r_actions['Jz'][1]))))
[13]:
Text(0.5, 1.0, 'lnJz = 3.906050278824991')
../_images/tutorials_get_age_predictions_21_1.png
[ ]: