Magnitudes, colors, indices and M/Ls#

In addition to spectroscopic and photometric predictions, FASTAR also allows the computation of complementary quantities, in particular, magnitudes, colors, line-strength indices, and mass-to-light ratios.

[1]:
import numpy as np

Magnitudes and colors#

Absolute AB magnitudes can be measured directly from the FASTAR models using the provided built-in function. Let’s see first an example for a fully-sampled SSP model

[2]:
# Let's load the SSP synthesizer and an IMF
from fastar import IntegratedSSPSynthesizer
from fastar.imf import kroupa

# From the FASTAR tools, we also load the function to compute magnitudes
from fastar.tools.utils import compute_ab_magnitudes

# As well as some additional astropy ones to load photometric filter responses
from astroquery.svo_fps import SvoFps

# We create first a SSP model
ssp = IntegratedSSPSynthesizer(imf_function=kroupa)
wave = ssp.wave

# Synthesize SSP
spec = ssp.synthesize(age=5, met=-1)

# For example, we can calculate the expected r-band AB absolute magnitude
r_filter_data = SvoFps.get_transmission_data('SLOAN/SDSS.r')
r_filter_response = np.interp(
    wave, r_filter_data['Wavelength'], r_filter_data['Transmission'], left=0, right=0
)
rmag = compute_ab_magnitudes(wave, spec, r_filter_response)

For a semi-resolved FASTAR SSP model, the approach is exactly the same

[3]:
import jax
from fastar import SemiresolvedSSPSynthesizer

semi_ssp = SemiresolvedSSPSynthesizer(imf_function=kroupa)
wave = semi_ssp.wave

key = jax.random.PRNGKey(0)
semi_spec, semi_mass = semi_ssp.synthesize(age=8, met=0, num_stars=int(100), key=key)
semi_rmag = compute_ab_magnitudes(wave, semi_spec, r_filter_response)

The meaning of absolute magnitudes

The interpretation of absolute magnitudes in FASTAR depends on whether you are using fully-sampled or semi-resolved models.

Fully-sampled SSP models: normalized to 1 M☉ at birth → magnitude corresponds to that population at 10 pc.

Semi-resolved SSP models: defined by N stars → stochastic magnitudes due to IMF sampling.

Colors are trivially calculated as the difference between two magnitudes

[4]:
g_filter_data = SvoFps.get_transmission_data('SLOAN/SDSS.g')
g_filter_response = np.interp(
    wave, r_filter_data['Wavelength'], r_filter_data['Transmission'], left=0, right=0
)
gmag = compute_ab_magnitudes(wave, spec, g_filter_response)

gr_color = gmag - rmag

Line-strength indices#

FASTAR comes with a built-in function to measure line-strength indices over the synthesized spectra. We include an extensive compilation of index definitions that can be updated to accommodate new ones.

[5]:
from fastar.tools.assets import get_asset_path
from astropy.io.ascii import read as ascii_read
from fastar.tools.utils import compute_linestrengths

index_tab = ascii_read(get_asset_path('indices.def'))

hbeta = compute_linestrengths(wave, spec, 'Hbeta_o', index_tab)
print('Hbeta_o', hbeta)
Hbeta_o [3.6031184]

Mass-to-light ratios#

Mass-to-light ratios can be measured given any photometric within the FASTAR wavelength range(s). Because of the difference in the normalization, the way that M/L are measured depends on whether you are working with fully-sampled (standard) SSP models or with semi-resolved predictions.

M/L in fully-sampled SSP models#

Measuring the M/L for the standard FASTAR models is straightforward. As commonly assumed, the measured M/L are in units of solar masses over solar luminosities. FASTAR uses the CALSPEC Kurucz model of the Sun (Bohlin et al. 2014), scaled the adopted V-band absolute magnitude of the Sun.

[6]:
# Let's load for example the SDSS g-band filter
ml_ratio = ssp.mass_to_light_ratio(age=10, met=0, filter_response=g_filter_response)
print('Stellar M/L', ml_ratio['stars'])
print('Total M/L', ml_ratio['total'])
Stellar M/L 2.6522236
Total M/L 5.8894258

Note that we provide two different mass-to-light ratios. The stelar M/L corresponds to the stellar mass present in the SSP divided by the luminosity, while the total M/L takes into account the stellar mass, plus the mass in stellar remnants and the mass of gas ejected during the evolution of the stars. Both of them are valid assumptions depending on your scientific goals.

For completeness, you can also have access to the mass in stars still contributing to any given SSP model. This mass is in units of solar masses and it will always be smaller than one as the SSPs are normalized to one solar mass at birth.

[7]:
stellar_mass = ssp.stellar_mass(age=10, met=0)
print('Total mass in stars still alive', stellar_mass)
Total mass in stars still alive 0.45033658

M/L in semi-resolved SSP models#

As virtually any prediction associated to semi-resolved stellar populations, M/L predictions are stochastic and unique to each different model realization / IMF sampling.

Calculating the M/L involves in this case a two-step process. First, the synthesis of the desired semi-resolved model, which retrieves both the spectrum and the stellar mass.

[8]:
semi_spec, semi_mass = semi_ssp.synthesize(age=7, met=0.2, num_stars=int(100), key=key)
print('Stellar mass of the semi-resolved model', semi_mass)
Stellar mass of the semi-resolved model 35.23527

Note that in the semi-resolved mode, stellar masses actually correspond to the total stellar mass (in solar units) of that population and it then scales with the number of stars.

The absolute magnitude of the model is calculated as before (in the r-band, for example)

[9]:
semi_rband_mabs = compute_ab_magnitudes(wave, semi_spec, r_filter_response)

To scale the model luminosity into solar units, for consistency, we will use again the CALSPEC Kurucz model of the Sun. It is easily accessible from the fully-integrated SSP module

[10]:
solar_model = ssp.sun_spec[None, :]
solar_rband_mabs = compute_ab_magnitudes(wave, solar_model, r_filter_response)

semi_solarscaled_rband_luminosity = 10 ** (-0.4 * (semi_rband_mabs - solar_rband_mabs))

The M/L of the semi-resolved SSP model would then directly be the ratio between the mass of the model and its luminosity, both already in solar units

[11]:
semi_rband_ml = semi_mass / semi_solarscaled_rband_luminosity

print('M/L of this specific semi-resolved model realization (r-band)', semi_rband_ml)
M/L of this specific semi-resolved model realization (r-band) [4.8730373]