Isochrone Interpolation and CMD Loading in Astronomy
This Python script is designed for astronomers and astrophysicists who work with stellar isochrones and color-magnitude diagrams (CMDs). It includes functions to load isochrone data files, extract metadata, and perform interpolations for specific ages and metallicities based on the isochrone models. The script utilizes libraries such as NumPy for numerical operations, SciPy for interpolation, and tqdm for progress bars. Key functionalities include the ability to read isochrone files and metadata, construct and interpolate within CMDs at specific magnitudes, and interpolate isochrone data for a target stellar age.
from fidanka.isochrone.MIST import read_iso, read_iso_metadata import numpy as np import pickle as pkl import pathlib import re from tqdm import tqdm from scipy.interpolate import interp1d def load_ISO_CMDs(root): CMDs = list(map(lambda x: str(x), pathlib.Path(root).rglob("isochrones.txt"))) extract = list(map(lambda x: re.findall(r"Pop(A|E)\+(\d\.\d+)\/alpha-(\d\.\d+)\/", x)[0], CMDs)) pops = set(map(lambda x: x[0], extract)) Ys = set(map(lambda x: x[1], extract)) alphas = set(map(lambda x: x[2], extract)) lookup = dict() FeHLookup = dict() for pop in tqdm(pops, leave=False): lookup[pop] = dict() FeHLookup[pop] = dict() for Y in tqdm(Ys, leave=False): lookup[pop][float(Y)] = dict() FeHLookup[pop][float(Y)] = dict() for alpha in tqdm(alphas, leave=False): if checkTup := (pop, Y, alpha) in extract: extractID = extract.index((pop, Y, alpha)) iso = read_iso(CMDs[extractID]) metadata = read_iso_metadata(CMDs[extractID]) FeH = metadata['[Fe/H]'] lookup[pop][float(Y)][float(alpha)] = iso FeHLookup[pop][float(Y)][float(alpha)] = FeH return lookup, FeHLookup def interCMDatMag(color, mag, targetMag): f = interp1d(mag, color) return f(targetMag) def interp_isochrone_age(iso, targetAge): logTargetAgeYr= np.log10(targetAge*1e9) ageKeys = list(iso.keys()) distance = [(x-logTargetAgeYr, x) for x in ageKeys] below = sorted(filter(lambda x: x[0] <=0, distance), key=lambda x: abs(x[0])) above = sorted(filter(lambda x: x[0] > 0, distance), key=lambda x: x[0]) isoBelow = iso[below[0][1]] isoAbove = iso[above[0][1]] age1 = isoBelow['log10_isochrone_age_yr'].iloc[0] age2 = isoAbove['log10_isochrone_age_yr'].iloc[0] def linearinterpolate(x, other, age1, age2): newIso = ((other[x.name] - x)/(age2-age1)) * (logTargetAgeYr - age1) + x return newIso interpolated = isoBelow.apply(lambda x: linearinterpolate(x, isoAbove, age1, age2)) return interpolated