Skip to main content

No project description provided

Project description

spice logo

SPICE: SPectral Integration Compiled Engine

A comprehensive Python library for modeling and analyzing stellar spectra with inhomogeneous surfaces, supporting rotation, pulsations, spots, and binary star systems.

The paper is submitted and available as a preprint.

Installation

Install from PyPI:

pip install stellar-spice

For PHOEBE integration support:

pip install stellar-spice[phoebe]

For zarr-backed model-atmosphere grid interpolation (LazyZarrInterpolator and friends):

pip install stellar-spice[grid]

Documentation

📖 Read the full documentation for detailed API reference and tutorials.

Key Features

🌟 Stellar Surface Modeling

  • Mesh-based stellar surfaces using icosphere discretization
  • Inhomogeneous temperature distributions across stellar surfaces
  • Surface gravity variations accounting for rotation and shape distortions
  • Line-of-sight velocity calculations for Doppler shift effects

🔄 Stellar Rotation

  • Solid-body (rigid) rotation with a configurable axis and equatorial velocity
  • Rotational broadening effects on spectral lines
  • Surface velocity field calculations
  • Time-dependent spectral variations due to rotation

🌊 Stellar Pulsations

  • Spherical harmonic pulsation modes (l, m modes)
  • Fourier series parameterization for complex pulsation patterns
  • Multi-mode pulsations with different periods and amplitudes
  • Surface displacement and velocity calculations

🌑 Stellar Spots

  • Spherical harmonic spot modeling for complex spot distributions
  • Temperature contrast between spots and photosphere
  • Time-evolving spot patterns
  • Spot-induced spectral variations

Binary Star Systems

  • Full orbital dynamics with Keplerian orbits
  • Mutual eclipses and occultations resolved on the projected meshes
  • PHOEBE integration — import Roche-lobe geometry and tidally distorted binary meshes computed by PHOEBE

📊 Spectral Synthesis

  • Blackbody radiation for basic stellar modeling
  • Model-atmosphere grid interpolation from precomputed, zarr-backed grids
  • Analytic line-profile emulators (Gaussian and physical)
  • Transformer-Payne integration for ML-based spectral synthesis
  • Custom spectral models via the SpectrumEmulator interface

🔍 Synthetic Photometry

  • Multiple passband support (Johnson, Stromgren, Gaia, etc.)
  • AB magnitude system calculations
  • Bolometric luminosity computations
  • Time-series photometry for variable stars

🎯 Advanced Features

  • JAX-based computations for fast, differentiable calculations
  • GPU acceleration support
  • 3D visualization of stellar surfaces and binary systems
  • Animation capabilities for time-evolving systems
  • Occlusion handling for complex geometries

Quick Start

Basic Stellar Model

import numpy as np
from spice.models import IcosphereModel
from spice.models.mesh_transform import add_rotation
from spice.spectrum import simulate_observed_flux, Blackbody

bb = Blackbody()

# Create a solar-like star
star = IcosphereModel.construct(
    n_vertices=1000,                 # Mesh resolution (number of vertices)
    radius=1.0,                      # Solar radii
    mass=1.0,                        # Solar masses
    parameters=bb.solar_parameters,
    parameter_names=bb.parameter_names,
)

# Add solid-body rotation (equatorial velocity in km/s)
star = add_rotation(star, rotation_velocity=2.0)

# Generate the disc-integrated spectrum. simulate_observed_flux expects *log10*
# wavelengths and returns an (n_wavelengths, 2) array whose columns are the
# disc-integrated emulator channels (flux and continuum; column 0 is the flux).
wavelengths = np.logspace(3, 4, 1000)            # 1000-10000 Å
flux = simulate_observed_flux(bb.intensity, star, np.log10(wavelengths))

Binary Star System

import numpy as np
import jax.numpy as jnp
from spice.models import IcosphereModel, Binary
from spice.models.binary import add_orbit, evaluate_orbit_at_times
from spice.models.mesh_view import get_mesh_view
from spice.spectrum import simulate_observed_flux, Blackbody, AB_passband_luminosity
from spice.spectrum.filter import GaiaG

bb = Blackbody()
los = jnp.array([0.0, 1.0, 0.0])  # line of sight

# Create binary components (cast to the line of sight for occlusion handling)
primary = get_mesh_view(
    IcosphereModel.construct(1000, 1.0, 1.0, bb.solar_parameters, bb.parameter_names), los)
secondary = get_mesh_view(
    IcosphereModel.construct(1000, 0.8, 0.8, bb.solar_parameters, bb.parameter_names), los)

# Assemble the system
binary = Binary.from_bodies(primary, secondary)

# Add orbital elements
binary = add_orbit(
    binary,
    P=1.0,                    # orbital period [years]
    ecc=0.1,                  # eccentricity
    T=0.0,                    # time of periastron passage [years]
    i=np.pi / 3,              # inclination [rad]
    omega=0.0,                # argument of periastron [rad]
    Omega=0.0,                # longitude of the ascending node [rad]
    mean_anomaly=0.0,         # mean anomaly at the reference time [rad]
    reference_time=0.0,       # reference time [years]
    vgamma=0.0,               # systemic velocity [km/s]
    orbit_resolution_points=50,
)

# Evaluate the orbit across phases (eclipses/occlusions resolved internally)
times = jnp.linspace(0.0, 1.0, 100)
primaries, secondaries = evaluate_orbit_at_times(binary, times)

# Combined Gaia G-band light curve
wavelengths = np.linspace(900, 40000, 1000)
gaia_g = GaiaG()
light_curve = [
    AB_passband_luminosity(
        gaia_g,
        wavelengths,
        simulate_observed_flux(bb.intensity, p1, np.log10(wavelengths))[:, 0]
        + simulate_observed_flux(bb.intensity, p2, np.log10(wavelengths))[:, 0],
    )
    for p1, p2 in zip(primaries, secondaries)
]

PHOEBE Integration

import numpy as np
import phoebe
from phoebe.parameters.dataset import _mesh_columns
from spice.models import PhoebeBinary
from spice.models.binary import evaluate_orbit
from spice.models.phoebe_utils import PhoebeConfig
from spice.spectrum import simulate_observed_flux, Blackbody

bb = Blackbody()

# Build a PHOEBE binary and compute a mesh dataset (standard PHOEBE workflow)
b = phoebe.default_binary()
times = np.linspace(0, 1, 10)
b.add_dataset('mesh', compute_times=times, columns=_mesh_columns, dataset='mesh01')
b.run_compute(coordinates='uvw', overwrite=True)

# Wrap the PHOEBE meshes for SPICE (PHOEBE models are read-only inside SPICE)
config = PhoebeConfig(b, 'mesh01')
pb = PhoebeBinary.construct(config, ['teff', 'logg', 'abun'])

# Evaluate the components at a snapshot time, then synthesise the spectrum
primary, secondary = evaluate_orbit(pb, config.times[0])
wavelengths = np.logspace(3, 4, 1000)
flux = simulate_observed_flux(bb.intensity, primary, np.log10(wavelengths))

Performance

  • JAX-powered computations for fast, vectorized operations
  • GPU acceleration support for large-scale calculations
  • Efficient mesh operations with optimized occlusion algorithms
  • Memory-efficient spectral synthesis for time-series data

Known internals caveat

Mesh area conventions (slated for cleanup)

MeshModel currently exposes two area arrays that follow different unit conventions:

Property Convention Sum over the mesh
m.areas / m.base_areas unit-sphere normalised ≈ 4π for any R
m.cast_areas / m.visible_cast_areas physical R⊙² ≈ 4π R² / ≈ π R²

Any code that integrates over the stellar surface must apply the matching cgs prefactor:

  • simulate_observed_flux integrates m.visible_cast_areas (already in R⊙²) and applies only the dimensionless dilution (R⊙ / pc)² / d_pc².
  • simulate_monochromatic_luminosity integrates m.areas (unit-sphere) and applies R² × R⊙²[cm²] to convert to cgs.

If you add a new integrator over either array, mirror the matching pattern. This convention asymmetry is a known maintainability hazard and is slated for future cleanup: once m.areas is normalised the same way as m.visible_cast_areas, the cgs prefactor in simulate_monochromatic_luminosity should be reduced to R⊙²[cm²] only, matching the structure of simulate_observed_flux.

Citation

If you use stellar-spice in your research, please cite:

@misc{spice,
      title={SPICE -- modelling synthetic spectra of stars with non-homogeneous surfaces}, 
      author={M. Jabłońska, T. Różański, L. Casagrande, H. Shah, P. A. Kołaczek-Szymański, M. Rychlicki and Yuan-Sen Ting},
      year={2025},
      eprint={2511.10998},
      archivePrefix={arXiv},
      primaryClass={astro-ph.SR},
      url={https://arxiv.org/abs/2511.10998}, 
}

Contributing

We welcome contributions! Please see our contributing guidelines for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Built with JAX for fast, differentiable computations
  • Integrates with PHOEBE for binary star modeling
  • Uses Transformer-Payne for ML-based spectral synthesis

A preprint describing SPICE is available on arXiv. See Citation if you use it in your work.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stellar_spice-1.8.0.tar.gz (595.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stellar_spice-1.8.0-py3-none-any.whl (591.1 kB view details)

Uploaded Python 3

File details

Details for the file stellar_spice-1.8.0.tar.gz.

File metadata

  • Download URL: stellar_spice-1.8.0.tar.gz
  • Upload date:
  • Size: 595.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for stellar_spice-1.8.0.tar.gz
Algorithm Hash digest
SHA256 f9be0a6a4b119aea6a820f823f3504585528a2e41ac72dd41d7f920f62278f78
MD5 6639c8ea528c16469c8455f95c1fe1fa
BLAKE2b-256 ae5c35a6c4d638fae86e18dcccd6ab2ca701242c258183ad741d44e635449bc7

See more details on using hashes here.

Provenance

The following attestation bundles were made for stellar_spice-1.8.0.tar.gz:

Publisher: release.yml on maja-jablonska/spice

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stellar_spice-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: stellar_spice-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 591.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for stellar_spice-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 48e8734c0cb41e2ea9ce471e229f19dfe31d245177a8f8bcafa91438ef5be9cd
MD5 4d2bb3177d6da424600c96db5d02ad64
BLAKE2b-256 916aeaad5b0fe5d22c74f150c84b7660ced3303846e7fc09fb170337cf17e91e

See more details on using hashes here.

Provenance

The following attestation bundles were made for stellar_spice-1.8.0-py3-none-any.whl:

Publisher: release.yml on maja-jablonska/spice

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page