Core Module (brutus.core)

brutus.core provides the stellar modeling and synthetic photometry infrastructure for individual stars and coeval stellar populations.

Key Components:

  • Individual Stars: EEPTracks predicts physical stellar parameters along evolutionary tracks, StarEvolTrack generates synthetic SEDs along tracks on the fly, and StarGrid evaluates pre-computed SED grids.

  • Populations: Isochrone interpolates coeval stellar populations, and StellarPop synthesizes single and binary population photometry.

  • Neural Networks: FastNN and FastNNPredictor evaluate neural network bolometric corrections across photometric passbands.

  • Grid Generation: GridGenerator builds pre-computed HDF5 model grids with linear reddening vectors for BruteForce.

Architecture:

  • Parameter Prediction (EEPTracks, Isochrone): Maps intrinsic stellar labels (initial mass, evolutionary phase or age, metallicity, alpha enhancement) to physical observables (effective temperature, luminosity, radius, surface gravity).

  • Photometry Synthesis (StarEvolTrack, StellarPop): Converts predicted physical observables into reddened broadband magnitudes and fluxes via FastNNPredictor.

Typical Usage Patterns:

For individual field stars with unknown evolutionary state:

from brutus.core import EEPTracks, StarEvolTrack

# Parameter prediction
tracks = EEPTracks()

# Photometry generation (on-the-fly)
star = StarEvolTrack(tracks=tracks, filters=['PS_g', 'PS_r', 'PS_i', 'PS_z'])
sed, params1, params2 = star.get_seds(
    mini=1.0, eep=400, feh=0.0,
    av=0.1, dist=1000.0
)

For large samples requiring speed:

from brutus.core import StarGrid
from brutus.data import load_models

# Load pre-computed grid
models, labels, label_mask = load_models('grid_mist_v9.h5')
grid = StarGrid(models, labels)

# Fast photometry lookup (no re-computation)
# Use with BruteForce fitter for thousands to millions of stars

For stellar clusters with shared age and metallicity:

from brutus.core import Isochrone, StellarPop

# Population parameter prediction
iso = Isochrone()

# Population photometry
pop = StellarPop(isochrone=iso)
seds, params1, params2 = pop.get_seds(
    feh=0.0, loga=9.0, av=0.5, dist=2000.0
)

See Also:

Individual Star Models

class brutus.core.EEPTracks(mistfile=None, predictions=['loga', 'logl', 'logt', 'logg', 'feh_surf', 'afe_surf'], ageweight=True, verbose=True, use_cache=True)[source]

Bases: object

Interpolate stellar parameters along MIST evolutionary tracks.

Predicts stellar parameters as a function of initial mass (mini), equivalent evolutionary point (eep), initial metallicity (feh), and initial alpha enhancement (afe). Pass an instance to StarEvolTrack to synthesize photometry.

Parameters:
  • mistfile (str, optional) – Path to the HDF5 file containing the evolutionary tracks. If not provided, MIST_1.2_EEPtrk.h5 is looked up in the brutus download directory (the Pooch cache, or $ASTRO_BRUTUS_DATA_DIR when set), then in data/DATAFILES in the repository.

  • predictions (iterable of str, optional) – The names of stellar parameters to predict, from ‘mass’, ‘feh_surf’, ‘afe_surf’, ‘loga’, ‘logt’, ‘logg’, ‘logl’ and ‘logr’. It must include ‘loga’, ‘logl’, ‘logt’ and ‘logg’. Default is: [“loga”, “logl”, “logt”, “logg”, “feh_surf”, “afe_surf”].

  • ageweight (bool, optional) – Whether to compute age weights d(age)/d(EEP) for age priors. Default is True.

  • verbose (bool, optional) – Whether to output progress messages during initialization. Default is True.

  • use_cache (bool, optional) – Whether to use pickle caching to speed up loading. If True, will save processed EEPTracks to a .pkl file for faster subsequent loads, and load from cache if available and newer than the original file. Default is True.

Raises:
  • ValueError – If predictions has an unknown name or lacks a required one.

  • FileNotFoundError – If the track file does not exist. brutus.data.fetch_tracks downloads it.

labels

Input parameter names: [‘mini’, ‘eep’, ‘feh’, ‘afe’]

Type:

list of str

predictions

Output column names of get_predictions: the requested predictions, then "agewt" when ageweight=True.

Type:

list of str

ndim, npred

Number of input dimensions and of requested predictions. npred does not count the appended "agewt" column.

Type:

int

interpolator

The main interpolation object for stellar parameter prediction

Type:

scipy.interpolate.RegularGridInterpolator

gridpoints

Unique grid points for each input parameter

Type:

dict

Examples

Predict parameters for a solar-mass star on the main sequence:

>>> tracks = EEPTracks()
>>> params = tracks.get_predictions([1.0, 350, 0.0, 0.0])  # mini, eep, feh, afe
>>> log_age = params[0]  # log10(age in years)
>>> log_teff = params[2]  # log10(effective temperature)
>>> print(f"Age: {10**log_age:.1e} yr, Teff: {10**log_teff:.0f} K")

Batch prediction for multiple stars:

>>> import numpy as np
>>> labels = np.array([[0.8, 350, -0.5, 0.2],   # Metal-poor dwarf
...                    [1.2, 454, 0.0, 0.0],    # Solar at turnoff
...                    [2.0, 500, 0.3, 0.0]])   # Massive metal-rich
>>> preds = tracks.get_predictions(labels)
>>> ages = 10**preds[:, 0]  # Convert to linear ages
__init__(mistfile=None, predictions=['loga', 'logl', 'logt', 'logg', 'feh_surf', 'afe_surf'], ageweight=True, verbose=True, use_cache=True)[source]
get_predictions(labels, apply_corr=True, corr_params=None)[source]

Generate stellar parameter predictions for given input parameters.

Parameters:
  • labels (array-like of shape (4,) or (Nobj, 4)) – Input parameters [mini, eep, feh, afe]: - mini: initial mass in solar masses (\(M_\odot\)). - eep: equivalent evolutionary point (dimensionless). - feh: initial metallicity [Fe/H] in dex. - afe: initial alpha enhancement [alpha/Fe] in dex.

  • apply_corr (bool, optional) – Whether to apply low-mass empirical corrections. Default is True.

  • corr_params (tuple of 4 floats, optional) – Correction parameters (dtdm, drdm, msto_smooth, feh_scale).

Returns:

preds – Predicted stellar parameters in the order listed in self.predictions (loga in log10(yr), logl in log10(\(L_\odot\)), logt in log10(K), logg in log10(cm/s^2), feh_surf and afe_surf in dex, mass in \(M_\odot\), logr in log10(\(R_\odot\)), and agewt in yr per EEP).

Return type:

numpy.ndarray of shape (Npred,) or (Nobj, Npred)

See also

get_corrections

Compute empirical corrections when apply_corr=True.

StarEvolTrack.get_seds

Generate synthetic photometry from track predictions.

Notes

When apply_corr=True, the empirical corrections shift logt by dlogt, logl by +2 * dlogr, and logg by -2 * dlogr. See get_corrections for why the luminosity shift omits the Stefan-Boltzmann 4 * dlogt term.

Examples

Single star prediction:

>>> tracks = EEPTracks()
>>> params = tracks.get_predictions([1.0, 350, 0.0, 0.0])
>>> log_age, log_L, log_Teff, log_g = params[:4]

Multiple star prediction:

>>> import numpy as np
>>> labels = np.array([[0.8, 350, -0.5, 0.2], [1.2, 454, 0.0, 0.0]])
>>> params = tracks.get_predictions(labels)
get_corrections(labels, corr_params=None)[source]

Compute empirical corrections to stellar parameters.

Applies empirical corrections to effective temperature and radius based on stellar mass, evolutionary phase (EEP), and metallicity. These corrections account for systematic offsets between MIST models and observations, particularly for low-mass stars.

Parameters:
  • labels (array-like of shape (4,) or (Nobj, 4)) – Input parameters [mini, eep, feh, afe] where: - mini: Initial mass in solar masses - eep: Equivalent evolutionary point - feh: Metallicity [Fe/H] - afe: Alpha enhancement [α/Fe]

  • corr_params (tuple of float, optional) – Correction parameters (dtdm, drdm, msto_smooth, feh_scale) where: - dtdm: Temperature correction slope with mass - drdm: Radius correction slope with mass - msto_smooth: Smoothing scale for main sequence turnoff transition - feh_scale: Metallicity scaling factor Default is (0.09, -0.09, 30.0, 0.5).

Returns:

corrs – Corrections to [log(Teff), log(R)]. These are added to the base predictions from the interpolator.

Return type:

numpy.ndarray of shape (2,) or (Nobj, 2)

Raises:

ValueError – If labels is not 1-D or 2-D, or corr_params does not have 4 entries.

See also

get_predictions

Applies these corrections to stellar parameters

Notes

Corrections are applied as:

\[\Delta \log T_{\rm eff} = f_{\rm EEP} \cdot f_{\rm [Fe/H]} \cdot \log(1 + \Delta M \cdot \alpha_T) \Delta \log R = f_{\rm EEP} \cdot f_{\rm [Fe/H]} \cdot \log(1 + \Delta M \cdot \alpha_R)\]

where \(\Delta M = M_{\rm ini} - 1.0\) and the EEP factor smoothly transitions from 1 on the main sequence to 0 after the main-sequence turnoff (EEP 454). Corrections are zero for stars with \(M_{\rm ini} \geq 1.0\,M_\odot\).

get_predictions applies these corrections as an effective calibrated map, shifting logt by dlogt, logl by +2 * dlogr, and logg by -2 * dlogr. The luminosity shift omits the 4 * dlogt term from the Stefan-Boltzmann law (\(L = 4\pi R^2 \sigma T^4\)) because the default corr_params were calibrated against observations using this parameterization.

class brutus.core.StarGrid(models, models_labels, models_params=None, filters=None, verbose=True)[source]

Bases: object

Interpolate stellar parameters and synthetic photometry from a pre-computed grid.

Evaluates stellar parameters and reddened SEDs by multi-linear or KD-tree interpolation over a pre-computed grid of magnitude coefficients and stellar labels.

The grid structure allows for irregular spacing in each dimension, with models indexed by their array location. Multi-linear interpolation is used to compute stellar parameters and photometry between grid points.

Parameters:
  • models (numpy.ndarray of shape (Nmodel, Nfilt, Ncoef) or dict) – Pre-computed model grid containing photometric coefficients. A dict must contain the ‘mag_coeffs’ key. Each model contains 3 coefficients per filter: - Unreddened magnitude - Reddening vector for R_V = 0 - Change in reddening vector as function of R_V

  • models_labels (structured numpy.ndarray of shape (Nmodel,)) – Labels for each model in the grid (e.g., mini, eep, feh, afe, smf).

  • models_params (structured numpy.ndarray of shape (Nmodel,), optional) – Additional parameters for each model (e.g., loga, logl, logt, logg). If not provided, these won’t be available in predictions.

  • filters (list of str, optional) – Filter names for photometry. For a structured models array, the filters to keep, in this order; names not in models are skipped with a warning. Otherwise, one name per filter of models. If None, uses all available filters from the models.

  • verbose (bool, optional) – Whether to print progress messages. Default is True.

nmodels

Number of models in the grid

Type:

int

nfilters

Number of filters

Type:

int

filters

Array of filter names

Type:

numpy.ndarray

labels

Grid labels (mini, eep, feh, etc.)

Type:

structured numpy.ndarray

params

Additional parameters if provided

Type:

structured numpy.ndarray or None

label_names

Names of available labels

Type:

list

param_names

Names of available parameters

Type:

list

Raises:

ValueError – If no requested filter is in a structured models array, if filters does not give one name per filter of models, or if a grid label has no finite value or no model has finite values for all of them.

Notes

Binary star support is currently limited. The smf parameter is accepted for API compatibility with StarEvolTrack, but full binary modeling requires a dedicated binary grid with pre-computed combined photometry. The current implementation returns empty placeholders for secondary parameters.

Examples

Load a pre-computed grid and generate photometry:

>>> from brutus.data import load_models
>>> models, labels, label_mask = load_models('grid_mist_v9.h5')
>>> grid = StarGrid(models, labels)
>>>
>>> # Get predictions for specific stellar parameters
>>> predictions = grid.get_predictions(mini=1.0, eep=350, feh=0.0)
>>>
>>> # Generate SED with extinction
>>> sed, params, params2 = grid.get_seds(
...     mini=1.0, eep=350, feh=0.0,
...     av=0.1, rv=3.3, dist=1000.0
... )
__init__(models, models_labels, models_params=None, filters=None, verbose=True)[source]

Initialize the StarGrid with model data.

get_predictions(mini=None, eep=None, feh=None, afe=None, smf=None, use_multilinear=True)[source]

Get stellar parameter predictions from the grid.

Interpolates grid models to estimate stellar parameters at the requested input values using multi-linear interpolation.

Parameters:
  • mini (float, optional) – Initial mass in solar masses (\(M_\odot\)).

  • eep (float, optional) – Equivalent evolutionary point (dimensionless).

  • feh (float, optional) – Initial metallicity [Fe/H] in dex.

  • afe (float, optional) – Initial alpha enhancement [alpha/Fe] in dex.

  • smf (float, optional) – Secondary mass fraction in [0, 1].

  • use_multilinear (bool, optional) – Whether to use multi-linear interpolation (True) or KD-tree inverse-distance interpolation (False). Default is True.

Returns:

predictions – Interpolated stellar parameters (or grid labels when models_params is absent) keyed by parameter name.

Return type:

dict of str to float

Raises:

ValueError – If a grid dimension with more than one value is omitted, or if a given grid label is not finite or lies outside its axis range (with a relative tolerance of 1e-6 at the edges). Single-valued dimensions may be omitted and take their only value.

Warns:

UserWarning – If a label is given that the grid does not have. It is ignored.

See also

get_seds

Generate photometry along with parameter predictions

_find_neighbors_multilinear

Multi-linear interpolation method

_find_neighbors_kdtree

KD-tree nearest neighbor method

Examples

>>> grid = StarGrid(models, labels, params)
>>> preds = grid.get_predictions(mini=1.0, eep=350, feh=0.0)
>>> print(f"log(age) = {preds['loga']:.2f}")
>>> print(f"log(L) = {preds['logl']:.2f}")
get_seds(mini=None, eep=None, feh=None, afe=None, av=0.0, rv=3.3, smf=None, dist=1000.0, return_dict=True, return_flux=False, return_predictions=True, use_multilinear=True)[source]

Generate synthetic SED from the grid.

Interpolates grid models and applies extinction to generate synthetic photometry using multi-linear interpolation.

Parameters:
  • mini (float, optional) – Initial mass in solar masses (\(M_\odot\)).

  • eep (float, optional) – Equivalent evolutionary point (dimensionless).

  • feh (float, optional) – Initial metallicity [Fe/H] in dex.

  • afe (float, optional) – Initial alpha enhancement [alpha/Fe] in dex.

  • av (float, optional) – V-band extinction \(A(V)\) in magnitudes. Default is 0.0.

  • rv (float, optional) – Total-to-selective extinction ratio \(R(V)\) (dimensionless). Default is 3.3.

  • smf (float, optional) – Secondary mass fraction in [0, 1].

  • dist (float, optional) – Distance in parsecs (pc). Default is 1000.0 (1 kpc).

  • return_dict (bool, optional) – If True, return params and params2 as dicts; if False, return 1-D numpy arrays. Default is True.

  • return_flux (bool, optional) – If True, return linear flux densities in maggies (10**(-0.4 * mag)) instead of apparent magnitudes. Default is False.

  • return_predictions (bool, optional) – If True, interpolate and return stellar parameters in params. Default is True.

  • use_multilinear (bool, optional) – Whether to use multi-linear interpolation (True) or KD-tree inverse-distance interpolation (False). Default is True.

Returns:

  • sed (numpy.ndarray of shape (Nfilt,)) – Synthetic photometry in apparent magnitudes (or maggies when return_flux=True).

  • params (dict, numpy.ndarray of shape (Nparam,), or None) – Interpolated primary star parameters, or None when return_predictions=False.

  • params2 (dict or numpy.ndarray of shape (0,)) – Empty placeholder ({} or np.array([])) for API compatibility with StarEvolTrack.get_seds.

Raises:

ValueError – As in get_predictions, or if dist is not a finite distance greater than 0.

Warns:

UserWarning – As in get_predictions.

See also

get_predictions

Get stellar parameters without photometry

StarEvolTrack.get_seds

Alternative track-based SED generation

brutus.analysis.BruteForce

Fitting with StarGrid

Notes

The SED is computed by interpolating magnitude coefficients and applying the extinction law:

\[m(\lambda) = m_0(\lambda) + A_V \cdot [r_0(\lambda) + R_V \cdot dr(\lambda)]\]

where \(m_0\) is the unreddened magnitude, \(r_0\) and \(dr\) are the reddening vector coefficients from the grid.

Examples

>>> grid = StarGrid(models, labels)
>>> sed, params, _ = grid.get_seds(
...     mini=1.0, eep=350, feh=0.0,
...     av=0.1, dist=500.0
... )
>>> print(f"G magnitude: {sed[0]:.2f}")
class brutus.core.StarEvolTrack(tracks, filters=None, nnfile=None, verbose=True)[source]

Bases: object

Synthesize individual-star photometry from evolutionary tracks.

Combines stellar parameter predictions from an EEPTracks instance with neural network bolometric corrections (FastNNPredictor) to compute reddened apparent magnitudes for single and unresolved binary stars.

Parameters:
  • tracks (EEPTracks) – EEPTracks instance for stellar parameter predictions. Its predictions must include loga, logl, logt, logg, feh_surf and afe_surf.

  • filters (list of str, optional) – Filter names for photometry computation. If None, uses all available.

  • nnfile (str, optional) – Path to neural network file for bolometric corrections. If None, FastNNPredictor finds the default file.

  • verbose (bool, optional) – Whether to output progress messages. Default is True.

Raises:

ValueError – If tracks.predictions lacks a label listed above, or if a filter is not in the neural network file.

tracks

The evolutionary track model for stellar parameter predictions

Type:

EEPTracks

filters

Array of filter names

Type:

numpy.ndarray

predictor

Neural network predictor for photometry

Type:

FastNNPredictor

See also

EEPTracks

Stellar parameter predictions used by this class

StarGrid

Alternative grid-based approach for photometry

brutus.core.neural_nets.FastNNPredictor

Neural network used for SEDs

Examples

Basic individual star photometry:

>>> tracks = EEPTracks()
>>> star_track = StarEvolTrack(tracks=tracks)
>>>
>>> # Generate SED for a solar-mass main sequence star
>>> sed, params, params2 = star_track.get_seds(
...     mini=1.0, eep=350, feh=0.0, afe=0.0,
...     av=0.1, rv=3.1, dist=1000.0
... )

Binary star modeling:

>>> # Model binary with 70% mass ratio secondary
>>> sed, params, params2 = star_track.get_seds(
...     mini=1.2, eep=400, feh=-0.2, afe=0.0,
...     smf=0.7, av=0.15, dist=1500.0
... )
__init__(tracks, filters=None, nnfile=None, verbose=True)[source]
get_seds(mini=1.0, eep=350, feh=0.0, afe=0.0, av=0.0, rv=3.3, smf=0.0, dist=1000.0, loga_max=10.15, eep2=None, mini_bound=0.08, eep_binary_max=480.0, apply_corr=True, corr_params=None, return_eep2=False, return_dict=True, combine_seds=True, tol=0.01)[source]

Generate synthetic SED for an individual star.

Parameters:
  • mini (float, optional) – Initial stellar mass in solar masses (\(M_\odot\)). Default is 1.0.

  • eep (float, optional) – Equivalent evolutionary point (dimensionless). Default is 350.

  • feh (float, optional) – Initial metallicity [Fe/H] in dex. Default is 0.0.

  • afe (float, optional) – Initial alpha enhancement [alpha/Fe] in dex. Default is 0.0.

  • av (float, optional) – V-band extinction \(A(V)\) in magnitudes. Default is 0.0.

  • rv (float, optional) – Total-to-selective extinction ratio \(R(V)\) (dimensionless). Default is 3.3.

  • smf (float, optional) – Secondary-to-primary initial mass ratio \(q = M_2 / M_1\) in [0, 1]. Default is 0.0 (single star).

  • dist (float, optional) – Distance in parsecs (pc). Default is 1000.0.

  • loga_max (float, optional) – Maximum log10(age / yr) for SED evaluation. Default is 10.15.

  • eep2 (float, optional) – Secondary component EEP. If None, solved by matching the primary’s age.

  • mini_bound (float, optional) – Minimum initial mass in \(M_\odot\) for SED evaluation. Default is 0.08.

  • eep_binary_max (float, optional) – Maximum primary EEP for binary modeling. Default is 480.0.

  • apply_corr (bool, optional) – Whether to apply low-mass empirical corrections. Default is True.

  • corr_params (tuple of 4 floats, optional) – Empirical correction parameters (dtdm, drdm, msto_smooth, feh_scale).

  • return_eep2 (bool, optional) – Whether to return the secondary EEP eep2. Default is False.

  • return_dict (bool, optional) – Whether to return params and params2 as dictionaries keyed by tracks.predictions (True) or 1-D arrays of shape (Npred,) (False). Default is True.

  • combine_seds (bool, optional) – If True, sum the primary and secondary fluxes into a single SED. If False and smf > 0, return [sed1, sed2]. Default is True.

  • tol (float, optional) – Convergence tolerance in dex on log10(age / yr) when solving for the secondary EEP. If the age match exceeds tol, a primary-only SED is returned. Default is 1e-2.

Returns:

  • sed (numpy.ndarray of shape (Nfilters,) or list of 2 numpy.ndarray) – Apparent magnitudes in each filter, or [sed1, sed2] when combine_seds=False and smf > 0.

  • params (dict or numpy.ndarray of shape (Npred,)) – Primary stellar parameters.

  • params2 (dict or numpy.ndarray of shape (Npred,)) – Secondary stellar parameters (all-NaN when no companion is added).

  • eep2 (float, optional) – Secondary EEP, returned only when return_eep2=True.

See also

EEPTracks.get_predictions

Stellar parameter predictions

FastNNPredictor.sed

Neural network SED generation

_get_eep_for_secondary

Binary companion EEP calculation

Notes

Distance modulus is applied as:

\[m = M + 5 \log_{10}(d/10\,{\rm pc})\]

where d is the distance in parsecs.

Binary SEDs are combined using magnitude addition (flux summing):

\[m_{\rm combined} = -2.5 \log_{10}(10^{-0.4 m_1} + 10^{-0.4 m_2})\]

Examples

Single star:

>>> sed, params, params2 = star_track.get_seds(
...     mini=1.0, eep=350, feh=0.0, afe=0.0
... )

Binary system:

>>> sed, params, params2 = star_track.get_seds(
...     mini=1.2, eep=400, feh=-0.2, afe=0.0, smf=0.7
... )

Population Models

class brutus.core.Isochrone(mistfile=None, predictions=None, verbose=True)[source]

Bases: object

Interpolate stellar parameters along MIST isochrones.

Predicts stellar parameters along an isochrone of fixed metallicity (feh), alpha enhancement (afe), and log-age (loga) across equivalent evolutionary points (eep). Pass an instance to StellarPop to synthesize population photometry.

Parameters:
  • mistfile (str, optional) – Path to the HDF5 file containing the MIST isochrone grid. If not provided, MIST_1.2_iso_vvcrit0.0.h5 is looked up in the brutus download directory (the Pooch cache, or $ASTRO_BRUTUS_DATA_DIR when set), then in data/DATAFILES in the repository; a FileNotFoundError names brutus.data.fetch_isos when it is absent. The file must hold the mini, logt, logl and logg labels, which the empirical corrections need; a missing one raises a ValueError.

  • predictions (list of str, optional) – The names of stellar parameters to predict. Must be a subset of the parameters available in the isochrone file (pred_labels); the columns returned by get_predictions follow this list’s order. Unknown names raise a ValueError. Default is: [“mini”, “mass”, “logl”, “logt”, “logr”, “logg”, “feh_surf”, “afe_surf”].

  • verbose (bool, optional) – Whether to output progress messages during initialization. Default is True.

predictions

List of stellar parameter names for prediction

Type:

list of str

feh_grid, afe_grid, loga_grid, eep_grid

Input parameter grids from MIST isochrone file

Type:

numpy.ndarray

pred_grid

Stellar parameter predictions organized by grid coordinates

Type:

numpy.ndarray

interpolator

Main interpolation object for stellar parameter prediction

Type:

scipy.interpolate.RegularGridInterpolator

Examples

Generate stellar parameters for a solar metallicity, 1 Gyr population:

>>> iso = Isochrone()
>>> params = iso.get_predictions(feh=0.0, afe=0.0, loga=9.0)
>>> masses = params[:, 0]  # Initial masses
>>> log_teff = params[:, 3]  # log(effective temperatures)
>>> print(f"Mass range: {masses.min():.2f} - {masses.max():.2f} M_sun")

Generate parameters for specific evolutionary phases:

>>> import numpy as np
>>> eep_range = np.arange(200, 500, 50)  # Main sequence to turnoff
>>> params = iso.get_predictions(feh=-0.5, afe=0.0, loga=10.0, eep=eep_range)
__init__(mistfile=None, predictions=None, verbose=True)[source]
get_predictions(feh=0.0, afe=0.0, loga=8.5, eep=None, apply_corr=True, corr_params=None)[source]

Generate stellar parameter predictions for an isochrone.

Parameters:
  • feh (float, optional) – Metallicity [Fe/H] in dex. Default is 0.0.

  • afe (float, optional) – Alpha enhancement [alpha/Fe] in dex. Default is 0.0. A value outside the grid’s afe range returns NaN; for the shipped MIST file, the only valid value is 0.0.

  • loga (float, optional) – Log10(age in yr). Default is 8.5 (~316 Myr).

  • eep (array-like of shape (Neep,), optional) – Equivalent evolutionary points (dimensionless). If None, uses self.eep_u.

  • apply_corr (bool, optional) – Whether to apply empirical corrections. Default is True.

  • corr_params (tuple, optional) – Correction parameters (dtdm, drdm, msto_smooth, feh_scale). Default is (0.09, -0.09, 30.0, 0.5), as in EEPTracks.get_corrections.

Returns:

preds – Stellar parameter predictions for each EEP value. The columns correspond to the parameters listed in self.predictions (a subset/reordering of the file’s self.pred_labels).

Return type:

numpy.ndarray of shape (Neep, Npred)

Raises:

ValueError – If corr_params does not have 4 entries.

See also

StellarPop.get_seds

Uses these predictions for photometry generation

brutus.core.EEPTracks.get_predictions

Similar function for individual stars

Notes

The method interpolates across the pre-computed MIST isochrone grid. Returns NaN for parameters outside the grid bounds or where data is not available.

MIST primary EEPs (Dotter 2016): - Pre-main sequence: EEP < 202 - Zero-age main sequence: EEP = 202 - Terminal-age main sequence: EEP = 454 - Subgiant and red giant branches: EEP 454-605 (RGB tip at 605) - Core helium burning: EEP 631-707 - Early asymptotic giant branch: EEP 707-808 - Thermally pulsing AGB: EEP 808 - Post-AGB: EEP 1409

Examples

>>> iso = Isochrone()
>>> # Get parameters for a 1 Gyr solar metallicity population
>>> params = iso.get_predictions(feh=0.0, afe=0.0, loga=9.0)
>>> masses = params[:, 0]  # Initial masses
>>> temps = 10**params[:, 3]  # Effective temperatures
class brutus.core.StellarPop(isochrone, filters=None, nnfile=None, verbose=True)[source]

Bases: object

Synthesize photometry for coeval stellar populations.

Combines isochrone parameter predictions from an Isochrone instance with neural network bolometric corrections (FastNNPredictor) to compute reddened apparent magnitudes across equivalent evolutionary points (EEPs) for single and binary stellar populations.

Parameters:
  • isochrone (Isochrone) – Isochrone instance for stellar parameter predictions. Its predictions must include mini, logl, logt, logg, feh_surf and afe_surf.

  • filters (list of str, optional) – Filter names for photometry computation. If None, uses all available.

  • nnfile (str, optional) – Path to neural network file for bolometric corrections. If None, FastNNPredictor finds the default file.

  • verbose (bool, optional) – Whether to output progress messages. Default is True.

Raises:

ValueError – If isochrone.predictions lacks a label listed above, or if a filter is not in the neural network file.

isochrone

The isochrone model used for stellar parameter predictions

Type:

Isochrone

filters

Array of filter names

Type:

numpy.ndarray

predictor

Neural network predictor for photometry

Type:

FastNNPredictor

Examples

Basic stellar population photometry:

>>> iso = Isochrone()
>>> ssp = StellarPop(isochrone=iso)
>>>
>>> # Generate SEDs for solar metallicity, 1 Gyr population
>>> seds, params, params2 = ssp.get_seds(
...     feh=0.0, afe=0.0, loga=9.0,
...     av=0.1, rv=3.1, dist=1000.0
... )

Binary population modeling:

>>> # Model population with 40% mass ratio binaries
>>> seds, params, params2 = ssp.get_seds(
...     feh=-0.5, afe=0.0, loga=10.0,
...     binary_fraction=0.4,
...     av=0.2, dist=2000.0
... )

See also

Isochrone

Stellar parameter predictions used by this class

StarEvolTrack

Individual star analog

brutus.core.neural_nets.FastNNPredictor

Neural network SED generation

Notes

For binary populations (binary_fraction > 0), secondary masses are set to binary_fraction * mini and secondary EEPs are interpolated from the isochrone’s mini(EEP) relation at the same age and metallicity for main sequence primaries (eep <= eep_binary_max).

__init__(isochrone, filters=None, nnfile=None, verbose=True)[source]
get_seds(feh=0.0, afe=0.0, loga=8.5, eep=None, av=0.0, rv=3.3, binary_fraction=0.0, dist=1000.0, mini_bound=0.5, eep_binary_max=480.0, apply_corr=True, corr_params=None, return_dict=True)[source]

Generate synthetic photometry for a stellar population.

Parameters:
  • feh (float, optional) – Metallicity [Fe/H] in dex. Default is 0.0.

  • afe (float, optional) – Alpha enhancement [alpha/Fe] in dex. Default is 0.0. A value outside the isochrone grid’s afe range gives NaN SEDs; for the shipped MIST file, the only valid value is 0.0.

  • loga (float, optional) – Log10(age in yr). Default is 8.5.

  • eep (float or array-like of shape (Neep,), optional) – Equivalent evolutionary points (dimensionless), as a scalar or 1-D array. If None, uses the isochrone’s EEP grid.

  • av (float, optional) – V-band extinction \(A(V)\) in magnitudes. Default is 0.0.

  • rv (float, optional) – Total-to-selective extinction ratio \(R(V)\) (dimensionless). Default is 3.3.

  • binary_fraction (float, optional) –

    Secondary-to-primary mass ratio \(q = M_2 / M_1\) in [0, 1]. Default is 0.0 (single stars): - 0.0: single stars only - 0 < binary_fraction < 1: mass-ratio binaries - 1.0: equal-mass binaries

    Binary companions are added only for primaries with eep <= eep_binary_max; other stars (and stars whose companion falls below mini_bound or has no age-consistent EEP) keep their primary-only SED. The companion EEP inverts mini(EEP) on the isochrone’s own EEP grid, independent of eep.

  • dist (float, optional) – Distance in parsecs (pc). Default is 1000.0.

  • mini_bound (float, optional) – Minimum initial mass in \(M_\odot\) for SED computation. Default is 0.5.

  • eep_binary_max (float, optional) – Maximum primary EEP for binary modeling. Default is 480.0.

  • apply_corr (bool, optional) – Apply empirical corrections. Default is True.

  • corr_params (tuple, optional) – Correction parameters.

  • return_dict (bool, optional) – Return parameters as dictionaries. Default is True.

Returns:

  • seds (numpy.ndarray of shape (Neep, Nfilters)) – Synthetic SEDs in magnitudes.

  • params (dict or numpy.ndarray) – Primary component stellar parameters: a dict of (Neep,) arrays keyed by isochrone.predictions, or with return_dict=False an array of shape (Neep, Npred) with columns in that order.

  • params2 (dict or numpy.ndarray) – Secondary component parameters, in the same form as params. NaN for every star whose SED has no companion.

Raises:

ValueError – If binary_fraction is not finite or lies outside [0, 1].

See also

Isochrone.get_predictions

Stellar parameter predictions

FastNNPredictor.sed

Neural network photometry generation

StarEvolTrack.get_seds

Individual star analog

Notes

The photometry generation workflow:

  1. Predict stellar parameters from isochrone

  2. Generate primary SEDs using neural network

  3. For binaries: generate secondary SEDs and combine

  4. Apply dust extinction with specified R(V)

  5. Apply distance modulus

Binary stars are modeled with the same age and metallicity as primaries, with masses determined by the binary_fraction parameter. Binary companions are only added for stars below eep_binary_max (typically restricted to main sequence).

Examples

Simple stellar population:

>>> seds, params, params2 = pop_synth.get_seds(
...     feh=0.0, loga=9.0, av=0.1, dist=1000.0
... )

Binary population:

>>> seds, params, params2 = pop_synth.get_seds(
...     feh=-0.5, loga=10.0, binary_fraction=0.4,
...     av=0.2, dist=2000.0
... )
get_seds_smf_grid(smf_values, feh=0.0, afe=0.0, loga=8.5, eep=None, av=0.0, rv=3.3, dist=1000.0, mini_bound=0.5, eep_binary_max=480.0, apply_corr=True, corr_params=None, return_dict=True)[source]

Generate synthetic photometry for several binary mass fractions.

Equivalent to calling get_seds() once per entry of smf_values (with binary_fraction set to that entry), except that the primary isochrone predictions and primary SEDs (which do not depend on the binary mass fraction) are computed once and reused across all values. Recomputing only the secondary components roughly halves the cost of building a full (mass, SMF) population grid.

Parameters:
  • smf_values (array-like of float) – Binary mass fractions (secondary mass fractions) to evaluate, each in [0, 1]. Each entry is interpreted exactly like binary_fraction in get_seds().

  • feh – Same as in get_seds(); shared by every SMF value.

  • afe – Same as in get_seds(); shared by every SMF value.

  • loga – Same as in get_seds(); shared by every SMF value.

  • eep – Same as in get_seds(); shared by every SMF value.

  • av – Same as in get_seds(); shared by every SMF value.

  • rv – Same as in get_seds(); shared by every SMF value.

  • dist – Same as in get_seds(); shared by every SMF value.

  • mini_bound – Same as in get_seds(); shared by every SMF value.

  • eep_binary_max – Same as in get_seds(); shared by every SMF value.

  • apply_corr – Same as in get_seds(); shared by every SMF value.

  • corr_params – Same as in get_seds(); shared by every SMF value.

  • return_dict – Same as in get_seds(); shared by every SMF value.

Returns:

results – One get_seds()-style result per entry of smf_values, in order. The primary-parameter outputs (params arrays) share underlying arrays across entries and must not be modified in place.

Return type:

list of (seds, params, params2) tuples

Raises:

ValueError – If any value of smf_values is not finite or lies outside [0, 1].

See also

get_seds

Single binary-mass-fraction evaluation.

brutus.analysis.populations.generate_isochrone_population_grid

Main consumer of this method.

Neural Networks

class brutus.core.FastNN(filters=None, nnfile=None, verbose=True)[source]

Bases: object

Evaluate neural network bolometric corrections from stellar parameters.

Loads pre-trained neural network weights, biases, and input scaling bounds for a set of photometric filters and evaluates bolometric corrections via a 3-layer feedforward network.

Parameters:
  • filters (list of str, optional) – The names of filters that photometry should be computed for. If not provided, all available filters will be used. Filter names should match those defined in brutus.data.filters.FILTERS.

  • nnfile (str, optional) – Path to the neural network file containing pre-trained weights and biases. If not provided, brutus.data.find_nn_file looks it up in the brutus data directories; brutus.data.fetch_nns downloads it.

  • verbose (bool, optional) – Whether to print initialization progress messages to stderr. Default is True.

w1, w2, w3

Neural network weight matrices for each layer.

Type:

numpy.ndarray

b1, b2, b3

Neural network bias vectors for each layer.

Type:

numpy.ndarray

xmin, xmax

Minimum and maximum values for input parameter scaling.

Type:

numpy.ndarray

xspan

Range of input parameters (xmax - xmin).

Type:

numpy.ndarray

Notes

The neural network architecture is a 3-layer feedforward network with sigmoid activation functions. Input parameters are scaled to [0,1] range before evaluation.

Expected input parameters (in order):

  • Teff : Effective temperature in Kelvin (linear, NOT log10; FastNNPredictor.sed converts its logt argument via 10**logt before calling the network)

  • log g : Surface gravity in cgs units

  • [Fe/H] : Surface metallicity (log scale)

  • [α/Fe] : Alpha enhancement (log scale)

  • Av : V-band extinction in magnitudes

  • Rv : Reddening parameter R(V) = A(V)/E(B-V)

encode and nneval perform NO bounds checking: inputs outside the training ranges (xmin/xmax) silently produce extrapolated garbage. Use FastNNPredictor.sed/sed_batch, which validate bounds and return NaN for out-of-range parameters.

__init__(filters=None, nnfile=None, verbose=True)[source]
encode(x)[source]

Rescale input parameters to [0,1] range for neural network evaluation.

The neural networks are trained on scaled inputs where each parameter is normalized to the range [0,1] based on the training data bounds.

Parameters:

x (numpy.ndarray of shape (6,) or (6, Nsamples)) – Input parameters [Teff, logg, feh_surf, afe, av, rv] with Teff in linear K (not log10(Teff)), logg in log10(cm/s^2), feh_surf and afe in dex, av in mag, and rv dimensionless. No bounds checking is performed; see the class Notes.

Returns:

xp – Scaled input parameters ready for neural network evaluation.

Return type:

numpy.ndarray of shape (Ninput, 1) or (Ninput, Nsamples)

Notes

The scaling is applied as: x_scaled = (x - xmin) / (xmax - xmin) where xmin and xmax are the bounds from the training data.

sigmoid(a)[source]

Apply sigmoid activation function.

Computes the logistic sigmoid function: f(a) = 1 / (1 + exp(-a))

Parameters:

a (numpy.ndarray) – Input array to apply sigmoid transformation to.

Returns:

a_t – Output after applying sigmoid activation, same shape as input.

Return type:

numpy.ndarray

Notes

The sigmoid function maps any real number to the range (0, 1), providing smooth activation for the neural network hidden layers.

nneval(x)[source]

Evaluate the neural network for given input parameters.

Performs forward propagation through the 3-layer neural network to predict bolometric corrections for all filters.

Parameters:

x (numpy.ndarray of shape (6,) or (6, Nsamples)) – Input parameters [Teff, logg, feh_surf, afe, av, rv] with Teff in linear K (not log10(Teff)), logg in log10(cm/s^2), feh_surf and afe in dex, av in mag, and rv dimensionless. No bounds checking is performed; see the class Notes.

Returns:

y – Predicted bolometric corrections in magnitudes for each filter (squeezed along singleton axes).

Return type:

numpy.ndarray of shape (Nfilt,) or (Nfilt, Nsamples)

Notes

The network architecture is: - Input layer: 6 parameters - Hidden layer 1: with sigmoid activation - Hidden layer 2: with sigmoid activation - Output layer: linear activation (bolometric corrections)

class brutus.core.FastNNPredictor(filters=None, nnfile=None, verbose=True)[source]

Bases: FastNN

Predict apparent magnitudes across photometric filters using neural networks.

Extends FastNN by combining predicted bolometric corrections with bolometric luminosity and distance modulus to return apparent magnitudes.

Parameters:
  • filters (list of str, optional) – The names of filters that photometry should be computed for. If not provided, all available filters will be used. Must be a subset of filters available in the neural network file.

  • nnfile (str, optional) – Path to the neural network file containing pre-trained weights. If not provided, brutus.data.find_nn_file looks it up in the brutus data directories; brutus.data.fetch_nns downloads it.

  • verbose (bool, optional) – Whether to print initialization progress messages. Default is True.

filters

Array of filter names for which predictions are made.

Type:

numpy.ndarray

NFILT

Number of filters for which predictions are made.

Type:

int

Examples

Predict SED for a solar analog:

>>> predictor = FastNNPredictor(filters=['PS_g', 'PS_r', 'PS_i'])
>>> sed = predictor.sed(logt=3.76, logg=4.44, feh_surf=0.0,
...                     logl=0.0, dist=1000.)
>>> print(f"g-r color: {sed[0] - sed[1]:.3f}")

Predict for a red giant with extinction:

>>> sed = predictor.sed(logt=3.60, logg=2.5, feh_surf=-0.5,
...                     logl=1.5, av=0.5, rv=3.1, dist=2000.)

Notes

The neural networks provide bolometric corrections which are combined with luminosity and distance to produce apparent magnitudes:

m = -2.5 * log10(L/L_sun) + 4.74 - BC + distance_modulus

where BC is the bolometric correction predicted by the neural network.

__init__(filters=None, nnfile=None, verbose=True)[source]
sed(logt=3.8, logg=4.4, feh_surf=0.0, logl=0.0, afe=0.0, av=0.0, rv=3.3, dist=1000.0, filt_idxs=slice(None, None, None))[source]

Generate SED predictions for specified stellar parameters.

Returns predicted apparent magnitudes in the specified filters for a star with the given physical parameters, distance, and extinction. Uses neural network bolometric corrections combined with standard photometric transformations.

The network inputs (Teff, logg, feh_surf, afe, av, rv) must lie within the training bounds xmin and xmax; otherwise the SED is NaN. The ranges below are those of the default file nn_c3k.h5.

Parameters:
  • logt (float, optional) – Base-10 logarithm of effective temperature in Kelvin. Range: [3.40, 4.70] (Teff from 2500 to 50000 K). Default is 3.8 (6300K, solar-type).

  • logg (float, optional) – Base-10 logarithm of surface gravity in cgs units (cm/s^2). Range: [-1, 5.5]. Default is 4.4 (solar value).

  • feh_surf (float, optional) – Surface metallicity [Fe/H] in logarithmic units relative to solar. Range: [-4, 0.5]. Default is 0.0 (solar).

  • logl (float, optional) – Base-10 logarithm of luminosity in solar luminosities. It is not a network input and has no range. Default is 0.0 (solar luminosity).

  • afe (float, optional) – Alpha element enhancement [alpha/Fe] in logarithmic units relative to solar abundance ratios. Range: [-0.2, 0.6]. Default is 0.0 (solar ratios).

  • av (float, optional) – V-band extinction in magnitudes. Range: [0, 6] mag. Default is 0.0 (no extinction).

  • rv (float, optional) – Reddening parameter R(V) = A(V)/E(B-V), describing the extinction curve shape. Range: [2, 5]. Default is 3.3 (Milky Way average).

  • dist (float, optional) – Distance to the star in parsecs. Must be positive. Default is 1000 pc.

  • filt_idxs (slice or array-like, optional) – Indices or slice object specifying which subset of filters to return predictions for. Default is slice(None) (all filters).

Returns:

sed – Predicted apparent magnitudes in the specified filter subset. Magnitudes are in each survey’s native photometric system and include distance modulus and extinction corrections.

Return type:

numpy.ndarray of shape (Nfilt_subset,)

Notes

The computation follows these steps:

  1. Compute distance modulus: mu = 5 * log10(dist) - 5

  2. Evaluate neural network for bolometric corrections: BC = NN(params)

  3. Convert to apparent magnitudes: m = -2.5 * logl + 4.74 - BC + mu

Examples

Solar analog at various distances:

>>> predictor = FastNNPredictor(['Bessell_V', '2MASS_Ks'])
>>> for d in [100, 1000, 10000]:  # pc
...     sed = predictor.sed(dist=d)
...     print(f"{d:5d} pc: V={sed[0]:.2f}, K={sed[1]:.2f}")

Effect of extinction:

>>> sed_clean = predictor.sed(av=0.0)
>>> sed_dusty = predictor.sed(av=1.0, rv=3.1)
>>> extinction = sed_dusty - sed_clean
>>> print(f"V-band extinction: {extinction[0]:.2f} mag")
sed_batch(logt, logg, feh_surf, logl, afe, av, rv, dist, filt_idxs=slice(None, None, None))[source]

Generate SED predictions for an array of stellar parameters.

Vectorized version of sed() that evaluates the neural network once for all stars, providing significant speedup over looping.

Parameters:
  • logt (numpy.ndarray of shape (N,)) – Base-10 logarithm of effective temperature in K for each star.

  • logg (numpy.ndarray of shape (N,)) – Base-10 logarithm of surface gravity in cm/s^2 for each star.

  • feh_surf (numpy.ndarray of shape (N,)) – Surface metallicity [Fe/H] in dex for each star.

  • logl (numpy.ndarray of shape (N,)) – Base-10 logarithm of bolometric luminosity in \(L_\odot\) for each star.

  • afe (numpy.ndarray of shape (N,)) – Surface alpha enhancement [alpha/Fe] in dex for each star.

  • av (float or numpy.ndarray of shape (N,)) – V-band extinction \(A(V)\) in magnitudes.

  • rv (float or numpy.ndarray of shape (N,)) – Total-to-selective extinction ratio \(R(V)\) (dimensionless).

  • dist (float) – Distance in parsecs (pc), shared by all stars.

  • filt_idxs (slice or array-like, optional) – Filter subset to return. Default is slice(None) (all filters).

Returns:

seds – Predicted apparent magnitudes in each filter. Stars with parameters outside the neural network training bounds receive NaN rows.

Return type:

numpy.ndarray of shape (N, Nfilt_subset)

Grid Generation

class brutus.core.GridGenerator(tracks, filters=None, nnfile=None, verbose=True)[source]

Bases: object

Generate pre-computed stellar model grids with reddening coefficients.

This class creates HDF5 grid files used by StarGrid for fast photometric predictions. Grids are computed at 1 kpc reference distance and include polynomial coefficients for A_V and R_V reddening corrections.

The generator uses evolutionary tracks (EEPTracks) combined with neural network bolometric corrections to compute photometry across a multi-dimensional parameter grid, then fits reddening vectors to enable fast interpolation.

Parameters:
  • tracks (EEPTracks) – Stellar evolutionary track model providing parameter predictions. Must expose the EEPTracks interface: labels, predictions, and a get_predictions(label_array, …) method. Isochrone objects are NOT supported (they lack labels and use a keyword-based get_predictions signature).

  • filters (list of str, optional) – Names of photometric filters for which to generate models. If None, uses all available filters from FILTERS.

  • nnfile (str or Path, optional) – Path to neural network file for bolometric corrections. If None, uses default neural network file.

  • verbose (bool, optional) – Whether to print progress messages during initialization. Default is True.

tracks

Evolutionary track model

Type:

EEPTracks

star_track

SED generator combining tracks with neural networks

Type:

StarEvolTrack

filters

Array of filter names

Type:

numpy.ndarray

predictor

Neural network predictor for photometry

Type:

FastNNPredictor

Examples

Create grid generator and generate default grid:

>>> from brutus.core.individual import EEPTracks
>>> from brutus.core.grid_generation import GridGenerator
>>>
>>> tracks = EEPTracks(verbose=False)
>>> gen = GridGenerator(tracks)
>>> gen.make_grid(output_file='grid.h5', verbose=True)

Generate grid for specific filters only:

>>> gen_gaia = GridGenerator(tracks, filters=['Gaia_G_MAW', 'Gaia_BP_MAWf', 'Gaia_RP_MAW'])
>>> gen_gaia.make_grid(output_file='grid_gaia.h5')

Notes

GridGenerator wraps StarEvolTrack to evaluate base photometry at 1 kpc and batches the neural network reddening evaluations across the \((A(V), R(V))\) lattice for each grid point.

See also

brutus.core.individual.StarGrid

Uses grids generated by this class

brutus.data.loader.load_models

Loads grids generated by this class

__init__(tracks, filters=None, nnfile=None, verbose=True)[source]

Initialize grid generator with evolutionary tracks.

make_grid(mini_grid=None, eep_grid=None, feh_grid=None, afe_grid=None, smf_grid=None, av_grid=None, av_wt=None, rv_grid=None, rv_wt=None, loga_max=10.14, eep_binary_max=480.0, mini_bound=0.5, apply_corr=True, corr_params=None, output_file=None, verbose=True)[source]

Generate model grid with reddening coefficients.

Creates a grid of stellar models across the specified parameter space, computing photometry at 1 kpc reference distance and fitting polynomial coefficients for reddening corrections. Results are saved to HDF5 format compatible with StarGrid.

Parameters:
  • mini_grid (numpy.ndarray, optional) – Grid of initial masses in solar masses. If None, defaults to np.arange(0.5, 2.0 + 1e-5, 0.025), 61 values from 0.5 to 2.0.

  • eep_grid (numpy.ndarray, optional) – Grid of equivalent evolutionary points. If None, defaults to adaptive grid: resolution 6 from 202-454 (MS), resolution 2 from 454-808 (post-MS).

  • feh_grid (numpy.ndarray, optional) – Grid of [Fe/H] metallicity values. If None, defaults to adaptive grid: resolution 0.1 from -3.0 to -2.0, resolution 0.05 from -2.0 to +0.5.

  • afe_grid (numpy.ndarray, optional) – Grid of [α/Fe] alpha enhancement values. If None, defaults to np.arange(-0.2, 0.6 + 1e-5, 0.2), five values from -0.2 to +0.6.

  • smf_grid (numpy.ndarray, optional) – Grid of secondary mass fractions for binaries. If None, defaults to [0.] (single stars only).

  • av_grid (numpy.ndarray, optional) – Grid of A_V extinction values used for fitting reddening vector, with at least 2 distinct values. If None, defaults to 6 values from 0 to 1.5 - 1e-5 in steps of 0.3.

  • av_wt (numpy.ndarray, optional) – Weights for A_V grid points when fitting, one per av_grid value. If None, defaults to (1e-5 + av_grid)**-1 which forces fit through A_V=0.

  • rv_grid (numpy.ndarray, optional) – Grid of R_V values used for fitting differential reddening, with at least 2 distinct values. If None, defaults to np.arange(2.4, 4.2 + 1e-5, 0.3), 7 values from 2.4 to 4.2.

  • rv_wt (numpy.ndarray, optional) – Weights for R_V grid points when fitting, one per rv_grid value. If None, defaults to exp(-abs(R_V - 3.3) / 0.5) favoring R_V=3.3.

  • loga_max (float, optional) – Maximum log10(age) in years. Models older than this are masked. Default is 10.14 (13.8 Gyr).

  • eep_binary_max (float, optional) – Maximum EEP for binary models. Above this, binaries are not computed (typically giant phase). Default is 480.

  • mini_bound (float, optional) – Minimum initial mass threshold. Models below this are masked. Default is 0.5 solar masses.

  • apply_corr (bool, optional) – Whether to apply empirical corrections to Teff and radius. Default is True.

  • corr_params (tuple, optional) – Parameters for empirical corrections (dtdm, drdm, msto_smooth, feh_scale). If None, uses default values from tracks.

  • output_file (str or Path, optional) – Path to output HDF5 file. If None, results are stored as attributes but not saved to disk.

  • verbose (bool, optional) – Whether to print progress messages. Default is True.

Returns:

Results are saved to output_file if provided, and stored as class attributes: grid_labels, grid_seds, grid_params, grid_sel

Return type:

None

Raises:

ValueError – If av_grid or rv_grid has fewer than 2 distinct values, or if av_wt or rv_wt has a different shape from its grid.

Notes

Grid Size: The default axes give 61 mini x 220 eep x 61 feh x 5 afe x 1 smf = 4,093,100 labels before masking. Computation time scales linearly with the number of labels and with len(av_grid) * len(rv_grid), the number of SED evaluations per model in the reddening fits. A model with no companion is computed once per (mini, eep, feh, afe) and copied to the other smf_grid values.

Reddening Fits: For each valid model, the code:

  1. Computes SEDs across (av_grid × rv_grid) combinations

  2. Fits linear dependence on A_V at each R_V value

  3. Fits linear dependence of A_V slope on R_V

  4. Stores [m_0, a, b] where m = m_0 + A_V·(a + b·R_V), i.e. a is the A_V reddening vector extrapolated to R_V=0

Examples

Generate default grid:

>>> gen.make_grid(output_file='grid_default.h5')

Generate sparse testing grid:

>>> gen.make_grid(
...     mini_grid=np.linspace(0.8, 1.2, 5),
...     eep_grid=np.linspace(300, 450, 10),
...     feh_grid=np.array([0.0]),
...     afe_grid=np.array([0.0]),
...     smf_grid=np.array([0.0]),
...     output_file='grid_test.h5',
...     verbose=True
... )

SED Utilities

brutus.core.get_seds(mag_coeffs, av=None, rv=None, return_flux=False, return_rvec=False, return_drvec=False)[source]

Compute reddened SEDs from the provided magnitude coefficients.

This is a convenience wrapper around _get_seds that provides parameter handling and optional return values.

Parameters:
  • mag_coeffs (~numpy.ndarray of shape (Nmodels, Nbands, 3)) – Polynomial coefficients (m_0, R_0, dR/dR_V) per model and band, where m_0 is the unreddened apparent magnitude at 1 kpc (mag), R_0 is the \(A(V)\) reddening vector extrapolated to \(R(V) = 0\) (mag per mag of \(A(V)\)), and dR/dR_V is its derivative with respect to \(R(V)\) (mag per mag of \(A(V)\)).

  • av (float or ~numpy.ndarray of shape (Nmodels,), optional) – V-band dust extinction \(A(V)\) in magnitudes. Default is 0.0.

  • rv (float or ~numpy.ndarray of shape (Nmodels,), optional) – Total-to-selective extinction ratio \(R(V)\) (dimensionless). Default is 3.3.

  • return_flux (bool, optional) – If True, return linear flux densities in maggies (10**(-0.4 * mag)) instead of magnitudes. Default is False.

  • return_rvec (bool, optional) – Whether to return the reddening vectors rvecs at the given av and rv. Default is False.

  • return_drvec (bool, optional) – Whether to return the differential reddening vectors drvecs at the given av and rv. Default is False.

Returns:

  • seds (~numpy.ndarray of shape (Nmodels, Nbands)) – Reddened SEDs in magnitudes (or maggies when return_flux=True).

  • rvecs (~numpy.ndarray of shape (Nmodels, Nbands), optional) – Reddening derivatives \(\partial m / \partial A(V)\) in mag per mag of \(A(V)\) (or \(\partial F / \partial A(V)\) in maggies per mag when return_flux=True). Returned when return_rvec=True.

  • drvecs (~numpy.ndarray of shape (Nmodels, Nbands), optional) – Scaled differential reddening vectors \(A(V)^{-1} \partial m / \partial R(V)\) in mag per mag of \(A(V)\) (or \(A(V)^{-1} \partial F / \partial R(V)\) in maggies per mag when return_flux=True). Returned when return_drvec=True.

Raises:

ValueError – If mag_coeffs does not have shape (Nmodels, Nbands, 3), or if av or rv is an array whose shape is not (Nmodels,).

Examples

>>> import numpy as np
>>> from brutus.core.sed_utils import get_seds
>>>
>>> # Create mock magnitude coefficients for 2 models, 3 bands
>>> mag_coeffs = np.random.random((2, 3, 3))
>>> mag_coeffs[:, :, 0] = 15.0  # Base magnitudes
>>> mag_coeffs[:, :, 1] = 1.0   # R(V)=0 reddening
>>> mag_coeffs[:, :, 2] = 0.1   # dR/dR(V)
>>>
>>> # Compute reddened SEDs
>>> seds = get_seds(mag_coeffs, av=0.1, rv=3.1)
>>> print(f"SED shape: {seds.shape}")
>>> # Get SEDs and reddening vectors
>>> seds, rvecs = get_seds(mag_coeffs, av=0.1, rv=3.1, return_rvec=True)
>>> # Get all outputs
>>> seds, rvecs, drvecs = get_seds(mag_coeffs, av=0.1, rv=3.1,
...                                return_rvec=True, return_drvec=True)

Notes

This function evaluates per-band reddening from the grid’s precomputed coefficients, which parameterize the R(V)-dependent extinction curve of Fitzpatrick & Massa (2009) used throughout brutus (see the stellar models documentation). The reddening is applied as:

A(λ) = A(V) * [R(V)=0 + R(V) * dR/dR(V)]

where A(λ) is the extinction in a given band.

brutus.core.sed_utils._get_seds(mag_coeffs, av, rv, return_flux=False)[source]

Compute reddened SEDs from the provided magnitude coefficients.

This is the core function for computing reddened SEDs, optimized with numba for performance.

Parameters:
  • mag_coeffs (~numpy.ndarray of shape (Nmodels, Nbands, 3)) – Array of (mag, R, dR/dRv) coefficients used to generate reddened photometry in all bands. The first coefficient is the unreddened photometry, the second is the A(V) reddening vector for R(V)=0, and the third is the change in the reddening vector as a function of R(V).

  • av (~numpy.ndarray of shape (Nmodels,)) – Array of A(V) dust attenuation values.

  • rv (~numpy.ndarray of shape (Nmodels,)) – Array of R(V) dust attenuation curve “shape” values.

  • return_flux (bool, optional) – Whether to return SEDs as flux densities instead of magnitudes. Default is False.

Returns:

  • seds (~numpy.ndarray of shape (Nmodels, Nbands)) – Reddened SEDs, in magnitudes, or in maggies if return_flux.

  • rvecs (~numpy.ndarray of shape (Nmodels, Nbands)) – Reddening vectors. With return_flux=False, dm/dA(V) = R + R(V) * dR/dRv, in mag per mag of A(V). With return_flux=True, dF/dA(V), in maggies per mag of A(V).

  • drvecs (~numpy.ndarray of shape (Nmodels, Nbands)) – Differential reddening vectors. With return_flux=False, (1 / A(V)) dm/dR(V) = dR/dRv, in mag per mag of A(V). With return_flux=True, (1 / A(V)) dF/dR(V), in maggies per mag of A(V).