Source code for fastar.tools.utils
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import jax.numpy as jnp
from jax.scipy.integrate import trapezoid
# =============================================================================
# Photometric and Spectroscopic Utilities for FaStar
# =============================================================================
[docs]
def compute_ab_magnitudes(wave, spectra, fresp):
"""
Compute AB magnitudes from synthetic spectra using a filter response.
Parameters
----------
wave : array-like
Wavelength grid (in Angstroms).
spectra : array-like
Spectral fluxes sampled over `wave`.
fresp : array-like
Filter transmission curve sampled over `wave`.
Returns
-------
float
AB magnitude.
"""
denominator = trapezoid(fresp / wave, x=wave)
numerators = trapezoid(spectra * fresp * wave, x=wave)
flux_density = numerators / denominator
return -2.5 * jnp.log10(flux_density) - 2.406
[docs]
def flux_sum(wave, flux, bend, rend):
"""
Integrate spectral flux within a specified wavelength band,
accounting for partial pixel coverage at band edges.
Parameters
----------
wave : array-like
Wavelength grid.
flux : array-like
Flux values corresponding to `wave`.
bend : float
Blue (lower) limit of the band.
rend : float
Red (upper) limit of the band.
Returns
-------
float
Total flux within the band.
"""
step = wave[1] - wave[0]
total = sum(flux[(wave >= bend + step / 2) & (wave <= rend - step / 2)])
# Handle partial pixels on blue edge
nfrac = wave[(wave > bend - step / 2) & (wave < bend + step / 2)]
if nfrac.size != 0:
wfrac = ((nfrac + step / 2) - bend) / step
total += flux[(wave > bend - step / 2) & (wave < bend + step / 2)] * wfrac
# Handle partial pixels on red edge
nfrac = wave[(wave < rend + step / 2) & (wave > rend - step / 2)]
if nfrac.size != 0:
wfrac = (rend - (nfrac - step / 2)) / step
total += flux[(wave > rend - step / 2) & (wave < rend + step / 2)] * wfrac
return total
[docs]
def compute_linestrengths(wave, flux, index, dat):
"""
Compute the strength of a spectral feature defined by a Lick-style index.
Parameters
----------
wave : array-like
Wavelength grid.
flux : array-like
Spectral flux.
index : str
Name of the index to compute (must match `dat['NAME']`).
dat : Table
Table with index definitions (Blue_1, Blue_2, Red_1, Red_2, Line_1,
Line_2, T).
Returns
-------
float
Line strength in Angstroms (T=2) or magnitudes (T=1).
"""
# Continuum regions
blue_c = flux_sum(
wave,
flux,
dat[dat['NAME'] == index]['Blue_1'][0],
dat[dat['NAME'] == index]['Blue_2'][0],
)
red_c = flux_sum(
wave,
flux,
dat[dat['NAME'] == index]['Red_1'][0],
dat[dat['NAME'] == index]['Red_2'][0],
)
blue_width = (
dat[dat['NAME'] == index]['Blue_1'][0] + dat[dat['NAME'] == index]['Blue_2'][0] # noqa: W503
) / 2.0
red_width = (
dat[dat['NAME'] == index]['Red_1'][0] + dat[dat['NAME'] == index]['Red_2'][0] # noqa: W503
) / 2.0
blue_c /= (
dat[dat['NAME'] == index]['Blue_2'][0] - dat[dat['NAME'] == index]['Blue_1'][0] # noqa: W503
)
red_c /= (
dat[dat['NAME'] == index]['Red_2'][0] - dat[dat['NAME'] == index]['Red_1'][0] # noqa: W503
)
mval = (red_c - blue_c) / (red_width - blue_width)
cval_1 = mval * (dat[dat['NAME'] == index]['Line_1'][0] - blue_width) + blue_c
cval_2 = mval * (dat[dat['NAME'] == index]['Line_2'][0] - blue_width) + blue_c
cont = (0.5 * (cval_1 + cval_2)) * (
dat[dat['NAME'] == index]['Line_2'][0] - dat[dat['NAME'] == index]['Line_1'][0] # noqa: W503
)
band_c = flux_sum(
wave,
flux,
dat[dat['NAME'] == index]['Line_1'][0],
dat[dat['NAME'] == index]['Line_2'][0],
)
if dat[dat['NAME'] == index]['T'] == 2:
index_val = (1.0 - (band_c / cont)) * (
dat[dat['NAME'] == index]['Line_2'][0]
- dat[dat['NAME'] == index]['Line_1'][0] # noqa: W503
)
elif dat[dat['NAME'] == index]['T'] == 1:
index_val = -2.5 * jnp.log10(band_c / cont)
return index_val