Color grid predictions

It is generally useful when analysing stellar populations to plot the color of the populations against a background model grid to infer the age and metallicity of the population. With milespy, it is straightforward to generate such a grid in a few steps.

[1]:
from milespy import SSPLibrary
import matplotlib.pyplot as plt
import numpy as np
import astropy.units as u
import milespy.filter as flib

We start for this example with the E-MILES SSP library and with the Kroupa Universal IMF (see the MILES webpage) with the BaSTI isochrones.

[2]:
emiles = SSPLibrary(
    source="EMILES_SSP",
    version="9.1",
    imf_type="ku",
    isochrone="T",
)

As for this exercise we do not need the full EMILES spectral range, we trim the models to save some memory.

[3]:
emiles.trim(3600*u.AA, 15000*u.AA)

We select the filters that we want to use. We want to use the “g-r” and “i - J” colors, so we get the correspoding filters.

[4]:
fnames = flib.search("(SLOAN_SDSS.(g|r|i)|2MASS_2MASS.J)")
filts = flib.get(fnames)

We define the constant metallicities and ages for drawing the grid

[5]:
ctZs = np.array([-2.2, -1, -0.3, 0., 0.25]) << u.dex
ctTs = np.array([3., 5., 7.5, 10.]) << u.Gyr

And we proceed now to generate the plot. We start by generating the constant metallicity lines

[8]:
f, ax = plt.subplots(1, figsize=(5,4))

T = np.linspace(ctTs[0], ctTs[-1], 20)
imf = np.full(T.shape, 1.3)
for Z in ctZs:
    mags = emiles.interpolate(age=T, met=np.ones(T.shape)*Z, imf_slope=imf).magnitudes(filts)
    gr = mags['SLOAN_SDSS.g'] - mags['SLOAN_SDSS.r']
    iJ = mags['SLOAN_SDSS.i'] - mags['2MASS_2MASS.J']
    ax.plot(gr, iJ, 'k', alpha=0.8)
    ax.text(gr[-1]+0.05, iJ[-1], f"{Z.value:.2f}", c='k', horizontalalignment='center', verticalalignment='center')
../_images/tutorials_example_color_grid_11_0.png

And we repeat the process to add the constant age lines.

[9]:
Z = np.linspace(ctZs[0], ctZs[-1], 20)
for t in ctTs:
    mags = emiles.interpolate(age=np.ones(Z.shape)* t, met=Z, imf_slope=imf).magnitudes(filts)
    gr = mags['SLOAN_SDSS.g'] - mags['SLOAN_SDSS.r']
    iJ = mags['SLOAN_SDSS.i'] - mags['2MASS_2MASS.J']
    ax.plot(gr, iJ, 'r--', alpha=0.8)
    ax.text(gr[-1], iJ[-1]+0.04, f"{t.value:.1f}", c='r', horizontalalignment='center', verticalalignment='center')

ax.set_xlabel('g - r')
ax.set_ylabel('i - J')
ax.set_xlim(0.3, 0.9)
ax.set_ylim(0.05, 0.8)

ax.text(0.35, 0.7, 'Age, Gyr', c='r', size=16)
ax.text(0.35, 0.62, 'Metallicity, [M/H]', c='k', size=16)

plt.tight_layout()
f
[9]:
../_images/tutorials_example_color_grid_13_0.png
<Figure size 640x480 with 0 Axes>

Note: we used interpolate, rather than closest, which is faster. But for this grid it could generate bad-looking lines if we select the grid lines outside of the exact ranges sampled in the library.