galfits.sed_interp

Spectral Energy Distribution Interpolation Module

This module provides fast interpolation of pre-computed SED templates for stellar populations, AGN, dust emission, and nebular emission. It uses JAX for GPU-accelerated interpolation and automatic differentiation support.

The module loads various SED libraries at import time and provides functions to interpolate these templates for arbitrary physical parameters.

SED Templates

  • Stellar populations: BC03-based continuum and instantaneous burst

  • AGN: Thin disk, starburst disk, broad-line region

  • Dust emission: Draine & Li (2007) models with power-law and constant U

  • Nebular emission: Continuum (free-free, free-bound) and emission lines

  • Torus: CAT3D torus models for AGN

  • High-resolution: Templates for IFU/spectroscopy

Key Functions

  • get_host_SED : Interpolate stellar population SED

  • get_AGN_SED : Interpolate AGN thin disk SED

  • get_nebular : Interpolate nebular continuum and lines

  • get_cold_dust_sed : Interpolate dust emission SED

  • cat3Dtorus : Interpolate AGN torus emission

  • sed_to_obse : Transform rest-frame to observed-frame

  • mycigale : Calzetti+ dust attenuation curve

  • luminosity_distance : Compute luminosity distance at redshift

  • kpc_per_arcsec : Physical scale at redshift

  • cosmo_age : Age of universe at redshift

Cosmology

Default cosmology: Flat ΛCDM with H0=70, Ωm=0.3, ΩΛ=0.7

Units

  • Wavelength: Angstroms

  • Luminosity: 10^38 erg/s (or per Å for spectral luminosity)

  • Mass: Solar masses (M_sun)

  • Age: Gyr

  • Metallicity: Z (mass fraction, not [Z/H])

  • Dust extinction: Av (magnitudes)

Environment Variable

Requires GS_DATA_PATH environment variable pointing to template directory. Set in your shell configuration:

export GS_DATA_PATH=/path/to/galfits/data

Template Data

Templates are stored as .npz files with regular grids for fast interpolation. All interpolators use RegularGridInterpolator from JAX for differentiability.

Notes

All luminosity values are in units of 10^38 erg/s unless otherwise noted. This module is automatically imported and initialized when galfits is loaded.

galfits.sed_interp.BaC(x, logL3600, logM, logMdot, spin, dcen, fwhm)[source]

Generate Balmer continuum emission from AGN broad-line region.

Computes BLR Balmer continuum using pre-computed templates that include high-order Balmer recombination edges (Balmer jump at 3646 Å plus higher-order series). Applies velocity broadening and Doppler shift.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • logL3600 (float) – Log10 of continuum luminosity at 3600 Å in 10^38 erg/s/Å. Used for normalization.

  • logM (float) – Log10 of black hole mass in solar masses [5, 10].

  • logMdot (float) – Log10 of accretion rate in Eddington units [-4, 2].

  • spin (float) – Black hole spin parameter [0, 0.99].

  • dcen (float) – Velocity offset in km/s (positive = redshift).

  • fwhm (float) – Full-width at half-maximum velocity width in km/s.

Returns:

Balmer continuum flux in 10^38 erg/s/Å.

Return type:

array_like

Notes

The Balmer continuum arises from recombination of hydrogen in the dense, ionized gas of the AGN broad-line region. Key features:

  • Balmer jump at 3646 Å (flux discontinuity)

  • Series of higher-order Balmer edges converging to Balmer limit

  • Contributes blue “pseudo-continuum” in optical spectra

  • Depends on BLR density, temperature, covering factor

Templates are computed from photoionization models and depend on black hole parameters through the ionizing continuum shape.

The function normalizes to luminosity at 3600 Å (common AGN reference point below Balmer jump).

See also

FeII

Iron emission template

get_AGN_SED

AGN disk continuum

Examples

>>> wave = jnp.linspace(3000, 5000, 1000)
>>> bac = BaC(wave, logL3600=3.0, logM=8.0, logMdot=-0.5,
...           spin=0.7, dcen=0, fwhm=5000)
galfits.sed_interp.Bbody(x, Ltot, Teff)[source]
galfits.sed_interp.FeII(x, A_uv, A_op, dcen, fwhm)[source]

Generate optical/UV FeII emission template for AGN.

Constructs iron emission spectrum using empirical templates with independent UV and optical normalization. Applies velocity broadening and Doppler shift.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • A_uv (float) – Amplitude of UV FeII template (λ < 3500 Å).

  • A_op (float) – Amplitude of optical FeII template (λ > 3500 Å).

  • dcen (float) – Velocity offset in km/s (positive = redshift).

  • fwhm (float) – Full-width at half-maximum velocity width in km/s. Intrinsic template FWHM = 900 km/s is deconvolved.

Returns:

FeII emission flux (arbitrary normalization).

Return type:

array_like

Notes

FeII emission arises from collisionally excited iron in the AGN broad-line region. It creates broad pseudo-continuum with thousands of blended transitions, especially prominent at:

  • UV: 2200-3200 Å (FeII multiplet 191)

  • Optical: 4400-5500 Å (FeII multiplets around Hβ)

Templates are empirical from composite quasar spectra. The UV and optical components scale independently, reflecting different excitation conditions.

Convolution is performed in log-wavelength space for uniform velocity resolution. The 900 km/s intrinsic width is quadratically subtracted before applying user-specified FWHM.

See also

BaC

Balmer continuum emission

get_AGN_SED

AGN accretion disk continuum

Examples

>>> wave = jnp.linspace(4000, 5500, 1000)
>>> # Moderate FeII with 3000 km/s FWHM
>>> feii = FeII(wave, A_uv=1.0, A_op=1.0, dcen=0, fwhm=3000)

References

Templates from Vestergaard & Wilkes 2001, ApJS, 134, 1

class galfits.sed_interp.TableModel(table_path, param_names, prefix)[source]

Bases: object

Generic SED table model with multi-parameter interpolation.

Loads pre-computed SED grids from .npz files and provides fast interpolation for arbitrary parameter values. Supports optional normalization parameter for flexible scaling.

Parameters:
  • table_path (str) – Path to .npz file containing SED table. Must contain ‘sed’ (log10 L_λ), ‘wave’, and parameter grids.

  • param_names (list of str) – Parameter names to interpolate (must match keys in .npz file). If ‘logNorm’ is included, it will be used for normalization.

  • prefix (str) – Prefix to add to parameter names for external interface (e.g., ‘AGN’ → ‘AGN_spin’, ‘AGN_logM’).

norm

True if normalization parameter is present.

Type:

bool

norm_key

Name of normalization parameter (with prefix).

Type:

str

param_names

Parameter names without ‘logNorm’.

Type:

list of str

pnames

Display names with prefix applied.

Type:

list of str

intp_table_model

JAX interpolator for fast SED lookup.

Type:

RegularGridInterpolator

get_sed(pardict, x)[source]

Interpolate SED at given parameter values and wavelengths.

Notes

Table files (.npz) must contain:

  • ‘sed’: SED grid as log10(L_λ) in erg/s/Å (shape: [N_p1, N_p2, …, N_wave])

  • ‘wave’: Wavelength grid in Angstroms (1D array)

  • Parameter grids: 1D arrays for each parameter (e.g., ‘age’, ‘Z’, ‘logM’)

If ‘logNorm’ parameter is included, SEDs are scaled by 10^logNorm during interpolation, allowing flexible normalization.

The class uses JAX’s RegularGridInterpolator for GPU-accelerated interpolation with automatic differentiation support.

Examples

>>> # Load custom AGN template table
>>> agn_model = TableModel('custom_agn.npz',
...                        param_names=['logM', 'logMdot', 'spin', 'logNorm'],
...                        prefix='AGN')
>>> # Interpolate at specific parameters
>>> params = {'AGN_logM': 8.0, 'AGN_logMdot': -0.5,
...           'AGN_spin': 0.7, 'AGN_logNorm': 44}
>>> wave = jnp.logspace(2, 5, 1000)
>>> sed = agn_model.get_sed(params, wave)

See also

get_AGN_SED

Specialized AGN disk interpolation

get_host_SED

Specialized stellar population interpolation

get_sed(allparams, norm_key)[source]

Interpolate SED at given parameters and wavelengths.

Parameters:
  • pardict (dict) – Dictionary mapping parameter names (with prefix) to values. Must include all parameters in self.param_names. If self.norm=True, must also include normalization parameter.

  • x (array_like) – Wavelength grid in Angstroms for interpolation.

Returns:

Interpolated SED normalized to L5100 = 1. Output in units of 10^38 erg/s/Å.

Return type:

array_like

Examples

>>> params = {'prefix_param1': 1.0, 'prefix_param2': 2.0}
>>> wave = jnp.linspace(1000, 10000, 1000)
>>> sed = model.get_sed(params, wave)
load_table_model()[source]
galfits.sed_interp.brokenpower(x, A, C1, C2)[source]
galfits.sed_interp.calzetti2000(wavelength)[source]

Compute the Calzetti et al. (2000) A(λ)/E(B-V)∗

Given a wavelength grid, this function computes the selective attenuation A(λ)/E(B-V)∗ using the formula from Calzetti at al. (2000) and Leitherer et al. (2002). The formula is given for wavelengths between 91.2 nm and 2200 nm, but this function makes the computation outside.

Parameters:

wavelength (array of floats) – Wavelength grid in angstrom but converted to nm in the function.

Return type:

a numpy array of floats

galfits.sed_interp.cat3Dtorus(x, L38, a, h, N0, i)[source]

Interpolate AGN torus emission SED using CAT3D models.

Uses nearest-neighbor lookup in pre-computed grid of clumpy torus radiative transfer models (Hoenig & Kishimoto 2017).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • L38 (float) – Normalization luminosity in units of 10^38 erg/s.

  • a (float) – Radial density power-law index. Typical range [0, -2]. ρ ∝ r^a where r is distance from center.

  • h (float) – Scale height (ratio of torus height to radius at inner edge). Range [0.1, 1.0]. Larger h = more extended vertically.

  • N0 (float) – Average number of clouds along equatorial ray. Range [1, 15]. Controls optical depth (more clouds = higher τ).

  • i (float) – Inclination angle in degrees [0, 90]. i = 0: face-on (Type 1) i = 90: edge-on (Type 2)

Returns:

Torus emission spectral luminosity density in 10^38 erg/s/Å. Valid wavelength range: 1-100 μm (returns 0 outside).

Return type:

array_like

Notes

  • CAT3D models include clumpiness, 3D radiative transfer, anisotropy

  • Torus heated by central AGN UV/optical emission

  • Re-emits in near-to-far IR (peak around 10-30 μm)

  • Type 1/2 viewing angle dependence built into models

  • Uses nearest-neighbor interpolation (not smooth interpolation)

The torus provides obscuration and IR re-emission in AGN unified model.

See also

get_AGN_SED

AGN accretion disk emission

get_cold_dust_sed

Extended cold dust emission

Examples

>>> wave = jnp.logspace(4, 5, 100)  # 1-10 μm
>>> # Type 1 (face-on) torus
>>> torus_sed = cat3Dtorus(wave, L38=1000, a=-0.5, h=0.5, N0=10, i=30)

References

galfits.sed_interp.ccm89(x, Av, Rv)[source]
galfits.sed_interp.ccm89ab_fuv_invum(x, Av, Rv)[source]

ccm89 a, b parameters for 8 < x < 11 (far-UV)

galfits.sed_interp.ccm89ab_ir_invum(x, Av, Rv)[source]

ccm89 a, b parameters for 0.3 < x < 1.1 (infrared)

galfits.sed_interp.ccm89ab_opt_invum(x, Av, Rv)[source]

ccm89 a, b parameters for 1.1 < x < 3.3 (optical)

galfits.sed_interp.ccm89ab_uv1_invum(x, Av, Rv)[source]

ccm89 a, b parameters for 3.3 < x < 8.0 (ultraviolet)

galfits.sed_interp.ccm89ab_uv2_invum(x, Av, Rv)[source]

ccm89 a, b parameters for 3.3 < x < 8.0 (ultraviolet)

galfits.sed_interp.cigale(wavelength, delta, amplitude)[source]
galfits.sed_interp.conv_spec(wave, flux, sigma, dcenlog=0, Nlogv=2000)[source]

Convolve spectrum with Gaussian velocity kernel.

Performs convolution in log-wavelength space to model velocity dispersion and radial velocity shifts. JIT-compiled for performance.

Parameters:
  • wave (array_like) – Wavelength array in Angstroms.

  • flux (array_like) – Flux array (same length as wave).

  • sigma (float) – Velocity dispersion in km/s (1-sigma width of Gaussian kernel).

  • dcenlog (float, optional) – Velocity offset in km/s (positive = redshift, default: 0).

  • Nlogv (int, optional) – Number of points in log-wavelength interpolation grid (default: 2000). Higher = more accurate but slower.

Returns:

Convolved flux array at original wavelength grid.

Return type:

array_like

Notes

Algorithm:

  1. Convert wavelength to log(λ) for uniform velocity spacing

  2. Interpolate flux onto regular log-wavelength grid

  3. Convolve with Gaussian kernel: K(v) ∝ exp(-v²/2σ²)

  4. Shift by dcenlog (applies Doppler formula)

  5. Interpolate back to original wavelength grid

Edge effects are handled by extending flux with constant values (100 pixels on each side).

The Gaussian kernel in log-wavelength is equivalent to velocity-space convolution: Δv/c = Δ(ln λ).

See also

get_host_SED_3D

Uses this for velocity dispersion in stellar SEDs

Examples

>>> wave = jnp.linspace(5000, 5500, 1000)
>>> flux = jnp.ones_like(wave)
>>> flux = flux.at[500].set(10)  # Emission line
>>> # Broaden line by 200 km/s dispersion
>>> flux_conv = conv_spec(wave, flux, sigma=200)
>>> # Also apply +500 km/s redshift
>>> flux_shifted = conv_spec(wave, flux, sigma=200, dcenlog=500)
galfits.sed_interp.conv_spec_lsf_R(wave, flux, lsf_wave, lsf_R, *, dcen_kms=0.0, extra_sigma_kms=0.0, Nlogv=2000, K=50)[source]
galfits.sed_interp.cosmo_age(z)[source]

Compute age of universe at redshift z.

Uses pre-computed lookup table for flat ΛCDM cosmology (H0=70, Ωm=0.3).

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Age of universe in Gyr.

Return type:

float or array_like

Examples

>>> age = cosmo_age(2.0)
>>> print(f"Universe age at z=2: {age:.2f} Gyr")
galfits.sed_interp.eazy_lognorm_to_logSFR(lognorms, template_sfr=Array([7.8729427e-06, 6.3261302e-04, 1.0946556e+01, 7.8539217e-01, 5.9802396e-08, 8.7987081e-07, 1.8755735e-09, 3.8053772e-06, 2.3488412e-05, 7.0655952e+01, 2.2518292e-05, 3.3370560e+01, 4.1507337e-07, 3.5962694e-07, 1.9262400e-03, 2.3268182e+02, 4.2486950e-05, 5.7516351e+00], dtype=float32))[source]

Convert EAZY template log-normalizations to total log10(SFR).

Parameters:
  • lognorms (array-like) – Per-template log10 normalization coefficients.

  • template_sfr (array-like, optional) – SFR of each EAZY template at logM=10, in Msun/yr.

Returns:

Total log10(SFR/Msun yr^-1).

Return type:

float

galfits.sed_interp.eazy_logw_to_logSFR(logw, logM, template_sfr=Array([7.8729427e-06, 6.3261302e-04, 1.0946556e+01, 7.8539217e-01, 5.9802396e-08, 8.7987081e-07, 1.8755735e-09, 3.8053772e-06, 2.3488412e-05, 7.0655952e+01, 2.2518292e-05, 3.3370560e+01, 4.1507337e-07, 3.5962694e-07, 1.9262400e-03, 2.3268182e+02, 4.2486950e-05, 5.7516351e+00], dtype=float32))[source]

Convert EAZY template log-weights to total log10(SFR).

Parameters:
  • logw (array-like) – Raw per-template log10 weights (before normalization).

  • logM (float) – Total stellar mass in log10(Msun), consistent with GalfitS profile logM.

  • template_sfr (array-like, optional) – SFR of each EAZY template at logM=10, in Msun/yr.

Returns:

Total log10(SFR/Msun yr^-1).

Return type:

float

galfits.sed_interp.f_cont_to_logSFR(f_cont, logM, age, present_age=13.8, SFH='conti')[source]

Convert continuum fraction to instantaneous star formation rate.

Derives contemporary SFR from the mass fraction in continuous star formation component for composite SFH models.

Parameters:
  • f_cont (float or array_like) – Log10 of mass fraction in continuous SF component. For ‘bins’: array of log10 mass fractions per bin.

  • logM (float) – Log10 of total stellar mass in solar masses.

  • age (float or array_like) – For ‘conti’/’burst’: age of burst in Gyr. For ‘bins’: array of bin edges in Gyr.

  • present_age (float, optional) – Current age of universe in Gyr (default: 13.8).

  • SFH ({'conti', 'burst', 'bins'}, optional) – Star formation history model (default: ‘conti’).

Returns:

Log10 of star formation rate in M_sun/yr.

Return type:

float

Notes

For ‘conti’ SFH:

SFR = M_cont / (t_present - 0.2 Gyr)

For ‘burst’ SFH:

SFR = M_cont / (0.1 Gyr) [τ-model timescale]

Also accounts for instantaneous burst component with smoothed error function to handle recent starbursts (< 100 Myr).

See also

logSFR_to_f_cont

Inverse transformation (SFR → f_cont)

get_host_SED

Uses f_cont to build SED

Examples

>>> # 10^10 Msun galaxy, 10% in continuous SF
>>> logSFR = f_cont_to_logSFR(f_cont=-1.0, logM=10.0, age=0.1, SFH='conti')
>>> print(f"SFR = {10**logSFR:.2f} Msun/yr")
galfits.sed_interp.gaussianL_jax3D(x, norm, cen, wid)[source]
galfits.sed_interp.gaussian_jax(x, peak, cen, wid)[source]
galfits.sed_interp.get_AGN_SED(x, logM, logMdot, spin, C_unit)[source]

Interpolate AGN accretion disk SED for given black hole parameters.

Uses pre-computed thin disk models (Shakura-Sunyaev) with relativistic ray-tracing corrections for spinning black holes.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms [125, 24700].

  • logM (float) – Log10 of black hole mass in solar masses. Range [5, 10].

  • logMdot (float) – Log10 of accretion rate in Eddington units. Range [-4, 2]. Mdot_Edd = L_Edd / (η c^2).

  • spin (float) – Dimensionless black hole spin parameter (0 = Schwarzschild, 0.998 = maximal). Range [0, 0.99].

  • C_unit (float) – Normalization constant (typically 10^38 for erg/s units).

Returns:

Rest-frame AGN spectral luminosity density L_λ in units of C_unit (typically 10^38 erg/s/Å).

Return type:

array_like

Notes

  • Templates assume standard thin disk with Novikov-Thorne efficiency

  • Includes relativistic Doppler boosting and gravitational redshift

  • Higher spin → more luminous at fixed Mdot (higher efficiency)

  • Includes color correction for disk atmosphere

  • Valid for radiatively efficient accretion (Mdot/Mdot_Edd > 0.01)

See also

starburst_disk

Alternative starburst-heated disk model

cat3Dtorus

AGN torus emission component

Examples

>>> wave = jnp.logspace(2, 4.4, 500)  # 100 Å to 25000 Å
>>> agn_sed = get_AGN_SED(wave, logM=8.0, logMdot=-0.5, spin=0.7, C_unit=1e38)

References

galfits.sed_interp.get_cold_dust_L(qpah, Umin, alpha, gamma)[source]

Compute total dust luminosity for Draine & Li (2007) models.

Returns integrated IR luminosity (total power emitted) for given dust parameters, normalized to dust mass.

Parameters:
  • qpah (float or array_like) – PAH abundance parameter (percentage of dust mass in PAHs).

  • Umin (float) – Minimum radiation field intensity (Mathis field units).

  • alpha (float or array_like) – Power-law index for radiation field distribution.

  • gamma (float) – Fraction of dust mass in power-law component [0, 1].

Returns:

Log10 of total dust luminosity normalized to 10^38 erg/s per solar mass of dust: log10(L_dust / M_dust / 10^38).

Return type:

float or array_like

Notes

Total luminosity combines constant and power-law components:

L_tot = (1 - γ) × L(U_min) + γ × L(U_power)

where L(U) is the emissivity integrated over wavelength.

Used to convert dust mass to IR luminosity or vice versa.

See also

get_cold_dust_sed

Full SED for same parameters

Examples

>>> logL_per_Msun = get_cold_dust_L(qpah=3.5, Umin=1.0, alpha=2.0, gamma=0.3)
>>> # Total IR luminosity for 10^7 Msun of dust
>>> logMdust = 7.0
>>> logL_IR = logL_per_Msun + logMdust
galfits.sed_interp.get_cold_dust_sed(x, logMdust, qpah, Umin, alpha, gamma)[source]

Interpolate dust emission SED using Draine & Li (2007) models.

Computes IR dust emission as combination of radiation fields with constant intensity (U_min) and power-law distribution (dM/dU ∝ U^-α).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • logMdust (float) – Log10 of dust mass in solar masses.

  • qpah (float) – PAH abundance parameter (percentage of dust mass in PAH grains). Range [0.47, 4.58]. Solar neighborhood: qpah ~ 3.5%.

  • Umin (float) – Minimum radiation field intensity (in units of Mathis field). Range [0.1, 25]. ISRF: U = 1.

  • alpha (float) – Power-law index for radiation field distribution dM/dU ∝ U^-α. Range [1.0, 3.0]. Typical: α ~ 2.

  • gamma (float) – Fraction of dust mass in power-law component. Range [0, 1]. gamma = 0: all dust at U_min (quiescent) gamma = 1: all dust in power-law (PDR-dominated)

Returns:

Dust emission spectral luminosity density in 10^38 erg/s/Å.

Return type:

array_like

Notes

Total SED is combination of two components:

  • Constant U: L_const = (1 - γ) × M_dust × ε(U_min)

  • Power-law U: L_power = γ × M_dust × ∫ ε(U) U^-α dU

where ε(U) is the emissivity per unit dust mass at radiation field U.

PAH emission dominates at λ < 20 μm (features at 3.3, 6.2, 7.7, 11.3 μm). Larger grains emit modified blackbody at λ > 50 μm.

See also

get_cold_dust_L

Total dust luminosity for same parameters

Examples

>>> wave = jnp.logspace(4, 6, 200)  # 1-100 μm
>>> dust_sed = get_cold_dust_sed(wave, logMdust=7.0, qpah=3.5,
...                              Umin=1.0, alpha=2.0, gamma=0.3)

References

galfits.sed_interp.get_eazy_sed(wave, lognorms)[source]

Get the EAZY SEDs for a given set of wavelengths and normalizations.

Parameters:
  • wave (array-like) – The wavelengths at which to evaluate the SEDs.

  • lognorms (array-like) – Log10 normalizations for each template. (18,) array-like.

Returns:

sed – The SEDs evaluated at the given wavelengths and normalizations. by simply linearly combining the EAZY templates with the provided normalizations.

Return type:

array-like

galfits.sed_interp.get_host_SED(x, logM, f_cont, age, Z, Av, C_unit, SFH='conti', present_age=13.8, delta=3.0)[source]

Interpolate stellar population SED with composite star formation history.

Generates rest-frame SED by combining continuum star formation and instantaneous burst components using BC03 templates. Supports multiple SFH models (continuous, burst, or binned).

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms [91, 1.6e6].

  • logM (float) – Log10 of total stellar mass in solar masses.

  • f_cont (float or array_like) – Fraction of mass in continuous star formation component. For ‘bins’ SFH: array of log10(mass fraction) per bin. For ‘conti’/’burst’: scalar in range [log10(1e-6), 0].

  • age (float or array_like) – For ‘conti’/’burst’: Age of burst component in Gyr [1e-5, 13.69]. For ‘bins’: Array of bin edges in Gyr.

  • Z (float) – Metallicity (mass fraction, not [Z/H]). Range [0.001, 0.04]. Z_solar = 0.02.

  • Av (float) – V-band attenuation in magnitudes.

  • C_unit (float) – Normalization constant (typically 10^38 for erg/s units).

  • SFH ({'conti', 'burst', 'bins'}, optional) –

    Star formation history model (default: ‘conti’).

    • ’conti’: Continuous SF + recent burst

    • ’burst’: τ-model with exponential decline

    • ’bins’: Custom binned SFH

  • present_age (float, optional) – Current age of universe in Gyr (default: 13.8).

  • delta (float, optional) – UV slope modification for attenuation curve (default: 3.0).

Returns:

Rest-frame spectral luminosity density L_λ in units of C_unit (typically 10^38 erg/s/Å).

Return type:

array_like

Notes

  • Continuum template normalized to SFR = 10 M_sun/yr

  • Instantaneous burst template normalized to M_* = 10^7 M_sun

  • Uses Calzetti+ attenuation curve with UV bump

  • BC03 templates cover ages from 10 kyr to ~13.7 Gyr

For ‘bins’ SFH, mass fractions are internally normalized to sum to unity.

See also

get_host_SED_3D

High-resolution version with velocity dispersion

get_host_SED_withL

Version that also returns absorbed luminosity

mycigale

Attenuation curve implementation

Examples

>>> wave = jnp.logspace(2, 5, 1000)  # 100 Å to 100 μm
>>> sed = get_host_SED(wave, logM=10.5, f_cont=-1.0, age=0.1,
...                    Z=0.02, Av=1.0, C_unit=1e38, SFH='conti')
galfits.sed_interp.get_host_SED_3D(x, logM, f_cont, age, Z, Av, sigma, C_unit, wave_temp, SFH='conti', present_age=13.8, delta=3.0)[source]
galfits.sed_interp.get_host_SED_withL(x, logM, f_cont, age, Z, Av, C_unit, SFH='conti', present_age=13.8, delta=3.0)[source]
galfits.sed_interp.get_nebular(x, Lha, logU, Z, Av, withline=True, delta=3.0)[source]

Interpolate nebular emission SED (continuum + lines).

Uses pre-computed CLOUDY photoionization models normalized to H-α luminosity. Includes both nebular continuum (free-free, free-bound, two-photon) and emission lines.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • Lha (float) – H-α luminosity in units of 10^38 erg/s.

  • logU (float) – Log10 of ionization parameter (ratio of ionizing photon to hydrogen density). Range typically [-4, -1].

  • Z (float) – Gas-phase metallicity (mass fraction). Range [0.001, 0.04]. Z_solar = 0.02.

  • Av (float) – V-band attenuation in magnitudes.

  • withline (bool, optional) – If True, include emission lines; if False, only continuum (default: True).

  • delta (float, optional) – UV slope modification for attenuation curve (default: 3.0).

Returns:

Nebular spectral luminosity density L_λ in 10^38 erg/s/Å.

Return type:

array_like

Notes

  • Normalization factor 1.87531 calibrated by fitting CLOUDY models

  • Nebular continuum includes free-free, free-bound, and two-photon emission

  • Line emission includes H, He recombination lines and metal forbidden lines

  • Uses Calzetti+ attenuation curve (dust internal to HII regions)

  • Templates assume plane-parallel geometry with constant density

The ionization parameter U = Q(H) / (4π r^2 n_H c) characterizes the ionizing photon flux relative to gas density.

See also

get_host_SED

Stellar population SED

mycigale

Attenuation curve

Examples

>>> wave = jnp.linspace(3000, 10000, 1000)
>>> # Get full nebular SED with lines
>>> neb_sed = get_nebular(wave, Lha=100, logU=-2.5, Z=0.02, Av=0.5)
>>> # Get only nebular continuum
>>> neb_cont = get_nebular(wave, Lha=100, logU=-2.5, Z=0.02, Av=0.5, withline=False)

References

galfits.sed_interp.get_stellar_sed(x, L38, Teff, logg, logZ)[source]
galfits.sed_interp.igm_transmission(wavelength, redshift)[source]

Compute intergalactic medium (IGM) transmission.

Calculates wavelength-dependent IGM opacity from Lyman series absorption and Lyman continuum blanketing by intervening neutral hydrogen along the line of sight. Based on Meiksin (2006) prescriptions.

Parameters:
  • wavelength (array_like) – Observed-frame wavelength(s) in Angstroms.

  • redshift (float) – Source redshift. Must be strictly positive.

Returns:

IGM transmission factor T_IGM(λ) ∈ [0, 1]. Multiply SED by this to apply absorption: F_obs = F_int × T_IGM.

Return type:

array_like

Notes

Three opacity components contribute:

  1. Lyman series (Lyα, Lyβ, …): Discrete absorption features redshifted into spectrum. Each higher-order line has lower optical depth.

  2. Lyman continuum (λ < 912 Å rest): Strong blanketing blueward of Lyman limit. Creates sharp absorption edge at λ_obs = 912(1+z) Å.

  3. Lyman limit systems (LLS): Additional opacity from dense clouds with high HI column densities.

Total transmission: T = exp(-τ_Lyα - τ_Lyβ - … - τ_LC - τ_LLS)

At λ_obs < 912 Å (rest UV), transmission → 0 for z > 0. IGM becomes transparent at λ_obs > Lyα(1+z) ≈ 1216(1+z) Å.

The function is JIT-compiled for performance with JAX.

See also

sed_to_obse

Applies IGM transmission to rest-frame SEDs

Examples

>>> wave_obs = jnp.linspace(1000, 5000, 500)
>>> T_igm = igm_transmission(wave_obs, z=3.0)
>>> # Strong absorption blueward of Lyα at 1216*(1+3) = 4864 Å
>>> import matplotlib.pyplot as plt
>>> plt.plot(wave_obs, T_igm)
>>> plt.xlabel('Observed wavelength (Å)')
>>> plt.ylabel('IGM transmission')

References

galfits.sed_interp.jccm89(x, Av, Rv)
galfits.sed_interp.kpc_per_arcsec(z)[source]

Compute physical scale at redshift z.

Returns the angular scale (kpc per arcsec) for flat ΛCDM cosmology.

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Physical scale in kpc per arcsecond.

Return type:

float or array_like

Examples

>>> scale = kpc_per_arcsec(2.0)
>>> print(f"At z=2: 1 arcsec = {scale:.2f} kpc")
galfits.sed_interp.logSFR_to_f_cont(logSFR, logM, present_age=13.8, SFH='conti')[source]
galfits.sed_interp.luminosity_distance(z)[source]

Compute luminosity distance at redshift z.

Uses pre-computed lookup table for flat ΛCDM cosmology (H0=70, Ωm=0.3).

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Luminosity distance in Mpc.

Return type:

float or array_like

Examples

>>> dL = luminosity_distance(2.0)
>>> print(f"Luminosity distance at z=2: {dL:.1f} Mpc")
galfits.sed_interp.mycigale(wavelength, amplitude)[source]

Calzetti et al. (2000) attenuation curve with UV bump.

Implements the Calzetti+ (2000) and Leitherer+ (2002) starburst attenuation law with optional UV bump feature (2175 Å bump).

Parameters:
  • wavelength (array_like) – Wavelength array in Angstroms.

  • amplitude (float) – Amplitude of the UV bump (2175 Å feature). amplitude = 0: no bump (pure Calzetti curve) amplitude = 3: typical value for Milky Way-like bump

Returns:

Attenuation curve k(λ) where A(λ) = k(λ) × E(B-V). To apply: F_obs = F_int × 10^(-A(λ)/2.5).

Return type:

array_like

Notes

The Calzetti law applies to starburst galaxies where dust is mixed with stars. It differs from Galactic extinction curves (CCM, RV=3.1):

  • Grayer (flatter) in UV/optical

  • No 2175 Å bump by default (added optionally here)

  • Normalized to E(B-V) of stellar continuum

Wavelength ranges:

  • λ < 180 nm: Leitherer+ (2002) extrapolation

  • 180-630 nm: Calzetti+ (2000) law (optical/UV)

  • λ > 630 nm: Calzetti+ (2000) law (NIR)

The UV bump is parameterized as Drude profile centered at 2175 Å with FWHM = 350 Å.

See also

calzetti2000

Base Calzetti curve without bump

ccm89

Galactic extinction curve (for Milky Way foreground)

Examples

>>> wave = jnp.linspace(1000, 10000, 1000)
>>> # No UV bump (pure Calzetti)
>>> k_cal = mycigale(wave, amplitude=0)
>>> # With UV bump
>>> k_bump = mycigale(wave, amplitude=3)
>>> # Apply to SED with E(B-V) = 0.5
>>> ebv = 0.5
>>> flux_atten = flux_int * 10**(-k_bump * ebv / 2.5)

References

galfits.sed_interp.nearest_neighbors_jax(X, point)[source]
galfits.sed_interp.read_table_model(table_path, param_names, prefix)[source]

Factory function to create TableModel instance.

Convenience wrapper for TableModel initialization.

Parameters:
  • table_path (str) – Path to .npz file containing SED table.

  • param_names (list of str) – Parameter names to interpolate.

  • prefix (str) – Prefix for parameter names.

Returns:

Initialized table model ready for interpolation.

Return type:

TableModel

Examples

>>> model = read_table_model('templates/custom.npz',
...                          ['age', 'Z', 'Av'], prefix='host')
galfits.sed_interp.sed_to_obse(x, y, z, ebv)[source]

Transform rest-frame SED to observed frame with IGM and Galactic extinction.

Applies cosmological redshift, IGM absorption (Meiksin 2006), and Milky Way foreground extinction (CCM89).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • y (array_like) – Rest-frame spectral luminosity density in 10^38 erg/s/Å.

  • z (float) – Source redshift.

  • ebv (float) – Milky Way E(B-V) color excess in magnitudes.

Returns:

  • xnew (array_like) – Observed-frame wavelength in Angstroms: x_obs = x_rest × (1 + z).

  • ynew (array_like) – Observed-frame spectral luminosity density in 10^38 erg/s/Å. Includes (1+z)^-3 cosmological dimming factor.

Notes

Transformation steps:

  1. Redshift wavelength: λ_obs = λ_rest × (1 + z)

  2. Apply IGM absorption: L_obs *= T_IGM(λ_obs, z)

  3. Apply (1+z)^-3 cosmological dimming

  4. Apply Galactic extinction: L_obs *= 10^(-A_λ/2.5)

The IGM transmission T_IGM accounts for Lyman series absorption and Lyman continuum opacity from intervening neutral hydrogen.

See also

sed_to_rest

Inverse transformation (observed → rest frame)

igm_transmission

IGM absorption implementation

ccm89

Galactic extinction curve

Examples

>>> wave_rest = jnp.logspace(2, 4, 500)
>>> sed_rest = get_AGN_SED(wave_rest, 8.0, -0.5, 0.7, 1e38)
>>> wave_obs, sed_obs = sed_to_obse(wave_rest, sed_rest, z=2.0, ebv=0.05)
galfits.sed_interp.sed_to_rest(x, y, z, ebv)[source]

Convert observed frame SED to restframe, applying IGM and MW local extinction x: wavelength in observed frame y: L_38 in observed frame z: redshift ebv: Milky Way E(B-V)

Returns: xnew: wavelength in restframe ynew: L_38 in restframe

galfits.sed_interp.spowerlaw(x, A, C)[source]
galfits.sed_interp.starburst_disk(x, logM, logMdot, amax)[source]

SED Interpolation Functions

Stellar Populations

galfits.sed_interp.get_host_SED(x, logM, f_cont, age, Z, Av, C_unit, SFH='conti', present_age=13.8, delta=3.0)[source]

Interpolate stellar population SED with composite star formation history.

Generates rest-frame SED by combining continuum star formation and instantaneous burst components using BC03 templates. Supports multiple SFH models (continuous, burst, or binned).

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms [91, 1.6e6].

  • logM (float) – Log10 of total stellar mass in solar masses.

  • f_cont (float or array_like) – Fraction of mass in continuous star formation component. For ‘bins’ SFH: array of log10(mass fraction) per bin. For ‘conti’/’burst’: scalar in range [log10(1e-6), 0].

  • age (float or array_like) – For ‘conti’/’burst’: Age of burst component in Gyr [1e-5, 13.69]. For ‘bins’: Array of bin edges in Gyr.

  • Z (float) – Metallicity (mass fraction, not [Z/H]). Range [0.001, 0.04]. Z_solar = 0.02.

  • Av (float) – V-band attenuation in magnitudes.

  • C_unit (float) – Normalization constant (typically 10^38 for erg/s units).

  • SFH ({'conti', 'burst', 'bins'}, optional) –

    Star formation history model (default: ‘conti’).

    • ’conti’: Continuous SF + recent burst

    • ’burst’: τ-model with exponential decline

    • ’bins’: Custom binned SFH

  • present_age (float, optional) – Current age of universe in Gyr (default: 13.8).

  • delta (float, optional) – UV slope modification for attenuation curve (default: 3.0).

Returns:

Rest-frame spectral luminosity density L_λ in units of C_unit (typically 10^38 erg/s/Å).

Return type:

array_like

Notes

  • Continuum template normalized to SFR = 10 M_sun/yr

  • Instantaneous burst template normalized to M_* = 10^7 M_sun

  • Uses Calzetti+ attenuation curve with UV bump

  • BC03 templates cover ages from 10 kyr to ~13.7 Gyr

For ‘bins’ SFH, mass fractions are internally normalized to sum to unity.

See also

get_host_SED_3D

High-resolution version with velocity dispersion

get_host_SED_withL

Version that also returns absorbed luminosity

mycigale

Attenuation curve implementation

Examples

>>> wave = jnp.logspace(2, 5, 1000)  # 100 Å to 100 μm
>>> sed = get_host_SED(wave, logM=10.5, f_cont=-1.0, age=0.1,
...                    Z=0.02, Av=1.0, C_unit=1e38, SFH='conti')
galfits.sed_interp.get_host_SED_3D(x, logM, f_cont, age, Z, Av, sigma, C_unit, wave_temp, SFH='conti', present_age=13.8, delta=3.0)[source]
galfits.sed_interp.get_host_SED_withL(x, logM, f_cont, age, Z, Av, C_unit, SFH='conti', present_age=13.8, delta=3.0)[source]

AGN Components

galfits.sed_interp.get_AGN_SED(x, logM, logMdot, spin, C_unit)[source]

Interpolate AGN accretion disk SED for given black hole parameters.

Uses pre-computed thin disk models (Shakura-Sunyaev) with relativistic ray-tracing corrections for spinning black holes.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms [125, 24700].

  • logM (float) – Log10 of black hole mass in solar masses. Range [5, 10].

  • logMdot (float) – Log10 of accretion rate in Eddington units. Range [-4, 2]. Mdot_Edd = L_Edd / (η c^2).

  • spin (float) – Dimensionless black hole spin parameter (0 = Schwarzschild, 0.998 = maximal). Range [0, 0.99].

  • C_unit (float) – Normalization constant (typically 10^38 for erg/s units).

Returns:

Rest-frame AGN spectral luminosity density L_λ in units of C_unit (typically 10^38 erg/s/Å).

Return type:

array_like

Notes

  • Templates assume standard thin disk with Novikov-Thorne efficiency

  • Includes relativistic Doppler boosting and gravitational redshift

  • Higher spin → more luminous at fixed Mdot (higher efficiency)

  • Includes color correction for disk atmosphere

  • Valid for radiatively efficient accretion (Mdot/Mdot_Edd > 0.01)

See also

starburst_disk

Alternative starburst-heated disk model

cat3Dtorus

AGN torus emission component

Examples

>>> wave = jnp.logspace(2, 4.4, 500)  # 100 Å to 25000 Å
>>> agn_sed = get_AGN_SED(wave, logM=8.0, logMdot=-0.5, spin=0.7, C_unit=1e38)

References

galfits.sed_interp.starburst_disk(x, logM, logMdot, amax)[source]
galfits.sed_interp.cat3Dtorus(x, L38, a, h, N0, i)[source]

Interpolate AGN torus emission SED using CAT3D models.

Uses nearest-neighbor lookup in pre-computed grid of clumpy torus radiative transfer models (Hoenig & Kishimoto 2017).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • L38 (float) – Normalization luminosity in units of 10^38 erg/s.

  • a (float) – Radial density power-law index. Typical range [0, -2]. ρ ∝ r^a where r is distance from center.

  • h (float) – Scale height (ratio of torus height to radius at inner edge). Range [0.1, 1.0]. Larger h = more extended vertically.

  • N0 (float) – Average number of clouds along equatorial ray. Range [1, 15]. Controls optical depth (more clouds = higher τ).

  • i (float) – Inclination angle in degrees [0, 90]. i = 0: face-on (Type 1) i = 90: edge-on (Type 2)

Returns:

Torus emission spectral luminosity density in 10^38 erg/s/Å. Valid wavelength range: 1-100 μm (returns 0 outside).

Return type:

array_like

Notes

  • CAT3D models include clumpiness, 3D radiative transfer, anisotropy

  • Torus heated by central AGN UV/optical emission

  • Re-emits in near-to-far IR (peak around 10-30 μm)

  • Type 1/2 viewing angle dependence built into models

  • Uses nearest-neighbor interpolation (not smooth interpolation)

The torus provides obscuration and IR re-emission in AGN unified model.

See also

get_AGN_SED

AGN accretion disk emission

get_cold_dust_sed

Extended cold dust emission

Examples

>>> wave = jnp.logspace(4, 5, 100)  # 1-10 μm
>>> # Type 1 (face-on) torus
>>> torus_sed = cat3Dtorus(wave, L38=1000, a=-0.5, h=0.5, N0=10, i=30)

References

galfits.sed_interp.FeII(x, A_uv, A_op, dcen, fwhm)[source]

Generate optical/UV FeII emission template for AGN.

Constructs iron emission spectrum using empirical templates with independent UV and optical normalization. Applies velocity broadening and Doppler shift.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • A_uv (float) – Amplitude of UV FeII template (λ < 3500 Å).

  • A_op (float) – Amplitude of optical FeII template (λ > 3500 Å).

  • dcen (float) – Velocity offset in km/s (positive = redshift).

  • fwhm (float) – Full-width at half-maximum velocity width in km/s. Intrinsic template FWHM = 900 km/s is deconvolved.

Returns:

FeII emission flux (arbitrary normalization).

Return type:

array_like

Notes

FeII emission arises from collisionally excited iron in the AGN broad-line region. It creates broad pseudo-continuum with thousands of blended transitions, especially prominent at:

  • UV: 2200-3200 Å (FeII multiplet 191)

  • Optical: 4400-5500 Å (FeII multiplets around Hβ)

Templates are empirical from composite quasar spectra. The UV and optical components scale independently, reflecting different excitation conditions.

Convolution is performed in log-wavelength space for uniform velocity resolution. The 900 km/s intrinsic width is quadratically subtracted before applying user-specified FWHM.

See also

BaC

Balmer continuum emission

get_AGN_SED

AGN accretion disk continuum

Examples

>>> wave = jnp.linspace(4000, 5500, 1000)
>>> # Moderate FeII with 3000 km/s FWHM
>>> feii = FeII(wave, A_uv=1.0, A_op=1.0, dcen=0, fwhm=3000)

References

Templates from Vestergaard & Wilkes 2001, ApJS, 134, 1

galfits.sed_interp.BaC(x, logL3600, logM, logMdot, spin, dcen, fwhm)[source]

Generate Balmer continuum emission from AGN broad-line region.

Computes BLR Balmer continuum using pre-computed templates that include high-order Balmer recombination edges (Balmer jump at 3646 Å plus higher-order series). Applies velocity broadening and Doppler shift.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • logL3600 (float) – Log10 of continuum luminosity at 3600 Å in 10^38 erg/s/Å. Used for normalization.

  • logM (float) – Log10 of black hole mass in solar masses [5, 10].

  • logMdot (float) – Log10 of accretion rate in Eddington units [-4, 2].

  • spin (float) – Black hole spin parameter [0, 0.99].

  • dcen (float) – Velocity offset in km/s (positive = redshift).

  • fwhm (float) – Full-width at half-maximum velocity width in km/s.

Returns:

Balmer continuum flux in 10^38 erg/s/Å.

Return type:

array_like

Notes

The Balmer continuum arises from recombination of hydrogen in the dense, ionized gas of the AGN broad-line region. Key features:

  • Balmer jump at 3646 Å (flux discontinuity)

  • Series of higher-order Balmer edges converging to Balmer limit

  • Contributes blue “pseudo-continuum” in optical spectra

  • Depends on BLR density, temperature, covering factor

Templates are computed from photoionization models and depend on black hole parameters through the ionizing continuum shape.

The function normalizes to luminosity at 3600 Å (common AGN reference point below Balmer jump).

See also

FeII

Iron emission template

get_AGN_SED

AGN disk continuum

Examples

>>> wave = jnp.linspace(3000, 5000, 1000)
>>> bac = BaC(wave, logL3600=3.0, logM=8.0, logMdot=-0.5,
...           spin=0.7, dcen=0, fwhm=5000)

Nebular Emission

galfits.sed_interp.get_nebular(x, Lha, logU, Z, Av, withline=True, delta=3.0)[source]

Interpolate nebular emission SED (continuum + lines).

Uses pre-computed CLOUDY photoionization models normalized to H-α luminosity. Includes both nebular continuum (free-free, free-bound, two-photon) and emission lines.

Parameters:
  • x (array_like) – Rest-frame wavelength grid in Angstroms.

  • Lha (float) – H-α luminosity in units of 10^38 erg/s.

  • logU (float) – Log10 of ionization parameter (ratio of ionizing photon to hydrogen density). Range typically [-4, -1].

  • Z (float) – Gas-phase metallicity (mass fraction). Range [0.001, 0.04]. Z_solar = 0.02.

  • Av (float) – V-band attenuation in magnitudes.

  • withline (bool, optional) – If True, include emission lines; if False, only continuum (default: True).

  • delta (float, optional) – UV slope modification for attenuation curve (default: 3.0).

Returns:

Nebular spectral luminosity density L_λ in 10^38 erg/s/Å.

Return type:

array_like

Notes

  • Normalization factor 1.87531 calibrated by fitting CLOUDY models

  • Nebular continuum includes free-free, free-bound, and two-photon emission

  • Line emission includes H, He recombination lines and metal forbidden lines

  • Uses Calzetti+ attenuation curve (dust internal to HII regions)

  • Templates assume plane-parallel geometry with constant density

The ionization parameter U = Q(H) / (4π r^2 n_H c) characterizes the ionizing photon flux relative to gas density.

See also

get_host_SED

Stellar population SED

mycigale

Attenuation curve

Examples

>>> wave = jnp.linspace(3000, 10000, 1000)
>>> # Get full nebular SED with lines
>>> neb_sed = get_nebular(wave, Lha=100, logU=-2.5, Z=0.02, Av=0.5)
>>> # Get only nebular continuum
>>> neb_cont = get_nebular(wave, Lha=100, logU=-2.5, Z=0.02, Av=0.5, withline=False)

References

Dust Emission

galfits.sed_interp.get_cold_dust_sed(x, logMdust, qpah, Umin, alpha, gamma)[source]

Interpolate dust emission SED using Draine & Li (2007) models.

Computes IR dust emission as combination of radiation fields with constant intensity (U_min) and power-law distribution (dM/dU ∝ U^-α).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • logMdust (float) – Log10 of dust mass in solar masses.

  • qpah (float) – PAH abundance parameter (percentage of dust mass in PAH grains). Range [0.47, 4.58]. Solar neighborhood: qpah ~ 3.5%.

  • Umin (float) – Minimum radiation field intensity (in units of Mathis field). Range [0.1, 25]. ISRF: U = 1.

  • alpha (float) – Power-law index for radiation field distribution dM/dU ∝ U^-α. Range [1.0, 3.0]. Typical: α ~ 2.

  • gamma (float) – Fraction of dust mass in power-law component. Range [0, 1]. gamma = 0: all dust at U_min (quiescent) gamma = 1: all dust in power-law (PDR-dominated)

Returns:

Dust emission spectral luminosity density in 10^38 erg/s/Å.

Return type:

array_like

Notes

Total SED is combination of two components:

  • Constant U: L_const = (1 - γ) × M_dust × ε(U_min)

  • Power-law U: L_power = γ × M_dust × ∫ ε(U) U^-α dU

where ε(U) is the emissivity per unit dust mass at radiation field U.

PAH emission dominates at λ < 20 μm (features at 3.3, 6.2, 7.7, 11.3 μm). Larger grains emit modified blackbody at λ > 50 μm.

See also

get_cold_dust_L

Total dust luminosity for same parameters

Examples

>>> wave = jnp.logspace(4, 6, 200)  # 1-100 μm
>>> dust_sed = get_cold_dust_sed(wave, logMdust=7.0, qpah=3.5,
...                              Umin=1.0, alpha=2.0, gamma=0.3)

References

galfits.sed_interp.get_cold_dust_L(qpah, Umin, alpha, gamma)[source]

Compute total dust luminosity for Draine & Li (2007) models.

Returns integrated IR luminosity (total power emitted) for given dust parameters, normalized to dust mass.

Parameters:
  • qpah (float or array_like) – PAH abundance parameter (percentage of dust mass in PAHs).

  • Umin (float) – Minimum radiation field intensity (Mathis field units).

  • alpha (float or array_like) – Power-law index for radiation field distribution.

  • gamma (float) – Fraction of dust mass in power-law component [0, 1].

Returns:

Log10 of total dust luminosity normalized to 10^38 erg/s per solar mass of dust: log10(L_dust / M_dust / 10^38).

Return type:

float or array_like

Notes

Total luminosity combines constant and power-law components:

L_tot = (1 - γ) × L(U_min) + γ × L(U_power)

where L(U) is the emissivity integrated over wavelength.

Used to convert dust mass to IR luminosity or vice versa.

See also

get_cold_dust_sed

Full SED for same parameters

Examples

>>> logL_per_Msun = get_cold_dust_L(qpah=3.5, Umin=1.0, alpha=2.0, gamma=0.3)
>>> # Total IR luminosity for 10^7 Msun of dust
>>> logMdust = 7.0
>>> logL_IR = logL_per_Msun + logMdust

Stellar SEDs

galfits.sed_interp.get_stellar_sed(x, L38, Teff, logg, logZ)[source]

Coordinate Transformations

galfits.sed_interp.sed_to_obse(x, y, z, ebv)[source]

Transform rest-frame SED to observed frame with IGM and Galactic extinction.

Applies cosmological redshift, IGM absorption (Meiksin 2006), and Milky Way foreground extinction (CCM89).

Parameters:
  • x (array_like) – Rest-frame wavelength in Angstroms.

  • y (array_like) – Rest-frame spectral luminosity density in 10^38 erg/s/Å.

  • z (float) – Source redshift.

  • ebv (float) – Milky Way E(B-V) color excess in magnitudes.

Returns:

  • xnew (array_like) – Observed-frame wavelength in Angstroms: x_obs = x_rest × (1 + z).

  • ynew (array_like) – Observed-frame spectral luminosity density in 10^38 erg/s/Å. Includes (1+z)^-3 cosmological dimming factor.

Notes

Transformation steps:

  1. Redshift wavelength: λ_obs = λ_rest × (1 + z)

  2. Apply IGM absorption: L_obs *= T_IGM(λ_obs, z)

  3. Apply (1+z)^-3 cosmological dimming

  4. Apply Galactic extinction: L_obs *= 10^(-A_λ/2.5)

The IGM transmission T_IGM accounts for Lyman series absorption and Lyman continuum opacity from intervening neutral hydrogen.

See also

sed_to_rest

Inverse transformation (observed → rest frame)

igm_transmission

IGM absorption implementation

ccm89

Galactic extinction curve

Examples

>>> wave_rest = jnp.logspace(2, 4, 500)
>>> sed_rest = get_AGN_SED(wave_rest, 8.0, -0.5, 0.7, 1e38)
>>> wave_obs, sed_obs = sed_to_obse(wave_rest, sed_rest, z=2.0, ebv=0.05)
galfits.sed_interp.sed_to_rest(x, y, z, ebv)[source]

Convert observed frame SED to restframe, applying IGM and MW local extinction x: wavelength in observed frame y: L_38 in observed frame z: redshift ebv: Milky Way E(B-V)

Returns: xnew: wavelength in restframe ynew: L_38 in restframe

Cosmology

galfits.sed_interp.luminosity_distance(z)[source]

Compute luminosity distance at redshift z.

Uses pre-computed lookup table for flat ΛCDM cosmology (H0=70, Ωm=0.3).

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Luminosity distance in Mpc.

Return type:

float or array_like

Examples

>>> dL = luminosity_distance(2.0)
>>> print(f"Luminosity distance at z=2: {dL:.1f} Mpc")
galfits.sed_interp.kpc_per_arcsec(z)[source]

Compute physical scale at redshift z.

Returns the angular scale (kpc per arcsec) for flat ΛCDM cosmology.

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Physical scale in kpc per arcsecond.

Return type:

float or array_like

Examples

>>> scale = kpc_per_arcsec(2.0)
>>> print(f"At z=2: 1 arcsec = {scale:.2f} kpc")
galfits.sed_interp.cosmo_age(z)[source]

Compute age of universe at redshift z.

Uses pre-computed lookup table for flat ΛCDM cosmology (H0=70, Ωm=0.3).

Parameters:

z (float or array_like) – Redshift value(s).

Returns:

Age of universe in Gyr.

Return type:

float or array_like

Examples

>>> age = cosmo_age(2.0)
>>> print(f"Universe age at z=2: {age:.2f} Gyr")

Spectral Processing

galfits.sed_interp.conv_spec(wave, flux, sigma, dcenlog=0, Nlogv=2000)[source]

Convolve spectrum with Gaussian velocity kernel.

Performs convolution in log-wavelength space to model velocity dispersion and radial velocity shifts. JIT-compiled for performance.

Parameters:
  • wave (array_like) – Wavelength array in Angstroms.

  • flux (array_like) – Flux array (same length as wave).

  • sigma (float) – Velocity dispersion in km/s (1-sigma width of Gaussian kernel).

  • dcenlog (float, optional) – Velocity offset in km/s (positive = redshift, default: 0).

  • Nlogv (int, optional) – Number of points in log-wavelength interpolation grid (default: 2000). Higher = more accurate but slower.

Returns:

Convolved flux array at original wavelength grid.

Return type:

array_like

Notes

Algorithm:

  1. Convert wavelength to log(λ) for uniform velocity spacing

  2. Interpolate flux onto regular log-wavelength grid

  3. Convolve with Gaussian kernel: K(v) ∝ exp(-v²/2σ²)

  4. Shift by dcenlog (applies Doppler formula)

  5. Interpolate back to original wavelength grid

Edge effects are handled by extending flux with constant values (100 pixels on each side).

The Gaussian kernel in log-wavelength is equivalent to velocity-space convolution: Δv/c = Δ(ln λ).

See also

get_host_SED_3D

Uses this for velocity dispersion in stellar SEDs

Examples

>>> wave = jnp.linspace(5000, 5500, 1000)
>>> flux = jnp.ones_like(wave)
>>> flux = flux.at[500].set(10)  # Emission line
>>> # Broaden line by 200 km/s dispersion
>>> flux_conv = conv_spec(wave, flux, sigma=200)
>>> # Also apply +500 km/s redshift
>>> flux_shifted = conv_spec(wave, flux, sigma=200, dcenlog=500)

Attenuation Curves

galfits.sed_interp.mycigale(wavelength, amplitude)[source]

Calzetti et al. (2000) attenuation curve with UV bump.

Implements the Calzetti+ (2000) and Leitherer+ (2002) starburst attenuation law with optional UV bump feature (2175 Å bump).

Parameters:
  • wavelength (array_like) – Wavelength array in Angstroms.

  • amplitude (float) – Amplitude of the UV bump (2175 Å feature). amplitude = 0: no bump (pure Calzetti curve) amplitude = 3: typical value for Milky Way-like bump

Returns:

Attenuation curve k(λ) where A(λ) = k(λ) × E(B-V). To apply: F_obs = F_int × 10^(-A(λ)/2.5).

Return type:

array_like

Notes

The Calzetti law applies to starburst galaxies where dust is mixed with stars. It differs from Galactic extinction curves (CCM, RV=3.1):

  • Grayer (flatter) in UV/optical

  • No 2175 Å bump by default (added optionally here)

  • Normalized to E(B-V) of stellar continuum

Wavelength ranges:

  • λ < 180 nm: Leitherer+ (2002) extrapolation

  • 180-630 nm: Calzetti+ (2000) law (optical/UV)

  • λ > 630 nm: Calzetti+ (2000) law (NIR)

The UV bump is parameterized as Drude profile centered at 2175 Å with FWHM = 350 Å.

See also

calzetti2000

Base Calzetti curve without bump

ccm89

Galactic extinction curve (for Milky Way foreground)

Examples

>>> wave = jnp.linspace(1000, 10000, 1000)
>>> # No UV bump (pure Calzetti)
>>> k_cal = mycigale(wave, amplitude=0)
>>> # With UV bump
>>> k_bump = mycigale(wave, amplitude=3)
>>> # Apply to SED with E(B-V) = 0.5
>>> ebv = 0.5
>>> flux_atten = flux_int * 10**(-k_bump * ebv / 2.5)

References

galfits.sed_interp.cigale(wavelength, delta, amplitude)[source]
galfits.sed_interp.calzetti2000(wavelength)[source]

Compute the Calzetti et al. (2000) A(λ)/E(B-V)∗

Given a wavelength grid, this function computes the selective attenuation A(λ)/E(B-V)∗ using the formula from Calzetti at al. (2000) and Leitherer et al. (2002). The formula is given for wavelengths between 91.2 nm and 2200 nm, but this function makes the computation outside.

Parameters:

wavelength (array of floats) – Wavelength grid in angstrom but converted to nm in the function.

Return type:

a numpy array of floats

galfits.sed_interp.ccm89(x, Av, Rv)[source]

IGM Absorption

galfits.sed_interp.igm_transmission(wavelength, redshift)[source]

Compute intergalactic medium (IGM) transmission.

Calculates wavelength-dependent IGM opacity from Lyman series absorption and Lyman continuum blanketing by intervening neutral hydrogen along the line of sight. Based on Meiksin (2006) prescriptions.

Parameters:
  • wavelength (array_like) – Observed-frame wavelength(s) in Angstroms.

  • redshift (float) – Source redshift. Must be strictly positive.

Returns:

IGM transmission factor T_IGM(λ) ∈ [0, 1]. Multiply SED by this to apply absorption: F_obs = F_int × T_IGM.

Return type:

array_like

Notes

Three opacity components contribute:

  1. Lyman series (Lyα, Lyβ, …): Discrete absorption features redshifted into spectrum. Each higher-order line has lower optical depth.

  2. Lyman continuum (λ < 912 Å rest): Strong blanketing blueward of Lyman limit. Creates sharp absorption edge at λ_obs = 912(1+z) Å.

  3. Lyman limit systems (LLS): Additional opacity from dense clouds with high HI column densities.

Total transmission: T = exp(-τ_Lyα - τ_Lyβ - … - τ_LC - τ_LLS)

At λ_obs < 912 Å (rest UV), transmission → 0 for z > 0. IGM becomes transparent at λ_obs > Lyα(1+z) ≈ 1216(1+z) Å.

The function is JIT-compiled for performance with JAX.

See also

sed_to_obse

Applies IGM transmission to rest-frame SEDs

Examples

>>> wave_obs = jnp.linspace(1000, 5000, 500)
>>> T_igm = igm_transmission(wave_obs, z=3.0)
>>> # Strong absorption blueward of Lyα at 1216*(1+3) = 4864 Å
>>> import matplotlib.pyplot as plt
>>> plt.plot(wave_obs, T_igm)
>>> plt.xlabel('Observed wavelength (Å)')
>>> plt.ylabel('IGM transmission')

References

Star Formation History

galfits.sed_interp.f_cont_to_logSFR(f_cont, logM, age, present_age=13.8, SFH='conti')[source]

Convert continuum fraction to instantaneous star formation rate.

Derives contemporary SFR from the mass fraction in continuous star formation component for composite SFH models.

Parameters:
  • f_cont (float or array_like) – Log10 of mass fraction in continuous SF component. For ‘bins’: array of log10 mass fractions per bin.

  • logM (float) – Log10 of total stellar mass in solar masses.

  • age (float or array_like) – For ‘conti’/’burst’: age of burst in Gyr. For ‘bins’: array of bin edges in Gyr.

  • present_age (float, optional) – Current age of universe in Gyr (default: 13.8).

  • SFH ({'conti', 'burst', 'bins'}, optional) – Star formation history model (default: ‘conti’).

Returns:

Log10 of star formation rate in M_sun/yr.

Return type:

float

Notes

For ‘conti’ SFH:

SFR = M_cont / (t_present - 0.2 Gyr)

For ‘burst’ SFH:

SFR = M_cont / (0.1 Gyr) [τ-model timescale]

Also accounts for instantaneous burst component with smoothed error function to handle recent starbursts (< 100 Myr).

See also

logSFR_to_f_cont

Inverse transformation (SFR → f_cont)

get_host_SED

Uses f_cont to build SED

Examples

>>> # 10^10 Msun galaxy, 10% in continuous SF
>>> logSFR = f_cont_to_logSFR(f_cont=-1.0, logM=10.0, age=0.1, SFH='conti')
>>> print(f"SFR = {10**logSFR:.2f} Msun/yr")
galfits.sed_interp.logSFR_to_f_cont(logSFR, logM, present_age=13.8, SFH='conti')[source]

Table Models

class galfits.sed_interp.TableModel(table_path, param_names, prefix)[source]

Bases: object

Generic SED table model with multi-parameter interpolation.

Loads pre-computed SED grids from .npz files and provides fast interpolation for arbitrary parameter values. Supports optional normalization parameter for flexible scaling.

Parameters:
  • table_path (str) – Path to .npz file containing SED table. Must contain ‘sed’ (log10 L_λ), ‘wave’, and parameter grids.

  • param_names (list of str) – Parameter names to interpolate (must match keys in .npz file). If ‘logNorm’ is included, it will be used for normalization.

  • prefix (str) – Prefix to add to parameter names for external interface (e.g., ‘AGN’ → ‘AGN_spin’, ‘AGN_logM’).

norm

True if normalization parameter is present.

Type:

bool

norm_key

Name of normalization parameter (with prefix).

Type:

str

param_names

Parameter names without ‘logNorm’.

Type:

list of str

pnames

Display names with prefix applied.

Type:

list of str

intp_table_model

JAX interpolator for fast SED lookup.

Type:

RegularGridInterpolator

get_sed(pardict, x)[source]

Interpolate SED at given parameter values and wavelengths.

Notes

Table files (.npz) must contain:

  • ‘sed’: SED grid as log10(L_λ) in erg/s/Å (shape: [N_p1, N_p2, …, N_wave])

  • ‘wave’: Wavelength grid in Angstroms (1D array)

  • Parameter grids: 1D arrays for each parameter (e.g., ‘age’, ‘Z’, ‘logM’)

If ‘logNorm’ parameter is included, SEDs are scaled by 10^logNorm during interpolation, allowing flexible normalization.

The class uses JAX’s RegularGridInterpolator for GPU-accelerated interpolation with automatic differentiation support.

Examples

>>> # Load custom AGN template table
>>> agn_model = TableModel('custom_agn.npz',
...                        param_names=['logM', 'logMdot', 'spin', 'logNorm'],
...                        prefix='AGN')
>>> # Interpolate at specific parameters
>>> params = {'AGN_logM': 8.0, 'AGN_logMdot': -0.5,
...           'AGN_spin': 0.7, 'AGN_logNorm': 44}
>>> wave = jnp.logspace(2, 5, 1000)
>>> sed = agn_model.get_sed(params, wave)

See also

get_AGN_SED

Specialized AGN disk interpolation

get_host_SED

Specialized stellar population interpolation

get_sed(allparams, norm_key)[source]

Interpolate SED at given parameters and wavelengths.

Parameters:
  • pardict (dict) – Dictionary mapping parameter names (with prefix) to values. Must include all parameters in self.param_names. If self.norm=True, must also include normalization parameter.

  • x (array_like) – Wavelength grid in Angstroms for interpolation.

Returns:

Interpolated SED normalized to L5100 = 1. Output in units of 10^38 erg/s/Å.

Return type:

array_like

Examples

>>> params = {'prefix_param1': 1.0, 'prefix_param2': 2.0}
>>> wave = jnp.linspace(1000, 10000, 1000)
>>> sed = model.get_sed(params, wave)
load_table_model()[source]
galfits.sed_interp.read_table_model(table_path, param_names, prefix)[source]

Factory function to create TableModel instance.

Convenience wrapper for TableModel initialization.

Parameters:
  • table_path (str) – Path to .npz file containing SED table.

  • param_names (list of str) – Parameter names to interpolate.

  • prefix (str) – Prefix for parameter names.

Returns:

Initialized table model ready for interpolation.

Return type:

TableModel

Examples

>>> model = read_table_model('templates/custom.npz',
...                          ['age', 'Z', 'Av'], prefix='host')

Simple Models

galfits.sed_interp.spowerlaw(x, A, C)[source]
galfits.sed_interp.brokenpower(x, A, C1, C2)[source]
galfits.sed_interp.Bbody(x, Ltot, Teff)[source]

Helper Functions

galfits.sed_interp.gaussian_jax(x, peak, cen, wid)[source]
galfits.sed_interp.gaussianL_jax3D(x, norm, cen, wid)[source]
galfits.sed_interp.nearest_neighbors_jax(X, point)[source]