skyscapes
JAX-native astrophysical scene modeling for HWO direct imaging.
What skyscapes is
skyscapes provides the scene representation that downstream HWO
simulation tools consume — a forward model that runs at variable
fidelity, from analytic sandbox models for fast iteration up to
research-grade physics for retrievals. High-fidelity scene generators
like ExoVista feed into
skyscapes through loaders (from_exovista); skyscapes does not try to
replace them.
- A
Sceneis "everything on the sky that the telescope sees" — oneSystem(a star with planets and optionally a disk) plus optional background sources (zodiacal light, background galaxies, etc.). - Source models (
Star,Planet,Disk, physical models, backgrounds) are composableeqx.Modules — swap any one without touching the rest, or swap the whole class for a higher-fidelity variant. - Loaders bridge external simulation outputs (ExoVista FITS) into the
workspace via
from_exovista(...).
The same Scene flows through both the
coronagraphoto image
simulator and the jaxEDITH
ETC, so the astrophysical content is consistent across all downstream
science products.
What skyscapes is not
- Not a radiative transfer engine. The
ExoJaxPhysicalModelis a thin adapter over ExoJAX; skyscapes does not implement its own RT. - Not an orbit propagator. Orbital mechanics live in
orbix;
Planetcomposes anAbstractOrbitrather than reimplementing one. - Not a simulator. Downstream tools
(coronagraphoto,
jaxEDITH) consume a
Sceneto produce images / count rates.
Ecosystem position
flowchart LR
src["External sources<br/>ExoVista · spectra · catalogues"]
sky(["<b>skyscapes</b><br/>Scene · System · Star · Planet · Disk · Zodi · PhysicalModel"])
opt["<b>optixstuff</b><br/>OpticalPath"]
cor["<b>coronagraphoto</b><br/>2D image simulation"]
jet["<b>jaxedith</b><br/>Scalar count rates"]
src --> sky
sky --> cor
sky --> jet
opt --> cor
opt --> jet
Architecture
A Scene composes a System (star + planets + optional disk) with an
optional Zodi background:
- Stars —
Star(wavelength- and time-dependent spectrum, ExoVista- backed) andFlatStar(constant-flux sandbox). Imported stars retain FITS metadata and optionalStarSpotsgeometry and temperatures. - Planets —
Planetowns intrinsic params (Rp_Rearth,Mp_Mearth) and composes anAbstractOrbit(from orbix) with anAbstractPhysicalModel. - Physical models —
LambertianPhysicalModel,GridPhysicalModel(wavelength/phase contrast tables),TimeSeriesPhysicalModel(wavelength/Julian-Date contrast tables),PrecomputedPhysicalModel(cached reflectivity for hot loops), andExoJaxPhysicalModel(full 2-stream RT via ExoJAX). - Disks —
ExovistaDisk,ExovistaParametricDisk,GraterDisk,CompositeDisk. - Backgrounds —
AYOZodi(AYO-convention defaults),LeinertZodi(full position-dependent Leinert+1998),PrecomputedZodi(cached flux array).
Every leaf is an eqx.Module PyTree, so JAX transforms (jit, vmap,
grad) compose end-to-end.
Quick start
The easiest path is loading an ExoVista FITS file:
import jax
jax.config.update("jax_enable_x64", True)
from skyscapes import Scene, from_exovista
system = from_exovista("path/to/exovista_system.fits", planet_spectra="auto")
scene = Scene(system=system)
The importer requires JAX x64 to preserve orbital states and epoch
precision. ExoVista's elapsed years map to Julian Dates as
2451545.0 + 365.25 * elapsed_years. The importer assigns simulation
time zero to J2000.0; this origin is not a measured observation date.
from_exovista identifies the stellar and planetary extensions from
their FITS headers, supporting both the legacy layout and the newer
layout with a starspot extension. planet_spectra="auto" keeps the
legacy phase-based model for older files and uses physical-time
contrast tables for newer files. Select "time" explicitly to retain
the sampled history in an older file, or "phase" to request a
phase-only approximation that discards activity history.
Imported stellar spectra use linear interpolation to preserve
nonnegative tabulated flux (Star(interpolation_method="linear")).
Multi-epoch stellar and time-series planet models return NaN outside
their recorded time range; a single epoch is
a static snapshot. Spectral queries remain bounded by the supplied
wavelength grid. Directly constructed Star objects retain cubic
interpolation by default.
Star.spots and Star.metadata preserve source records. Loading spot
geometry does not yet provide resolved stellar-surface propagation or
asymmetric stellar leakage through a coronagraph. Planet methods call
contrast_at_time(..., time_jd=...); existing physical models inherit
a default hook that delegates to their phase-dependent contrast.
Building one from scratch:
import jax.numpy as jnp
from orbix.orbit import KeplerianOrbit
from skyscapes import Scene, System
from skyscapes.scene import FlatStar, Planet
from skyscapes.physical_model import LambertianPhysicalModel
from skyscapes.background import AYOZodi
star = FlatStar(
Ms_kg=1.989e30,
dist_pc=10.0,
flux_phot_per_nm_m2=1e9,
)
orbit = KeplerianOrbit(
a_AU=jnp.array([1.0]),
e=jnp.array([0.0]),
W_rad=jnp.array([0.0]),
i_rad=jnp.array([jnp.pi / 3]),
w_rad=jnp.array([0.0]),
M0_rad=jnp.array([0.0]),
t0_d=jnp.array([0.0]),
)
physical_model = LambertianPhysicalModel(Ag=jnp.array([0.3]))
planet = Planet(
Rp_Rearth=jnp.array([1.0]),
Mp_Mearth=jnp.array([1.0]),
orbit=orbit,
physical_model=physical_model,
)
zodi = AYOZodi(
wavelengths_nm=jnp.linspace(400, 1000, 60),
surface_brightness_mag=22.0,
)
scene = Scene(
system=System(star=star, planets=(planet,)),
zodi=zodi,
)
Installation
pip install skyscapes
Status
This package is in early development.
Metadata
Release files for skyscapes 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| skyscapes-2.0.0.tar.gz | 104.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| skyscapes-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 228.5 kB
Release files / skyscapes-2.0.0.tar.gz
| Download URL | skyscapes-2.0.0.tar.gz |
|---|---|
| Size | 104.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f485c19593c67c24edb475fc165e337e2e06057dee61be268164972d4fe1b34a
|
|
BLAKE2b-256 checksum How to use checksums |
72a673489fbbd52220bb09b269a9b26ed08484972e183dab1a0c14aa1323e2e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / skyscapes-2.0.0-py3-none-any.whl
| Download URL | skyscapes-2.0.0-py3-none-any.whl |
|---|---|
| Size | 124.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a134e57e8f937172bad962aac3a3147f6b7a850452e89ec86d82e6d5b6aa31fe
|
|
BLAKE2b-256 checksum How to use checksums |
060952a0ab80c72f4367fbee830a077f8ebfbcf432c38f15be6319247f1b4583
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log