User Guide

This guide describes the main PST workflows beyond the quickstart examples. It focuses on the current package structure and on the parts of the library that are most useful when building composite stellar population models, synthetic observables, and parameterized galaxy SEDs.

For runnable notebooks, see Tutorials. For the full class and method reference, see API Reference.

Getting Oriented

PST is organized around a few core building blocks:

  • pst.SSP provides simple stellar population libraries and interpolation

    tools on age, metallicity, and wavelength grids.

  • pst.cem provides chemical evolution models that map a star-formation

    and enrichment history onto an SSP grid.

  • pst.sed provides reusable SED components, including a stellar

    component built from an SSP plus a CEM.

  • pst.galaxy combines stellar emission, attenuation, and dust emission

    into a single galaxy SED model.

  • pst.observables provides filters and equivalent-width measurements.

  • pst.model provides the pst.model.Parameter and

    pst.model.ModelBase infrastructure used by the parameterized models.

Throughout PST, time arguments in chemical evolution models refer to cosmic time since the Big Bang, not lookback time. This is important when mixing analytic histories, tabulated histories, and redshift-dependent galaxy models.

Working with SSP Libraries

The backbone of the library is pst.SSP.SSPBase, which stores a grid of stellar population spectra sampled in metallicity, age, and wavelength.

Loading an SSP Library

PST includes interfaces to several commonly used libraries, such as PopStar, BC03, XSL, and EMILES.

from astropy import units as u
from pst.SSP import PopStar

ssp = PopStar(IMF="cha")

Once loaded, an SSP object exposes its main grids and metadata:

  • ssp.ages: age grid.

  • ssp.metallicities: metallicity grid.

  • ssp.wavelength: wavelength grid.

  • ssp.L_lambda: tabulated SSP spectra.

  • ssp.name, ssp.imf, ssp.isochrone, ssp.stellar_library.

Interpolating SSP Weights and Spectra

PST uses interpolation in age and metallicity space to map arbitrary stellar populations onto a discrete SSP library.

weights = ssp.get_weights(
        ages=[1e8, 5e8, 2e9] * u.yr,
        metallicities=[0.004, 0.008, 0.02],
        masses=[1e7, 2e7, 5e7] * u.Msun,
)

This is the basic operation used internally by the chemical evolution models, but it is also useful for custom population mixtures or particle-based inputs.

For wavelength-domain operations, you can trim or reinterpolate the spectral grid before further analysis:

ssp.cut_wavelength(wl_min=3000 * u.angstrom, wl_max=9000 * u.angstrom)
ssp.interpolate_sed(new_wavelength_grid)

Regridding in Age and Metallicity

If you need to align an SSP library with another model grid, you can regrid the library in age and metallicity.

import numpy as np

new_ages = np.geomspace(1e6, 1.3e10, 60) * u.yr
new_metallicities = np.array([0.0004, 0.004, 0.008, 0.02, 0.05])
ssp.regrid(new_ages, new_metallicities)

Derived SSP Quantities

PST SSP objects can store more than spectra. Depending on the library, you may also have access to derived quantities such as:

  • ssp.current_mass for surviving stellar mass fractions.

  • ssp.remnant_mass_frac and ssp.returned_mass_frac.

  • ssp.supernova_rate.

  • ssp.log_ionising_HI_photons, ssp.log_ionising_HeI_photons, ssp.log_ionising_HeII_photons.

These tabulated quantities are used by CEM methods such as surviving_stellar_mass, supernova_rate, and ionising-photon rate estimators.

Precomputing Synthetic Photometry

Broadband photometry can be tabulated directly on the SSP grid and reused later by a CEM.

from pst.observables import Filter

g_band = Filter.from_svo("SLOAN_SDSS.g")
r_band = Filter.from_svo("SLOAN_SDSS.r")
ssp.compute_photometry([g_band, r_band], z_obs=0.0)

The resulting ssp.photometry grid can then be combined with any compatible chemical evolution model through pst.cem.ChemicalEvolutionModel.compute_photometry().

Building Chemical Evolution Models

The base interface is pst.cem.ChemicalEvolutionModel. Subclasses define two histories as functions of cosmic time:

  • cumulative formed stellar mass, stellar_mass_formed(t)

  • gas-phase metallicity, ism_metallicity(t)

Analytic CEMs

Analytic histories are useful for quick experiments, forward modeling, and parameter studies.

from astropy import units as u
from pst.cem import ExponentialDelayedCEM

cem = ExponentialDelayedCEM(
        mass_today=1e10 * u.Msun,
        today=13.7 * u.Gyr,
        tau=3.0 * u.Gyr,
        ism_metallicity_today=0.02,
)

Once defined, a CEM can be queried directly:

cosmic_time = [1.0, 3.0, 10.0] * u.Gyr
formed_mass = cem.stellar_mass_formed(cosmic_time)
metallicity = cem.ism_metallicity(cosmic_time)

Synthesizing Composite Stellar Populations

The main bridge between a CEM and an SSP library is pst.cem.ChemicalEvolutionModel.interpolate_ssp_masses(), which computes the mass weights assigned to each SSP age-metallicity bin at a given observing time.

weights = cem.interpolate_ssp_masses(ssp, t_obs=13.7 * u.Gyr)
sed = cem.compute_SED(ssp, t_obs=13.7 * u.Gyr)

From the same combination, PST can derive additional integrated quantities:

surviving_mass = cem.surviving_stellar_mass(ssp, 13.7 * u.Gyr)
mean_age = cem.mean_stellar_age(ssp, 13.7 * u.Gyr, log=True)
photometry = cem.compute_photometry(ssp, 13.7 * u.Gyr)

Caching and Repeated Evaluations

The CEM layer can cache the output of interpolate_ssp_masses to accelerate repeated evaluations at the same observing time.

cem = ExponentialDelayedCEM(
        mass_today=1e10 * u.Msun,
        today=13.7 * u.Gyr,
        tau=3.0 * u.Gyr,
        ism_metallicity_today=0.02,
        cache_interp_ssp_mass=True,
)

Warning

The cache key currently depends only on ssp.name and t_obs. It does not track other arguments that affect the interpolation, such as oversample_factor. If caching is enabled, keep those inputs fixed across repeated calls.

Tabular and Particle-Based Histories

PST also supports more complex inputs than closed-form SFHs.

These models are useful when connecting PST to simulations, non-parametric SFH inference, or external reconstruction pipelines.

import numpy as np
from pst.cem import TabularCEM

tabular = TabularCEM(
        times=np.array([0.1, 1.0, 3.0, 6.0, 13.7]) * u.Gyr,
        masses=np.array([0.0, 1e8, 5e9, 8e9, 1e10]) * u.Msun,
        metallicities=np.array([1e-4, 5e-4, 3e-3, 1e-2, 2e-2]),
        today=13.7 * u.Gyr,
)

SED Components and Galaxy Models

The pst.sed and pst.galaxy modules make it possible to build more structured spectral models than a bare SSP+CEM combination.

Stellar SED Components

pst.sed.StellarComponent wraps an SSP and a CEM into a reusable SED component.

from pst.sed import StellarComponent

stars = StellarComponent(ssp=ssp, sfh=cem)
stellar_sed = stars.emission_spectrum(ssp.wavelength, t_obs=13.7 * u.Gyr)

This is useful when a stellar population model is one component in a larger SED assembly that also includes attenuation and dust emission.

Dust Attenuation and Dust Emission

The dust module provides both attenuation laws and emission components.

When building galaxy models, attenuation and dust emission can be combined with the stellar component instead of being applied manually to a single spectrum.

Composite Galaxy SEDs

pst.galaxy.GalaxySED combines stellar emission, attenuation, and dust emission on a common wavelength grid.

from pst.dust import DustScreenAttenuation
from pst.galaxy import GalaxySED

galaxy = GalaxySED(
        stellar_model=stars,
        dust_attenuation_model=DustScreenAttenuation(),
        target_wavelength=ssp.wavelength,
        redshift=0.05,
)

rest_sed = galaxy.emission_spectrum()
obs_sed = galaxy.emission_spectrum(to_obs_frame=True)

This interface is the preferred entry point when you need a higher-level model that can later be connected to samplers, fitters, or observational pipelines.

Parameterized Workflows

PST model classes use pst.model.Parameter objects rather than bare scalars. This provides:

  • explicit units,

  • optional valid ranges,

  • support for fixed versus free parameters,

  • recursive parameter discovery across nested models.

You can inspect a model directly:

params = galaxy.parameters_recursive(include_fixed=False)
for name, par in params.items():
        print(name, par.q, par.fixed)

For nested galaxy models, pst.galaxy.GalaxySED also provides a cached parameter index and dotted-path updates.

galaxy.build_param_index(include_fixed=False)
galaxy.update_parameters(
        {
                "redshift": 0.1,
                "dust_attenuation.a_v": 0.4 * u.mag,
        },
        validate=True,
)

This pattern is particularly useful when PST is embedded in fitting frameworks or MCMC pipelines.

Observables and Measurements

Filters and Synthetic Photometry

Photometric filters are represented by pst.observables.Filter. Filters can be loaded from local files or fetched from the SVO service.

import numpy as np
from pst.observables import Filter

jwst_filter = Filter.from_svo("JWST_MIRI.F2550W")
jwst_filter.interpolate(ssp.wavelength)

sed_10pc = sed / (4 * np.pi * (10 * u.pc) ** 2)
ab_mag, ab_mag_err = jwst_filter.get_ab(sed_10pc)

Equivalent Width Measurements

pst.observables.EquivalentWidth measures line indices from a spectrum using a left pseudo-continuum window, a central feature window, and a right pseudo-continuum window.

from pst.observables import EquivalentWidth

hbeta = EquivalentWidth(
        left_wl_range=[4827.875, 4847.875],
        central_wl_range=[4847.875, 4876.625],
        right_wl_range=[4876.625, 4891.625],
)

ew, ew_err = hbeta.compute_ew(
        wavelength=ssp.wavelength,
        spectra=sed,
        spectra_err=0.01 * sed,
)

Equivalent-width measurements can be applied to both SSP spectra and composite galaxy spectra, which makes them convenient for model-data comparisons in mixed spectroscopic and photometric analyses.

Choosing a Workflow

The modules are designed to compose cleanly:

  1. Use pst.SSP when you only need stellar population libraries and SSP-level observables.

  2. Use pst.cem when you need to turn an SFH plus metallicity history into a composite population.

  3. Use pst.sed and pst.galaxy when you need structured SED models with attenuation, dust emission, redshift, and parameter management.

  4. Use pst.observables to derive photometric or spectroscopic measurements from any spectrum produced upstream.

For individual class signatures and full method documentation, refer to Simple Stellar Population Libraries, Parameterized Model Infrastructure, Chemical Evolution Models (CEM), Spectral Energy Distribution (SED) Components, Galaxy Assembly and Composite SEDs, Dust Attenuation and Emission, and Observables, Filters, and Spectral Indices.