def infer_stellar_age(df): print("Hogwarts") # CALCULATE SOME USEFUL VARIABLES teff_err = .5 * (df["p20_cks_steff_err1"] - df["p20_cks_steff_err2"]) feh_err = .5 * (df["p20_cks_smet_err1"] - df["p20_cks_smet_err2"]) prot_err = .5 * (df["prot_err1"] - df["prot_err2"]) av_err = .5 * (df["l20_Av_errp"] + df["l20_Av_errm"]) av = df["l20_Av"] bprp = df["gaia_phot_bp_mean_mag"] - df["gaia_phot_rp_mean_mag"] print("Hagrid") # Now make sure you don't initialize at Av = 0. init_av = av * 1 init_av_err = av * 1 if av == 0: init_av = .1 if av_err == 0: init_av_err = .1 print("got here") # CALCULATE INITS mass, age, feh = (df["f18_Miso"], df["f18_logAiso"], df["p20_cks_smet"]) # "accurate=True" makes more accurate, but slower tracks = get_ichrone('mist', tracks=True) track = tracks.generate(mass, age, feh, return_dict=True) print("stop")
def __init__(self,photometric_args, astrometric_args=None, mcluster_args=None, kalkayotl_file=None, seed=1234): #------ Set Seed ----------------------------------- np.random.seed(seed=seed) self.random_state = np.random.RandomState(seed=seed) self.seed = seed #--------------------------------------------------- #--------------- Tracks ---------------------------- self.tracks = get_ichrone('mist', tracks=True, bands=photometric_args["bands"]) #--------------------------------------------------- #---------- Arguments --------------------------------------------------------------- self.photometric_args = photometric_args if astrometric_args is not None: self.astrometric_args = astrometric_args case = "astrometric" elif mcluster_args is not None: self.mcluster_args = mcluster_args case = "McLuster" elif kalkayotl_file is not None: assert os.path.exists(kalkayotl_file), "Input Kalkayotl file does not exists!" self.astrometric_args = self._read_kalkayotl(kalkayotl_file) case = "Kalkayotl" else: sys.exit("You must provide astrometric_args, mcluster_args or a Kalkayotl file!") print("Astrometry will be generated from the provided {0} arguments!".format(case)) #----------------------------------------------------------------------------------- #------- Labels ---------------------------------------------------------------------------------- self.labels_phase_space = ["X","Y","Z","U","V","W"] self.labels_true_as = ["ra_true","dec_true","parallax_true", "pmra_true","pmdec_true","radial_velocity_true"] self.labels_true_ph = [band+"_mag" for band in photometric_args["bands"]] self.labels_obs_as = ["ra","dec","parallax","pmra","pmdec","dr2_radial_velocity"] self.labels_unc_as = ["ra_error","dec_error","parallax_error", "pmra_error","pmdec_error","dr2_radial_velocity_error"] self.labels_cor_as = ["ra_dec_corr","ra_parallax_corr","ra_pmra_corr","ra_pmdec_corr", "dec_parallax_corr","dec_pmra_corr","dec_pmdec_corr", "parallax_pmra_corr","parallax_pmdec_corr", "pmra_pmdec_corr"] self.labels_obs_ph = ["g","bp","rp"] self.labels_unc_ph = ["g_error","bp_error","rp_error"] self.labels_rvl = ["dr2_radial_velocity","dr2_radial_velocity_error"]
def infer_stellar_age(df): iso_params = { "G": (df["G"], df["G_err"]), "BP": (df["bp"], df["bp_err"]), "RP": (df["rp"], df["rp_err"]), "g": (df["g_final"], df["g_final_err"]), "r": (df["r_final"], df["r_final_err"]), "J": (df["Jmag"], df["e_Jmag"]), "H": (df["Hmag"], df["e_Hmag"]), "K": (df["Kmag"], df["e_Kmag"]), "teff": (df["teff_vansaders"], df["teff_err"]), "feh": (df["feh_vansaders"], df["feh_err"]), "nu_max": (df["numax"], df["e_numax"]), "delta_nu": (df["Dnu"], df["e_Dnu"]), "parallax": (df["parallax"], df["parallax_error"]) } mist = get_ichrone('mist') age_init = np.log10(df["AMP_age"] * 1e9) eep = mist.get_eep(df["AMP_mass"], age_init, df["feh_vansaders"], accurate=True) mod = SingleStarModel(mist, **iso_params) # StarModel isochrones obj params = [354, np.log10(4.56 * 1e9), 0., 1000, 0.] args = [mod, iso_params] nwalkers, ndim, nsteps = 50, 5, 10000 inits = [ eep, age_init, df["feh_vansaders"], 1. / df["parallax"] * 1e3, df["Av"] ] p0 = [np.random.randn(ndim) * 1e-4 + inits for j in range(nwalkers)] sampler = emcee.EnsembleSampler(nwalkers, ndim, iso_lnprob, args=args) sampler.run_mcmc(p0, nsteps) samples = np.reshape(sampler.chain, (nwalkers * nsteps, ndim)) sample_df = pd.DataFrame({ "eep_samples": samples[:, 0], "age_samples": samples[:, 1], "feh_samples": samples[:, 2], "distance_samples": samples[:, 3], "Av_samples": samples[:, 4] }) sample_df.to_hdf("{}_iso_test.h5".format(int(df["kepid"])), key="samps", mode='w')
def get_inits(bp, rp, period, mass, feh, parallax_mas): # Get gyro age log10_age_yrs = gk_age_model(np.log10(period), bp-rp) gyro_age = (10**log10_age_yrs)*1e-9 # Get initial EEP: mist = get_ichrone('mist') try: eep = mist.get_eep(mass, log10_age_yrs, feh, accurate=True) except: eep = 355 distance_pc = 1./(parallax_mas*1e-3) inits = [eep, log10_age_yrs, feh, np.log(distance_pc), .1] return inits
def setUp(self): mist = get_ichrone("mist") sfh = StarFormationHistory() # Constant SFR for 10 Gyr; or, e.g., dist=norm(3, 0.2) imf = SalpeterPrior(bounds=(0.4, 10)) # bounds on solar masses binaries = BinaryDistribution(fB=0.4, gamma=0.3) feh = GaussianPrior(-0.2, 0.2) distance = DistancePrior(max_distance=3000) # pc AV = AVPrior(bounds=[0, 2]) pop = StarPopulation( mist, sfh=sfh, imf=imf, feh=feh, distance=distance, binary_distribution=binaries, AV=AV ) self.pop = pop self.mist = mist self.df = pop.generate(1000) self.dereddened_df = deredden(mist, self.df)
def simulate_isochrone_gc(nstar: int, feh: float, age: float, dist: float): """ Use the 'isochrones' module to simulate a globular cluster along with its isochrone (some stars in the prior will be gone after evaluation). : nstar : total number of star for the sample prior : feh : metalicity [Fe/H] : age : age of the globular cluster [log10(yr)] : dist : distance of the globular cluster [pc] : return : a data frame of the stars info in the globular gluster """ tracks = get_ichrone('mist', tracks=True, bands=['V', 'G', 'BP', 'RP']) masses = ChabrierPrior().sample(nstar) df = tracks.generate(masses, age, feh, distance=dist) df = df.dropna() df['V_abs_mag'] = calc_M_abs(df['V_mag'], dist) df['Lv_abs'] = calc_Lv(df['V_abs_mag']) df['G_abs_mag'] = calc_M_abs(df['G_mag'], dist) return df
def work(self, row): track = get_ichrone('mist', tracks=True, bands=self.bands) track.initialize() mod_spec = mod_from_row(track, row, name_col=self.name_col, tag='spec', props=['Teff', 'logg', 'feh', 'parallax']) mod_phot = mod_from_row(track, row, name_col=self.name_col, tag='phot', props=self.bands + ['parallax']) name = str(row[self.name_col]) print('fitting spec model for {}'.format(name)) mod_spec.fit(**self.fit_kwargs) mod_spec.write_results() print('spec model for {} complete; results written.'.format(name)) print('fitting phot model for {}'.format(name)) mod_phot.fit(**self.fit_kwargs) mod_phot.write_results() print('phot model for {} complete; results written.'.format(name)) cols = self.columns + ['{}_mag'.format(b) for b in self.bands] results_spec = mod_spec.derived_samples[cols].quantile(self.quantiles) results_phot = mod_phot.derived_samples[cols].quantile(self.quantiles) spec = '{} '.format(row[self.name_col]) phot = '{} '.format(row[self.name_col]) for c in cols: for q in self.quantiles: spec += '{:.3f} '.format(results_spec.loc[q, c]) phot += '{:.3f} '.format(results_phot.loc[q, c]) spec += '{:.3f}'.format(mod_spec.posterior_predictive) phot += '{:.3f}'.format(mod_phot.posterior_predictive) return spec, phot
#!/usr/bin/python3 import os import sys import numpy as np import pandas as pd import h5py import tqdm import emcee import stardate as sd from stardate.lhf import age_model from isochrones import get_ichrone mist = get_ichrone('mist') from multiprocessing import Pool # Necessary to add cwd to path when script run # by SLURM (since it executes a copy) sys.path.append(os.getcwd()) def infer_stellar_age(df): # Set up the parameter dictionary. iso_params = { "G": (df["phot_g_mean_mag"], df["G_err"]), "BP": (df["phot_bp_mean_mag"], df["bp_err"]), "RP": (df["phot_rp_mean_mag"], df["rp_err"]), "teff": (df["cks_steff"], df["cks_steff_err1"]),
def test_get_ichrone_gaia(models=['mist'], bands=['Gaia_G_MAW', 'Gaia_BP_MAWf', 'Gaia_RP_MAW', 'Gaia_BP_MAWb']): for m in models: get_ichrone(m, bands=bands)
import sys import os import numpy as np import pandas as pd from isochrones import get_ichrone, SingleStarModel from isochrones.priors import GaussianPrior, AgePrior import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches import seaborn as sns from Globals import * #-------------- Get the isochrones ---------------------------- mist = get_ichrone('mist', bands=bands) #------- This prints the available photometry ------------------ # mass, age, feh = (1.03, 9.72, -0.11) # print(mist.generate(mass, age, feh, return_dict=True)) # sys.exit() #--------------------------------------------------------------- #------------ Files ------------------------------------------------- file_chunk = dir_data + "data_{0}_of_{1}.csv".format(XXX, size) file_samp = dir_outs + "samples_{0}_of_{1}.h5".format(XXX, size) file_stat = dir_outs + "statistics_{0}_of_{1}.csv".format(XXX, size) #------------------------------------------------------------------- #------------- Load data -------------------------------- df = pd.read_csv(file_chunk, usecols=columns_data)
def test_spec(bands='JHK'): mist = get_ichrone('mist', bands=bands) _check_spec(mist)
def test_get_ichrone(models=['mist'], bands='JHK'): for m in models: get_ichrone(m, bands=bands)
from isochrones.starmodel import StarModel, BasicStarModel from isochrones import get_ichrone import numpy as np mist = get_ichrone("mist") props = dict(Teff=(5800, 100), logg=(4.5, 0.1), J=(3.58, 0.05), K=(3.22, 0.05), parallax=(100, 0.1)) props_phot = dict(J=(3.58, 0.05), K=(3.22, 0.05), parallax=(100, 0.1)) props_spec = dict(Teff=(5800, 100), logg=(4.5, 0.1), parallax=(100, 0.1)) def test_compare_starmodels(props=props): m1 = StarModel(mist, **props) m2 = BasicStarModel(mist, **props) # Ensure priors are identical for k in ["mass", "feh", "age", "distance", "AV", "eep"]: m2.set_prior(**{k: m1._priors[k]}) pars = [300, 9.8, 0.01, 100, 0.1] assert np.isclose(m1.lnlike(pars), m2.lnlike(pars)) assert np.isclose(m1.lnprior(pars), m2.lnprior(pars)) assert np.isclose(m1.lnpost(pars), m2.lnpost(pars)) m1_bin = StarModel(mist, **props, N=2) m2_bin = BasicStarModel(mist, **props, N=2)
def test_closest_eep(n=10000): mist = get_ichrone('mist') _check_closest_eep(mist, n=n)
def make_data(self, stream_distance=2., ang_0=pi / 2., z_sun=0.015, sun_vel=np.array([-11.1, 245.8, 7.2]), number_of_stars=None, stellar_start=0, plot=False): if number_of_stars == None: number_of_stars = self.df_stream.shape[0] stellar_thinning = 1 else: stellar_thinning = max( int(self.df_stream.shape[0] / number_of_stars), 1) if os.path.exists('../GeneratedStreams/mock_isochrone_Gmags.npy'): isochrones_appGs = np.load( '../GeneratedStreams/mock_isochrone_Gmags.npy') else: from isochrones import get_ichrone from isochrones.priors import ChabrierPrior tracks = get_ichrone('mist', tracks=True) N = 10000 masses = ChabrierPrior().sample(N) feh = -2. # Fe/H age = np.log10(12e9) # 12 Gyr distance = 10. # 10 pc df = tracks.generate(masses, age, feh, distance=distance) df = df.dropna() df = df[df['G_mag'] < 20. - 8.] isochrones_appGs = df['G_mag'].values np.save('../GeneratedStreams/mock_isochrone_Gmags', isochrones_appGs) self.ang_0 = ang_0 self.z_sun = z_sun sun_pos = [ np.median(self.df_stream['x']) - np.cos(ang_0) * stream_distance, np.median(self.df_stream['y']) - np.sin(ang_0) * stream_distance, self.z_sun ] self.sun_vel = sun_vel self.stream_distance = stream_distance obs_list = [] for index in self.df_stream.index[stellar_start:stellar_start + stellar_thinning * number_of_stars:stellar_thinning]: rel_pos = np.array([ self.df_stream['x'][index] - sun_pos[0], self.df_stream['y'][index] - sun_pos[1], self.df_stream['z'][index] - sun_pos[2] ]) dist = np.linalg.norm(rel_pos) appG = 30. G_diff = 5. * (np.log10(1e3 * dist) - 1.) while appG > 20.: appG = np.random.choice(isochrones_appGs) + G_diff par_err = 10.**log10_par_err_of_G(appG) mu_err = 10.**log10_mu_err_of_G(appG) vlos_err = 0.3 par = 1. / dist + par_err * np.random.normal() if rel_pos[1] > 0.: l = np.arccos(rel_pos[0] / np.sqrt(rel_pos[0]**2. + rel_pos[1]**2.)) else: l = 2. * pi - np.arccos( rel_pos[0] / np.sqrt(rel_pos[0]**2. + rel_pos[1]**2.)) b = np.arcsin(rel_pos[2] / dist) rel_vel = [ self.df_stream['vx'][index] - sun_vel[0], self.df_stream['vy'][index] - sun_vel[1], self.df_stream['vz'][index] - sun_vel[2] ] mul = (-np.sin(l) * rel_vel[0] + np.cos(l) * rel_vel[1]) / ( 4.74057 * dist) + mu_err * np.random.normal() mub = (-np.sin(b) * np.cos(l) * rel_vel[0] - np.sin(b) * np.sin(l) * rel_vel[1] + np.cos(b) * rel_vel[2] ) / (4.74057 * dist) + mu_err * np.random.normal() vlos = (+np.cos(b) * np.cos(l) * rel_vel[0] + np.cos(b) * np.sin(l) * rel_vel[1] + np.sin(b) * rel_vel[2]) + vlos_err * np.random.normal() obs_list.append( [par, l, b, mul, mub, vlos, par_err, mu_err, vlos_err, appG]) obs_list = np.array(obs_list) self.df_data = pd.DataFrame(obs_list, columns=[ 'par', 'l', 'b', 'mul', 'mub', 'vlos', 'par_err', 'mu_err', 'vlos_err', 'appG' ]) print("Size of obs. list:", np.shape(obs_list)) if plot: self.plot_data() return
def test_get_ichrone_gaia( models=["mist"], bands=["Gaia_G_MAW", "Gaia_BP_MAWf", "Gaia_RP_MAW", "Gaia_BP_MAWb"]): for m in models: get_ichrone(m, bands=bands)
def test_get_ichrone(models=["mist"], bands="JHK"): for m in models: get_ichrone(m, bands=bands)
def test_tracks(bands="JHK"): mist = get_ichrone("mist", bands=bands, tracks=True) _basic_ic_checks_tracks(mist) _check_spec_tracks(mist)
def test_spec(bands="JHK"): mist = get_ichrone("mist", bands=bands) _check_spec(mist)
from pygaia.astrometry.vectorastrometry import cartesianToSpherical from pygaia.errors.astrometric import parallaxErrorSkyAvg from isochrones import get_ichrone from isochrones.priors import ChabrierPrior dir_main = "/home/javier/Repositories/Kalkayotl/article/Synthetic/" random_seeds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Random state for the synthetic data n_stars = 1000 # 100,500, 1000 metallicity = 0.02 # Solar metallicity age = 8.2 # Typical value of Bossini+2019 mass_limit = 4.0 # Avoids NaNs in photometry labels = ["ID", "r", "ra", "dec", "parallax", "parallax_error", "G"] tracks = get_ichrone('mist', tracks=True, bands="VIG") extension_yrs = 0.0 ####### FAMILY PARAMETERS #################################################### family = "Gaussian" scale = 10.0 #---- Only for GMM ------- scale2 = 20.0 # Second component fraction = 0.5 # Of first component shift = 0.1 # Relative distance shift of second comp. #----- Only for EFF ----- gamma = 3 # Only for King --------- tidal_radius = 5 # In units of core radius (i.e. scale) #-----------------------------------------------------------
def run_fit(kicid): matches = xmatch[xmatch["kepid"] == kicid] if not len(matches): print("skipping {0}".format(kicid)) return ind = np.argmin(matches["kepler_gaia_ang_dist"]) r = matches[ind] # Parallax offset reference: https://arxiv.org/abs/1805.03526 plx = r["parallax"] + 0.082 plx_err = np.sqrt(r["parallax_error"]**2 + 0.033**2) if not (np.isfinite(plx) and np.isfinite(plx_err)): print("non finite parallax: {0}".format(kicid)) return factor = 2.5 / np.log(10) params = {} for band in ["G", "BP", "RP"]: mag = float(r["phot_{0}_mean_mag".format(band.lower())]) err = float(r["phot_{0}_mean_flux_error".format(band.lower())]) err /= float(r["phot_{0}_mean_flux".format(band.lower())]) err *= factor if not (np.isfinite(mag) and np.isfinite(err)): print("non finite params: {0}".format(kicid)) return params[band] = (mag, err) jitter_vars = list(sorted(params.keys())) params["parallax"] = (float(plx), float(plx_err)) for k, v in params.items(): params[k] = np.array(v, dtype=np.float64) if params["parallax"][0] > 0: params["max_distance"] = np.clip(2000 / plx, 100, np.inf) print(params) output_dir = "results" os.makedirs(output_dir, exist_ok=True) fn = os.path.join(output_dir, "{0}.h5".format(kicid)) if os.path.exists(fn): return # Set up an isochrones model using the MIST tracks mist = isochrones.get_ichrone("mist", bands=["G", "BP", "RP"]) mod = isochrones.SingleStarModel(mist, **params) # These functions wrap isochrones so that they can be used with dynesty: def prior_transform(u): cube = np.copy(u) mod.mnest_prior(cube[:mod.n_params], None, None) cube[mod.n_params:] = -10 + 20 * cube[mod.n_params:] return cube def loglike(theta): ind0 = mod.n_params lp0 = 0.0 for i, k in enumerate(jitter_vars): err = np.sqrt(params[k][1]**2 + np.exp(theta[ind0 + i])) lp0 -= 2 * np.log(err) # This is to fix a bug in isochrones mod.kwargs[k] = (params[k][0], err) lp = lp0 + mod.lnpost(theta[:mod.n_params]) if np.isfinite(lp): return np.clip(lp, -1e10, np.inf) return -1e10 # Run nested sampling on this model sampler = dynesty.NestedSampler(loglike, prior_transform, mod.n_params + len(jitter_vars)) strt = time.time() sampler.run_nested() print("Sampling took {0} minutes".format((time.time() - strt) / 60.0)) # Resample the chain to get unit weight samples and update the isochrones # model results = sampler.results samples = dynesty.utils.resample_equal( results.samples, np.exp(results.logwt - results.logz[-1])) df = mod._samples = pd.DataFrame( dict( zip( list(mod.param_names) + ["log_jitter_" + k for k in jitter_vars], samples.T, ))) mod._derived_samples = mod.ic(*[df[c].values for c in mod.param_names]) mod._derived_samples["parallax"] = 1000.0 / df["distance"] mod._derived_samples["distance"] = df["distance"] mod._derived_samples["AV"] = df["AV"] # Save these results to disk mod._samples.to_hdf(fn, "samples") mod._derived_samples.to_hdf(fn, "derived_samples")
def test_get_ichrone(models=['dartmouth','dartmouthfast','mist']): for m in models: get_ichrone(m)
def estimate(bands, params, logg=True, out_folder='.'): """Estimate logg using MIST isochrones.""" mist = get_ichrone('mist', bands=bands) model = SingleStarModel(mist, **params) if 'distance' in params.keys(): dist, dist_e = params['distance'] elif 'parallax' in params.keys(): dist = 1 / (params['parallax'][0] * 0.001) dist_e = dist * params['parallax'][1] / params['parallax'][0] else: msg = 'No parallax or distance found.' msg += 'Aborting age and mass calculation.' InputError(msg).warn() return np.zeros(10), np.zeros(10) if 'feh' in params.keys(): fe, fe_e = params['feh'] if fe + fe_e >= 0.5: model._priors['feh'] = FlatPrior([-0.5, 0.5]) else: model._priors['feh'] = GaussianPrior(fe, fe_e) if 'mass' in params.keys(): m, m_e = params['mass'] model._priors['mass'] = GaussianPrior(m, m_e) if 'AV' in params.keys(): av, av_e = params['AV'] model._priors['AV'] = GaussianPrior(av, av_e) model._priors['distance'] = GaussianPrior(dist, dist_e) sampler = dynesty.NestedSampler( loglike, prior_transform, model.n_params + len(bands), nlive=500, bound='multi', sample='rwalk', logl_args=([model, params, bands]), ptform_args=([model]) ) try: sampler.run_nested(dlogz=0.01) except ValueError as e: dump_out = f'{out_folder}/isochrone_DUMP.pkl' pickle.dump(sampler.results, open(dump_out, 'wb')) DynestyError(dump_out, 'isochrone', e).__raise__() results = sampler.results samples = resample_equal( results.samples, np.exp(results.logwt - results.logz[-1]) ) ########################################################################### # Written by Dan Foreman-mackey # https://github.com/dfm/gaia-isochrones df = model._samples = pd.DataFrame( dict( zip( list(model.param_names), samples.T, ) ) ) model._derived_samples = model.ic( *[df[c].values for c in model.param_names]) model._derived_samples["parallax"] = 1000.0 / df["distance"] model._derived_samples["distance"] = df["distance"] model._derived_samples["AV"] = df["AV"] ########################################################################### if logg: samples = model._derived_samples['logg'] med, lo, up = credibility_interval(samples, 5) med_e = max([med - lo, up - med]) return med, med_e else: age_samples = 10 ** (model._derived_samples['age'] - 9) mass_samples = model._derived_samples['mass'] eep_samples = model._derived_samples['eep'] return age_samples, mass_samples, eep_samples
import numpy as np from numpy.lib.recfunctions import append_fields from fdnu import asfgrid from isochrones import get_ichrone import ebf ''' I changed lines 34, 86, 138, 149 in mist/models.py to force vcrit=0. ''' # method 1 tracks = get_ichrone('mist', tracks=True) mass, age, feh = (1.03, 9.27, -0.11) a = tracks.generate(mass, age, feh, return_dict=True, accurate=True) # # method 2 iso = get_ichrone('mist') # read in Galaxia stars rootpath = '' synp = ebf.read(rootpath + "sample/kepler_galaxia_mrtd5.ebf") masses, ages, fehs = synp["smass"], synp["log_age"], synp["feh"] Nstar = masses.shape[0] keys = [ 'nu_max', 'radius', 'logg', 'Teff', 'delta_nu', 'phase', 'Mbol', 'feh', 'logTeff', 'initial_mass', 'density', 'mass', 'logL', 'age' ] #list(a.keys()) res = np.zeros(Nstar, dtype=np.dtype([(keys[i], np.float64) for i in range(len(keys))]))
from isochrones import get_ichrone mist = get_ichrone("mist", bands="JHK") mist.initialize() del mist tracks = get_ichrone("mist", bands="JHK", tracks=True) tracks.initialize()
import time from isochrones import get_ichrone mist = get_ichrone('mist', bands=['J']) mist.radius(1, 9.5, 0.1) N = 10000 start = time.time() for i in range(N): mist.radius(1, 9.6, 0.01) end = time.time() print('Time per isochrones execution: {}s'.format((end - start) / N))
import os import numpy as np import pandas as pd import h5py import tqdm from .lhf import lnprob, lnlike, nll# , ptform from isochrones import StarModel, SingleStarModel, get_ichrone import emcee import scipy.optimize as spo # from dynesty import NestedSampler from isochrones.priors import FlatPrior from isochrones.mist import MIST_Isochrone bands = ["B", "V", "J", "H", "K", "BP", "RP", "G"] # mist = MIST_Isochrone(bands) mist = get_ichrone("mist", bands=bands) from isochrones.priors import GaussianPrior class Star(object): """The star object. Creates the star object which will be set up with stellar parameters and instructions for saving the MCMC results. Args: iso_params (dict): A dictionary containing all available photometric and spectroscopic parameters for a star, as well as its parallax. All parameters should also have associated uncertainties. This dictionary should be similar to the standard one created for isochrones.py.
parser.add_argument('--AV', type=float, default=0.02, help='V-band extinction') parser.add_argument('--alpha', type=float, default=-3, help='IMF index') parser.add_argument('--gamma', type=float, default=0.3, help='mass ratio index') parser.add_argument('--fB', type=float, default=0.5, help='binary fraction') parser.add_argument('--models', type=str, default='mist') parser.add_argument('--mineep', type=int, default=202) parser.add_argument('--maxeep', type=int, default=605) parser.add_argument('--maxAV', type=float, default=0.1) parser.add_argument('--overwrite', '-o', action='store_true') parser.add_argument('--nlive', type=int, default=1000) args = parser.parse_args() if rank == 0: ic = get_ichrone(args.models) pars = [args.age, args.feh, args.distance, args.AV, args.alpha, args.gamma, args.fB] print(pars) cat = simulate_cluster(args.N, *pars) print(cat.df.describe()) cat.df.to_hdf('{}_stars.h5'.format(args.name), 'df') model = StarClusterModel(ic, cat, eep_bounds=(args.mineep, args.maxeep), max_distance=args.distance*3, max_AV=args.maxAV, name=args.name) model.set_prior(feh=FehPrior(halo_fraction=0.5), age=FlatLogPrior((6, 9.5))) print('lnprior, lnlike, lnpost: {}'.format([model.lnprior(pars), model.lnlike(pars),
def fit_gaia_data(name, gaia_data, clobber=False): # We will fit for jitter parameters for each magnitude jitter_vars = ["G", "BP", "RP"] # Set up an isochrones model using the MIST tracks mist = isochrones.get_ichrone("mist", bands=["G", "BP", "RP"]) mod = isochrones.SingleStarModel(mist, **gaia_data) # Return the existing samples if not clobbering output_dir = os.path.join(OUTPUT_DIR, __version__, name) os.makedirs(output_dir, exist_ok=True) fn = os.path.join(output_dir, "star.h5") if (not clobber) and os.path.exists(fn): mod._samples = pd.read_hdf(fn, "samples") mod._derived_samples = pd.read_hdf(fn, "derived_samples") return mod with open(os.path.join(output_dir, "gaia.json"), "w") as f: json.dump( dict((k, v.tolist()) for k, v in gaia_data.items()), f, indent=2, sort_keys=True, ) # These functions wrap isochrones so that they can be used with dynesty: def prior_transform(u): cube = np.copy(u) mod.mnest_prior(cube[: mod.n_params], None, None) cube[mod.n_params :] = -10 + 20 * cube[mod.n_params :] return cube def loglike(theta): ind0 = mod.n_params lp0 = 0.0 for i, k in enumerate(jitter_vars): err = np.sqrt(gaia_data[k][1] ** 2 + np.exp(theta[ind0 + i])) lp0 -= 2 * np.log(err) # This is to fix a bug in isochrones mod.kwargs[k] = (gaia_data[k][0], err) lp = lp0 + mod.lnpost(theta[: mod.n_params]) if np.isfinite(lp): return np.clip(lp, -1e10, np.inf) return -1e10 # Run nested sampling on this model sampler = dynesty.NestedSampler( loglike, prior_transform, mod.n_params + len(jitter_vars) ) strt = time.time() sampler.run_nested() total_time = (time.time() - strt) / 60.0 print("Sampling took {0} minutes".format(total_time)) # Resample the chain to get unit weight samples and update the isochrones # model results = sampler.results samples = dynesty.utils.resample_equal( results.samples, np.exp(results.logwt - results.logz[-1]) ) df = mod._samples = pd.DataFrame( dict( zip( list(mod.param_names) + ["log_jitter_" + k for k in jitter_vars], samples.T, ) ) ) mod._derived_samples = mod.ic(*[df[c].values for c in mod.param_names]) mod._derived_samples["parallax"] = 1000.0 / df["distance"] mod._derived_samples["distance"] = df["distance"] mod._derived_samples["AV"] = df["AV"] # Save these results to disk mod._samples.to_hdf(fn, "samples") mod._derived_samples.to_hdf(fn, "derived_samples") # Save the summary to disk mod._derived_samples.describe().transpose().to_csv( os.path.join(output_dir, "star_summary.csv") ) # Summarize the sampling performance summary = dict( nlive=int(results.nlive), niter=int(results.niter), ncall=int(sum(results.ncall)), eff=float(results.eff), logz=float(results.logz[-1]), logzerr=float(results.logzerr[-1]), total_time=float(total_time), ) with open( os.path.join(output_dir, "star_sampling_summary.json"), "w" ) as f: json.dump(summary, f, indent=True, sort_keys=True) return mod, sampler
def _get_mist(): global _MIST if _MIST is None: _MIST = isochrones.get_ichrone("mist", bands=["G", "BP", "RP"]) return _MIST