def view_eep_fit(self, mass, feh, plot_fit=True, order=5, p0=None, plot_p0=False): import holoviews as hv hv.extension('bokeh') subdf = self.df.xs((mass, feh), level=('initial_mass', 'initial_feh')) ds = hv.Dataset(subdf) pts = hv.Points(ds, kdims=['age', 'eep'], vdims=['phase', 'interpolated']).options(tools=['hover'], width=800, height=400, marker='+') primary_eeps = self.primary_eeps primary_ages = [subdf.loc[e].age for e in primary_eeps if e < subdf.eep.max()] from isochrones.eep import eep_fn, eep_jac, eep_fn_p0 from scipy.optimize import curve_fit if p0 is None: p0 = eep_fn_p0(subdf.age.values, subdf.eep.values, order=order) m = subdf.eep < 808 if plot_fit: pfit, _ = curve_fit(partial(eep_fn, order=order), subdf.age.values[m], subdf.eep.values[m], p0, jac=partial(eep_jac, order=order)) fit = hv.Points([(a, eep_fn(a, *pfit)) for a in subdf.age]) if plot_p0: p0_fit = hv.Points([(a, eep_fn(a, *p0)) for a in subdf.age]) olay = pts * hv.Points([(a, e) for a, e in zip(primary_ages, primary_eeps)]).options(size=8) if plot_fit: olay = olay * fit if plot_p0: olay = olay * p0_fit return olay
def fit_approx_eep(self, max_fit_eep=808): fehs = self.df.index.levels[0] ms = self.df.index.levels[1] columns = ['p5', 'p4', 'p3', 'p2', 'p1', 'p0', 'A', 'x0', 'tau'] par_df = pd.DataFrame(index=pd.MultiIndex.from_product((fehs, ms)), columns=columns) for feh, m in tqdm(itertools.product(fehs, ms), total=len(fehs) * len(ms), desc='Fitting approximate eep(age) function'): subdf = self.df.xs((feh, m), level=('initial_feh', 'initial_mass')) p0 = eep_fn_p0(subdf.age, subdf.eep) last_pfit = p0 mask = subdf.eep < max_fit_eep try: if subdf.eep.max() < 500: raise RuntimeError pfit, _ = curve_fit(eep_fn, subdf.age.values[mask], subdf.eep.values[mask], p0, jac=eep_jac) except RuntimeError: # if the full fit barfs, just use the polynomial by setting A to zero, and the rest same as previous. pfit = list( np.polyfit(subdf.age.values[mask], subdf.eep.values[mask], 5)) + last_pfit[-3:] pfit[-3] = 0 last_pfit = pfit par_df.loc[(feh, m), :] = pfit return par_df.astype(float)
def view_eep_fit(self, mass, feh, plot_fit=True, order=5, p0=None, plot_p0=False): import holoviews as hv hv.extension('bokeh') subdf = self.df.xs((mass, feh), level=('initial_mass', 'initial_feh')) ds = hv.Dataset(subdf) pts = hv.Points(ds, kdims=['age', 'eep'], vdims=['phase', 'interpolated']).options(tools=['hover'], width=800, height=400, marker='+') primary_eeps = self.primary_eeps primary_ages = [ subdf.loc[e].age for e in primary_eeps if e < subdf.eep.max() ] from isochrones.eep import eep_fn, eep_jac, eep_fn_p0 from scipy.optimize import curve_fit if p0 is None: p0 = eep_fn_p0(subdf.age.values, subdf.eep.values, order=order) m = subdf.eep < 808 if plot_fit: pfit, _ = curve_fit(partial(eep_fn, order=order), subdf.age.values[m], subdf.eep.values[m], p0, jac=partial(eep_jac, order=order)) fit = hv.Points([(a, eep_fn(a, *pfit)) for a in subdf.age]) if plot_p0: p0_fit = hv.Points([(a, eep_fn(a, *p0)) for a in subdf.age]) olay = pts * hv.Points([ (a, e) for a, e in zip(primary_ages, primary_eeps) ]).options(size=8) if plot_fit: olay = olay * fit if plot_p0: olay = olay * p0_fit return olay
def fit_approx_eep(self, max_fit_eep=808): fehs = self.df.index.levels[0] ms = self.df.index.levels[1] columns = ['p5', 'p4', 'p3', 'p2', 'p1', 'p0', 'A', 'x0', 'tau'] par_df = pd.DataFrame(index=pd.MultiIndex.from_product((fehs, ms)), columns=columns) for feh, m in tqdm(itertools.product(fehs, ms), total=len(fehs)*len(ms), desc='Fitting approximate eep(age) function'): subdf = self.df.xs((feh, m), level=('initial_feh', 'initial_mass')) p0 = eep_fn_p0(subdf.age, subdf.eep) last_pfit = p0 mask = subdf.eep < max_fit_eep try: if subdf.eep.max() < 500: raise RuntimeError pfit, _ = curve_fit(eep_fn, subdf.age.values[mask], subdf.eep.values[mask], p0, jac=eep_jac) except RuntimeError: # if the full fit barfs, just use the polynomial by setting A to zero, and the rest same as previous. pfit = list(np.polyfit(subdf.age.values[mask], subdf.eep.values[mask], 5)) + last_pfit[-3:] pfit[-3] = 0 last_pfit = pfit par_df.loc[(feh, m), :] = pfit return par_df.astype(float)