optixstuff

Contents

optixstuff#

optixstuff – Hardware abstractions for the HWO simulation suite.

Submodules#

Classes#

AbstractCoronagraph

Abstract interface for coronagraph performance models.

AbstractScalarCoronagraph

Base for ETC-only coronagraph models that lack 2D PSF generation.

AbstractTableCoronagraph

Base for coronagraphs backed by native-grid interpolation tables.

MultiBandCoronagraph

A broadband coronagraph as a stack of per-band models.

AbstractDetector

Abstract interface for a focal-plane detector.

Detector

Full detector model with dark current, CIC, and read noise.

IdealDetector

Detector with constant QE and minimal noise sources.

AbstractDisperser

Interface for a dispersing IFS element (lenslet array, slicer, MSA).

LensletDisperser

Lenslet-array IFS disperser (CRISPY heritage).

ExposureConfig

The physical parameters defining a single detector integration.

AbstractOpticalElement

Abstract interface for an optical element in the beam path.

AbstractUniformElement

Base for elements with spatially uniform throughput.

ConstantThroughput

An optical element with wavelength-independent throughput.

SpectralThroughput

Wavelength-dependent throughput defined by sampled (wavelength, throughput) pairs.

OpticalPath

Universal hardware container for a coronagraphic telescope.

AbstractPrimary

Abstract interface for a primary aperture.

SegmentedPrimary

A segmented hex primary that carries pupil geometry, not just scalars.

SimplePrimary

A simple circular primary mirror with a central obscuration.

AbstractSpeckleField

Abstract interface for time-varying speckle fields.

YippyCoronagraph

Coronagraph performance model backed by a yippy YIP interpolation table.

Functions#

clock_induced_charge(...)

Draw clock-induced charge electrons from a Poisson distribution.

dark_current(dark_current_rate_e_per_s, ...)

Draw dark current electrons from a Poisson distribution.

read_noise(read_noise_e, num_frames, shape, prng_key)

Draw read noise from a Gaussian distribution.

Package Contents#

class optixstuff.AbstractCoronagraph[source]#

Bases: equinox.Module

Abstract interface for coronagraph performance models.

Provides scalar performance curves (for ETC use), single-PSF generation, and a sampling-explicit image contract (for image simulation): stellar_map / source_psfs / background_transmission / extended_scene serve maps at the caller’s requested pixel scale and shape, so backend-internal grids never leak downstream. Implementations can be backed by pre-computed interpolation tables (subclass AbstractTableCoronagraph, which serves the image contract from native-grid tables), physical wavefront propagation, or analytical models.

All wavelength arguments are in nanometres throughout. All separations and pixel scales are in lambda/D units – the contract is dimensionless optics; angle conversions are the telescope primary’s business.

pixel_scale_lod: equinox.AbstractVar[float]#

Native pixel scale in lambda/D per pixel.

IWA: equinox.AbstractVar[float]#

Inner working angle in lambda/D.

OWA: equinox.AbstractVar[float]#

Outer working angle in lambda/D.

abstractmethod throughput(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Core (off-axis planet) throughput.

Args:

separation_lod: Angular separation in lambda/D. wavelength_nm: Wavelength in nanometres. time_s: Time since mission start in seconds.

Returns:

Fractional throughput in [0, 1].

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod core_area(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Photometric aperture area in (lambda/D)^2.

Args:

separation_lod: Angular separation in lambda/D. wavelength_nm: Wavelength in nanometres. time_s: Time since mission start in seconds.

Returns:

Core area in (lambda/D)^2.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod core_mean_intensity(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Mean stellar intensity within the photometric aperture.

Args:

separation_lod: Angular separation in lambda/D. wavelength_nm: Wavelength in nanometres. time_s: Time since mission start in seconds.

Returns:

Mean stellar leakage intensity in (lambda/D)^-2.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod occulter_transmission(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Off-axis (sky/zodi) transmission through the occulter.

Args:

separation_lod: Angular separation in lambda/D. wavelength_nm: Wavelength in nanometres. time_s: Time since mission start in seconds.

Returns:

Fractional sky transmission in [0, 1].

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod on_axis_psf(wavelength_nm, pixel_scale_rad, npixels)[source]#

On-axis (stellar leakage) PSF.

Returns the coronagraphic PSF for an on-axis point source, normalized to unit stellar flux before the coronagraph. For a finite stellar diameter use stellar_map(), which carries the diameter axis this signature lacks.

Args:

wavelength_nm: Wavelength in nanometres. pixel_scale_rad: Output pixel scale in radians/pixel. npixels: Output array side length in pixels. Must be a

Python int (not a JAX array) as it determines the output shape at compile time.

Returns:

2D float array of shape (npixels, npixels).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

abstractmethod off_axis_psf(wavelength_nm, separation_lod, pixel_scale_rad, npixels)[source]#

Off-axis PSF at a given angular separation.

Args:

wavelength_nm: Wavelength in nanometres. separation_lod: Source separation in lambda/D. pixel_scale_rad: Output pixel scale in radians/pixel. npixels: Output array side length in pixels. Must be a

Python int (not a JAX array) as it determines the output shape at compile time.

Returns:

2D float array of shape (npixels, npixels).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • separation_lod (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

abstractmethod stellar_map(wavelength_nm, stellar_diam_lod, *, pixel_scale_lod, shape)[source]#

On-axis stellar leakage map at the requested sampling.

Args:

wavelength_nm: Wavelength in nanometres. stellar_diam_lod: Stellar angular diameter in lambda/D. pixel_scale_lod: Target pixel scale in lambda/D per pixel. shape: Target array shape (ny, nx).

Returns:

Map of shape shape in fraction of pre-coronagraph stellar photons per target pixel.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • stellar_diam_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

abstractmethod source_psfs(wavelength_nm, x_lod, y_lod, *, pixel_scale_lod, shape)[source]#

Off-axis point-source PSFs at the requested sampling.

Args:

wavelength_nm: Wavelength in nanometres. x_lod: Source x-coordinates in lambda/D, shape (K,). y_lod: Source y-coordinates in lambda/D, shape (K,). pixel_scale_lod: Target pixel scale in lambda/D per pixel. shape: Target array shape (ny, nx).

Returns:

Stack of shape (K, ny, nx) in fraction of source photons per target pixel.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • x_lod (jax.typing.ArrayLike)

  • y_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

abstractmethod background_transmission(wavelength_nm, *, pixel_scale_lod, shape)[source]#

Per-pixel transmission map for a spatially uniform background.

Args:

wavelength_nm: Wavelength in nanometres. pixel_scale_lod: Target pixel scale in lambda/D per pixel. shape: Target array shape (ny, nx).

Returns:

Dimensionless transmission map of shape shape (value semantics, not a flux).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

abstractmethod extended_scene(scene_map, map_pixel_scale_lod, wavelength_nm, *, pixel_scale_lod, shape, rotation_deg=0.0)[source]#

Render an extended incoherent scene through the coronagraph.

Args:
scene_map: Per-pixel source intensity in any units; the

output carries the same units per target pixel.

map_pixel_scale_lod: Pixel scale of scene_map in

lambda/D per pixel.

wavelength_nm: Wavelength in nanometres. pixel_scale_lod: Target pixel scale in lambda/D per pixel. shape: Target array shape (ny, nx). rotation_deg: CCW rotation applied when mapping the scene

into the coronagraph frame (sky-to-detector roll).

Returns:

The scene redistributed by the per-position off-axis PSFs, shape shape.

Parameters:
  • scene_map (jaxtyping.Array)

  • map_pixel_scale_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • rotation_deg (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.AbstractScalarCoronagraph[source]#

Bases: AbstractCoronagraph

Base for ETC-only coronagraph models that lack 2D PSF generation.

Stubs out the single-PSF interface and the sampling-explicit image contract with zero arrays so the class satisfies AbstractCoronagraph without requiring a full optical model. Do NOT use this base for a model that carries native-grid tables – subclass AbstractTableCoronagraph instead, or the image pipeline will silently render zeros.

on_axis_psf(wavelength_nm, pixel_scale_rad, npixels)[source]#

Return a zero PSF (not implemented for scalar-only models).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

off_axis_psf(wavelength_nm, separation_lod, pixel_scale_rad, npixels)[source]#

Return a zero PSF (not implemented for scalar-only models).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • separation_lod (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

stellar_map(wavelength_nm, stellar_diam_lod, *, pixel_scale_lod, shape)[source]#

Return a zero map (not implemented for scalar-only models).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • stellar_diam_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

source_psfs(wavelength_nm, x_lod, y_lod, *, pixel_scale_lod, shape)[source]#

Return zero PSFs (not implemented for scalar-only models).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • x_lod (jax.typing.ArrayLike)

  • y_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

background_transmission(wavelength_nm, *, pixel_scale_lod, shape)[source]#

Return a zero map (not implemented for scalar-only models).

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

extended_scene(scene_map, map_pixel_scale_lod, wavelength_nm, *, pixel_scale_lod, shape, rotation_deg=0.0)[source]#

Return a zero map (not implemented for scalar-only models).

Parameters:
  • scene_map (jaxtyping.Array)

  • map_pixel_scale_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • rotation_deg (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.AbstractTableCoronagraph[source]#

Bases: AbstractCoronagraph

Base for coronagraphs backed by native-grid interpolation tables.

Declares the table SPI – the native-grid maps a table backend holds (stellar_intens, create_psfs, sky_trans, psf_shape, psf_datacube) – and serves the sampling-explicit image contract from it with flux-conserving resamples to the requested target grid. Scalar performance curves remain the subclass’s business (a table backend interpolates its own curve tables).

The tables are monochromatic by construction (a YIP is a per-band file), so the served maps ignore wavelength_nm beyond the caller’s own lambda/D sampling conversion; stack per-band instances in a MultiBandCoronagraph for a broadband model.

psf_shape: equinox.AbstractVar[tuple]#

Native map shape (ny, nx) shared by the table members.

sky_trans: equinox.AbstractVar[jaxtyping.Array]#

Native-grid transmission map for a spatially uniform background.

psf_datacube: equinox.AbstractVar[jaxtyping.Array | None]#

Optional per-source-position PSF library for extended scenes.

None means the table was built without one; extended_scene() then raises. Full (ny, nx, ny, nx) and quarter-symmetric (ny//2+1, nx//2+1, ny, nx) layouts are supported.

abstractmethod stellar_intens(stellar_diam_lod)[source]#

Native-grid stellar leakage map for a stellar angular diameter.

The diameter axis is a genuine table capability (a YIP tabulates finite-size stellar maps); implementations interpolate over it.

Parameters:

stellar_diam_lod (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

abstractmethod create_psfs(x_lod, y_lod)[source]#

Native-grid off-axis PSF stack at (x_lod, y_lod), shape (K, ny, nx).

Parameters:
  • x_lod (jax.typing.ArrayLike)

  • y_lod (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

on_axis_psf(wavelength_nm, pixel_scale_rad, npixels)[source]#

Point-source stellar leakage map on the native grid.

Table backends serve their native sampling; the requested pixel_scale_rad / npixels are accepted for interface conformance only. Use stellar_map() for target-sampled maps and finite stellar diameters.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

off_axis_psf(wavelength_nm, separation_lod, pixel_scale_rad, npixels)[source]#

Off-axis PSF at +x separation on the native grid.

Sampling arguments are accepted for interface conformance only; use source_psfs() for target-sampled maps.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • separation_lod (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

stellar_map(wavelength_nm, stellar_diam_lod, *, pixel_scale_lod, shape)[source]#

Native stellar_intens resampled (flux-conserving) to target.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • stellar_diam_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

source_psfs(wavelength_nm, x_lod, y_lod, *, pixel_scale_lod, shape)[source]#

Native create_psfs stack resampled (flux-conserving) to target.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • x_lod (jax.typing.ArrayLike)

  • y_lod (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

background_transmission(wavelength_nm, *, pixel_scale_lod, shape)[source]#

Native sky_trans resampled to target with value semantics.

A transmission is a per-pixel value, not a flux, so the pixel-area scaling of the flux-conserving resample is undone.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

Return type:

jaxtyping.Array

extended_scene(scene_map, map_pixel_scale_lod, wavelength_nm, *, pixel_scale_lod, shape, rotation_deg=0.0)[source]#

Scene convolved with the psf_datacube PSF library.

Resamples the scene to the native source grid (applying the sky-to-detector rotation), convolves via the full or quarter-symmetric datacube, and resamples the result to the target grid.

Raises:
ValueError: if psf_datacube is None, or its

source grid matches neither the full nor the quarter PSF shape.

Parameters:
  • scene_map (jaxtyping.Array)

  • map_pixel_scale_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_lod (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • rotation_deg (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.MultiBandCoronagraph(band_centers_nm, bands, *, reference_wavelength_nm=None)[source]#

Bases: AbstractCoronagraph

A broadband coronagraph as a stack of per-band models.

Every contract call dispatches to the band whose declared center is nearest the requested wavelength_nm and forwards the call unchanged. Because the contract is sampling-explicit in lambda/D, chromatic magnification needs no handling here: the caller already converts its detector grid to lambda/D at each wavelength.

The per-band models can be anything implementing AbstractCoronagraph – per-band YIP tables (optixstuff.YippyCoronagraph) or per-wavelength compiled views of a live propagation model – and can be mixed.

wavelength_nm must be concrete (a Python/NumPy scalar, not a traced JAX value) at dispatch time: bands are distinct pytrees with distinct shapes, so the selection is Python control flow. This matches the per-bin structure of the rate pipeline, where the wavelength is a static observation parameter.

Scalar metadata (pixel_scale_lod / IWA / OWA) is served from the band nearest reference_wavelength_nm (default: the first band).

band_centers_nm: tuple#
bands: tuple#
reference_wavelength_nm: float#
band(wavelength_nm)[source]#

The band model whose center is nearest wavelength_nm.

Return type:

AbstractCoronagraph

property pixel_scale_lod: float#

Native pixel scale of the reference band.

Return type:

float

property IWA: float#

Inner working angle of the reference band.

Return type:

float

property OWA: float#

Outer working angle of the reference band.

Return type:

float

throughput(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Core throughput from the nearest band.

core_area(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Photometric aperture area from the nearest band.

core_mean_intensity(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Mean stellar leakage from the nearest band.

occulter_transmission(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Sky transmission from the nearest band.

on_axis_psf(wavelength_nm, pixel_scale_rad, npixels)[source]#

On-axis PSF from the nearest band.

off_axis_psf(wavelength_nm, separation_lod, pixel_scale_rad, npixels)[source]#

Off-axis PSF from the nearest band.

stellar_map(wavelength_nm, stellar_diam_lod, *, pixel_scale_lod, shape)[source]#

Stellar leakage map from the nearest band.

source_psfs(wavelength_nm, x_lod, y_lod, *, pixel_scale_lod, shape)[source]#

Off-axis PSF stack from the nearest band.

background_transmission(wavelength_nm, *, pixel_scale_lod, shape)[source]#

Background transmission map from the nearest band.

extended_scene(scene_map, map_pixel_scale_lod, wavelength_nm, *, pixel_scale_lod, shape, rotation_deg=0.0)[source]#

Extended-scene render from the nearest band.

class optixstuff.AbstractDetector[source]#

Bases: equinox.Module

Abstract interface for a focal-plane detector.

Provides both scalar noise rates (for ETC use) and stochastic noise realization (for image simulation). All concrete implementations must define the hardware parameters listed as AbstractVar fields.

pixel_scale_arcsec: equinox.AbstractVar[float]#

Detector plate scale in arcsec/pixel.

quantum_efficiency: equinox.AbstractVar[float]#

Baseline quantum efficiency as a fraction in [0, 1].

dark_current_rate_e_per_s: equinox.AbstractVar[float]#

Dark current rate in electrons/pixel/second.

read_noise_e: equinox.AbstractVar[float]#

Read noise in electrons RMS per pixel per read.

clock_induced_charge_rate_e_per_frame: equinox.AbstractVar[float]#

Clock-induced charge in electrons/pixel/frame.

frame_time_s: equinox.AbstractVar[float]#

Integration time per frame/read in seconds.

read_time_s: equinox.AbstractVar[float]#

Time per read cycle in seconds (for RN^2/t_read in ETC).

dqe: equinox.AbstractVar[float]#

QE degradation factor (multiplicative correction over mission life).

shape: equinox.AbstractVar[tuple[int, int]]#

Detector dimensions (ny, nx) in pixels.

abstractmethod get_qe(wavelength_nm)[source]#

Quantum efficiency at a given wavelength.

Args:

wavelength_nm: Wavelength in nanometres.

Returns:

QE as a fraction in [0, 1].

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod scalar_noise_rate(n_pix, t_photon)[source]#

Total scalar noise variance rate for the ETC.

Returns the combined noise variance per unit time (electrons^2/s) for a photometric aperture of n_pix pixels.

Args:

n_pix: Number of pixels in the photometric aperture. t_photon: Photon counting integration time in seconds.

Returns:

Noise variance rate in electrons^2/second.

Parameters:
  • n_pix (jax.typing.ArrayLike)

  • t_photon (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod readout(image_rate, exposure_time_s, prng_key)[source]#

Apply stochastic noise realization to a photon rate image.

Converts photon rates to detected electrons including QE, dark current, CIC, and read noise.

Args:

image_rate: Incident photon rate array in ph/s/pixel. exposure_time_s: ExposureConfig time in seconds. prng_key: JAX PRNG key (required, no default).

Returns:

Detected electrons array, same shape as image_rate.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

readout_source_electrons(image_rate, exposure_time_s, prng_key)[source]#

Poisson-sample incident photons and convert to electrons via QE.

This is the source-dependent half of detector readout: photon arrival statistics and quantum-efficiency selection. Dark current, CIC, and read noise are handled separately by readout_noise_electrons() so that multi-source exposures do not double-count the source-independent noise floor.

Args:

image_rate: Incident photon rate array in ph/s/pixel. exposure_time_s: ExposureConfig time in seconds. prng_key: JAX PRNG key.

Returns:

Photo-electron counts, same shape as image_rate.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

readout_source_electrons_thinned(image_rate, exposure_time_s, prng_key)[source]#

Fast equivalent of readout_source_electrons() via Poisson thinning.

Distributionally identical to the explicit Poisson-then-Binomial chain (Poisson thinning theorem: Binomial(Poisson(L), p) ~ Poisson(L * p)), but ~3x faster because it skips the Binomial draw and never materialises the intermediate photon count. Use in performance-critical paths (animation rendering, yield runs) when the photon count is not needed downstream.

The marginal distribution of returned electrons is identical to readout_source_electrons(). The two methods produce different specific realisations even with the same key.

Args:

image_rate: Incident photon rate array in ph/s/pixel. exposure_time_s: ExposureConfig time in seconds. prng_key: JAX PRNG key.

Returns:

Photo-electron counts, same shape as image_rate.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

noise_variance(image_rate, exposure_time_s)[source]#

Deterministic per-pixel total noise variance in electrons^2.

The expected variance at each pixel for an incident photon-rate image – the deterministic companion to readout(). Combines source shot noise (Poisson on detected electrons) with the source-independent floor (dark current, clock-induced charge, read noise):

N = QE * rate * t
    + dark_rate * t
    + CIC_rate * n_frames
    + read_noise^2 * n_frames

with n_frames = ceil(t / frame_time_s). Use 1 / noise_variance(...) as inverse-variance weights for least-squares spectral extraction or its GLS covariance, where the shot term carries the wavelength dependence.

Args:

image_rate: Incident photon rate [ph/s/pixel], any shape. exposure_time_s: Exposure time in seconds.

Returns:

Per-pixel noise variance [electrons^2], same shape as image_rate.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

abstractmethod readout_noise_electrons(exposure_time_s, prng_key)[source]#

Source-independent detector noise (dark + CIC + read).

Each call draws a fresh noise realization of shape self.shape; consumers add exactly one such draw per exposure regardless of how many sources were co-added via readout_source_electrons().

Args:

exposure_time_s: ExposureConfig time in seconds. prng_key: JAX PRNG key.

Returns:

Noise-electron array of shape self.shape.

Parameters:
  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

class optixstuff.Detector(pixel_scale_arcsec, shape, quantum_efficiency=1.0, dark_current_rate_e_per_s=0.0, read_noise_e=0.0, clock_induced_charge_rate_e_per_frame=0.0, frame_time_s=1.0, read_time_s=0.05, dqe=0.0, qe_curve=None)[source]#

Bases: AbstractDetector

Full detector model with dark current, CIC, and read noise.

Suitable for detailed noise simulations where all detector noise sources matter. Uses Poisson statistics for dark/CIC and Gaussian for read noise, matching the coronagraphoto convention.

Warning: num_frames = jnp.ceil(exposure_time_s / frame_time_s) is kept as a float. Never cast it to int inside JIT – that triggers a ConcretizationTypeError when exposure_time_s is traced.

Parameters:
  • pixel_scale_arcsec (float)

  • shape (tuple[int, int])

  • quantum_efficiency (float)

  • dark_current_rate_e_per_s (float)

  • read_noise_e (float)

  • clock_induced_charge_rate_e_per_frame (float)

  • frame_time_s (float)

  • read_time_s (float)

  • dqe (float)

  • qe_curve (tuple[jax.typing.ArrayLike, jax.typing.ArrayLike] | None)

pixel_scale_arcsec: float#

Detector plate scale in arcsec/pixel.

quantum_efficiency: float#

Baseline quantum efficiency as a fraction in [0, 1].

dark_current_rate_e_per_s: float#

Dark current rate in electrons/pixel/second.

read_noise_e: float#

Read noise in electrons RMS per pixel per read.

clock_induced_charge_rate_e_per_frame: float#

Clock-induced charge in electrons/pixel/frame.

frame_time_s: float#

Integration time per frame/read in seconds.

read_time_s: float#

Time per read cycle in seconds (for RN^2/t_read in ETC).

dqe: float#

QE degradation factor (multiplicative correction over mission life).

shape: tuple[int, int]#

Detector dimensions (ny, nx) in pixels.

_qe_interp: interpax.Interpolator1D | None#
get_qe(wavelength_nm)[source]#

Quantum efficiency at a wavelength.

Interpolates the qe_curve if one was supplied (linear, zero outside the measured range); otherwise returns the scalar quantum_efficiency.

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

scalar_noise_rate(n_pix, t_photon)[source]#

Combined dark + CIC noise variance rate.

Parameters:
  • n_pix (jax.typing.ArrayLike)

  • t_photon (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

readout_noise_electrons(exposure_time_s, prng_key)[source]#

Dark current + CIC + read noise (source-independent).

Parameters:
  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

readout(image_rate, exposure_time_s, prng_key)[source]#

Full detector readout: source electrons + all noise sources.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

__repr__()[source]#

One-line summary of shape, plate scale, QE, and noise sources.

Return type:

str

class optixstuff.IdealDetector(pixel_scale_arcsec, shape, quantum_efficiency=1.0, dark_current_rate_e_per_s=0.0, read_noise_e=0.0, clock_induced_charge_rate_e_per_frame=0.0, frame_time_s=1.0, read_time_s=0.05, dqe=0.0)[source]#

Bases: AbstractDetector

Detector with constant QE and minimal noise sources.

Suitable for broadband imager studies where wavelength-dependent QE variation is not important and CIC/read noise are negligible.

Parameters:
pixel_scale_arcsec: float#

Detector plate scale in arcsec/pixel.

quantum_efficiency: float#

Baseline quantum efficiency as a fraction in [0, 1].

dark_current_rate_e_per_s: float#

Dark current rate in electrons/pixel/second.

read_noise_e: float#

Read noise in electrons RMS per pixel per read.

clock_induced_charge_rate_e_per_frame: float#

Clock-induced charge in electrons/pixel/frame.

frame_time_s: float#

Integration time per frame/read in seconds.

read_time_s: float#

Time per read cycle in seconds (for RN^2/t_read in ETC).

dqe: float#

QE degradation factor (multiplicative correction over mission life).

shape: tuple[int, int]#

Detector dimensions (ny, nx) in pixels.

get_qe(wavelength_nm)[source]#

Return constant QE, ignoring wavelength.

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

scalar_noise_rate(n_pix, t_photon)[source]#

Combined dark + CIC noise variance rate.

Read noise is not included here as it scales per-read, not per-second. Callers add (read_noise_e^2 * n_reads) / t_exp separately.

Parameters:
  • n_pix (jax.typing.ArrayLike)

  • t_photon (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

readout_noise_electrons(exposure_time_s, prng_key)[source]#

Dark current only – IdealDetector has no CIC or read noise.

Parameters:
  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

readout(image_rate, exposure_time_s, prng_key)[source]#

Full detector readout: source electrons + dark current.

Parameters:
  • image_rate (jaxtyping.Array)

  • exposure_time_s (jax.typing.ArrayLike)

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

__repr__()[source]#

One-line summary of shape, plate scale, QE, and dark current.

Return type:

str

optixstuff.clock_induced_charge(clock_induced_charge_rate_e_per_frame, num_frames, shape, prng_key)[source]#

Draw clock-induced charge electrons from a Poisson distribution.

Args:

clock_induced_charge_rate_e_per_frame: CIC rate in electrons/pixel/frame. num_frames: Number of frames (kept as float for JIT safety). shape: Detector shape (ny, nx). prng_key: PRNG key.

Returns:

CIC electrons, shape (ny, nx).

Parameters:
  • clock_induced_charge_rate_e_per_frame (float)

  • num_frames (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

optixstuff.dark_current(dark_current_rate_e_per_s, exposure_time_s, shape, prng_key)[source]#

Draw dark current electrons from a Poisson distribution.

Args:

dark_current_rate_e_per_s: Dark current rate in electrons/s/pixel. exposure_time_s: ExposureConfig time in seconds. shape: Detector shape (ny, nx). prng_key: PRNG key.

Returns:

Dark current electrons, shape (ny, nx).

Parameters:
  • dark_current_rate_e_per_s (float)

  • exposure_time_s (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

optixstuff.read_noise(read_noise_e, num_frames, shape, prng_key)[source]#

Draw read noise from a Gaussian distribution.

Total read noise sigma = sqrt(num_frames) * read_noise_per_read.

Args:

read_noise_e: Read noise in electrons/pixel/read. num_frames: Number of frames. shape: Detector shape (ny, nx). prng_key: PRNG key.

Returns:

Read noise electrons, shape (ny, nx).

Parameters:
  • read_noise_e (float)

  • num_frames (jax.typing.ArrayLike)

  • shape (tuple[int, int])

  • prng_key (jaxtyping.Array)

Return type:

jaxtyping.Array

class optixstuff.AbstractDisperser[source]#

Bases: equinox.Module

Interface for a dispersing IFS element (lenslet array, slicer, MSA).

Only the scalar/ETC face is defined here. Render geometry lives in coronachrome and dispatches on the concrete descriptor type.

abstractmethod spectral_resolution(wavelength_nm)[source]#

Resolving power R = lambda / dlambda at the given wavelength.

abstractmethod spectral_sampling()[source]#

Detector pixels per resolution element.

abstractmethod n_pix_spread(wavelength_min_nm, wavelength_max_nm)[source]#

Detector pixels a single spaxel spectrum spans across a band.

abstractmethod throughput(wavelength_nm)[source]#

Disperser optical throughput in [0, 1] at the given wavelength.

class optixstuff.LensletDisperser[source]#

Bases: AbstractDisperser

Lenslet-array IFS disperser (CRISPY heritage).

Config only. The render geometry (IR build) is performed by coronachrome, which reads these fields. Scalar/ETC methods derive from dispersion_coeffs + pix_per_reselt so the dispersion model is the single source of truth.

psflet_params[0] is the PSFlet core width in detector pixels (Gaussian sigma or Moffat alpha); any trailing entries are dimensionless shape parameters (e.g. Moffat beta). psflet_ref_nm is the wavelength at which that core width is specified: a diffraction-limited spot scales as lambda f / D, so at fixed pixel scale coronachrome scales the core width by lambda / psflet_ref_nm per wavelength (the shape parameters do not scale).

sky_pitch_arcsec is the lenslet pitch projected on sky, a plain angle in arcseconds (the focal-plane cube a render layer consumes lives on a fixed angular grid, so no reference wavelength is involved). It makes the spatial sampling an instrument property: the render layer derives focal-plane pixels per lenslet as the ratio of this pitch to the cube’s angular plate scale instead of taking a free knob. None means unspecified.

psflet_pack_path is a reference to a frozen PSFlet template pack file (used with psflet_kind="template"), the way throughput_element carries the blaze curve: config only, the render layer loads it.

pitch_m: float#
pixsize_m: float#
angle_rad: float#
lam_ref_nm: float#
pix_per_reselt: float#
dispersion_coeffs: jax.Array#
psflet_params: jax.Array#
psflet_ref_nm: float#
grid_kind: str#
n_lenslets: int#
psflet_kind: str#
detector_shape: tuple[int, int]#
throughput_element: optixstuff.optical_elements.AbstractOpticalElement#
sky_pitch_arcsec: float | None = None#
psflet_pack_path: str | None#
_dispersion_px(wavelength_nm)[source]#

Spectral-axis detector offset [px] for the wavelength(s).

spectral_resolution(wavelength_nm)[source]#

R = (local px per unit log-lambda) / pixels-per-resolution-element.

spectral_sampling()[source]#

Detector pixels per resolution element.

n_pix_spread(wavelength_min_nm, wavelength_max_nm)[source]#

Spectral trace length [px] across a band, plus a PSFlet-width margin.

throughput(wavelength_nm)[source]#

Disperser optical throughput in [0, 1], shaped like wavelength_nm.

Delegates to the composed throughput element (ConstantThroughput by default; SpectralThroughput for a tabulated blaze/transmission curve) and broadcasts to the wavelength shape so the output shape is canonical regardless of the backing element.

class optixstuff.ExposureConfig[source]#

Bases: equinox.Module

The physical parameters defining a single detector integration.

All fields can be scalars (for a single event) or vectors (for a sequence), depending on how the factories are composed.

start_time_jd: jax.numpy.ndarray#
exposure_time_s: jax.numpy.ndarray#
central_wavelength_nm: jax.numpy.ndarray#
bin_width_nm: jax.numpy.ndarray#
position_angle_deg: jax.numpy.ndarray#
classmethod in_axes(**vectorized_axes)[source]#

Helper to generate in_axes structure for JAX vmap over an ExposureConfig.

Usage:

# Vectorize over wavelength (axis 0), keep time constant in_axes = ExposureConfig.in_axes(central_wavelength_nm=0, bin_width_nm=0)

class optixstuff.AbstractOpticalElement[source]#

Bases: equinox.Module

Abstract interface for an optical element in the beam path.

Elements reduce photon flux via wavelength-dependent throughput. The ETC calls get_throughput() for scalar efficiency calculations. The simulator calls apply() to attenuate 2D photon arrays.

Both methods are abstract: use AbstractUniformElement for elements with spatially uniform throughput, which provides a default apply().

abstractmethod get_throughput(wavelength_nm)[source]#

Fractional throughput at a given wavelength.

Args:

wavelength_nm: Wavelength in nanometres.

Returns:

Scalar throughput in [0, 1].

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

abstractmethod apply(arr, wavelength_nm)[source]#

Apply this element to a 2D photon array.

Args:

arr: Input photon rate array [ph/s/pixel]. wavelength_nm: Wavelength in nanometres.

Returns:

Attenuated photon rate array, same shape as arr.

Parameters:
  • arr (jaxtyping.Array)

  • wavelength_nm (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.AbstractUniformElement[source]#

Bases: AbstractOpticalElement

Base for elements with spatially uniform throughput.

Provides a default apply() that multiplies the array by the scalar throughput. Override apply() for elements with spatially varying transmission (e.g., field-dependent filter transmission maps).

apply(arr, wavelength_nm)[source]#

Apply uniform throughput to a photon array.

Parameters:
  • arr (jaxtyping.Array)

  • wavelength_nm (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.ConstantThroughput[source]#

Bases: AbstractUniformElement

An optical element with wavelength-independent throughput.

Useful for modeling simple attenuators, beamsplitters, or as a placeholder during instrument design studies.

throughput: float#
name: str#
get_throughput(wavelength_nm)[source]#

Return constant throughput, ignoring wavelength.

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

__repr__()[source]#

One-line summary of throughput value.

Return type:

str

class optixstuff.SpectralThroughput(wavelengths_nm, throughputs)[source]#

Bases: AbstractUniformElement

Wavelength-dependent throughput defined by sampled (wavelength, throughput) pairs.

Linear interpolation between samples; throughput is zero outside the defined wavelength range.

Represents any tabulated wavelength-dependent throughput in the optical path: bandpass filters, dichroics, mirror reflectivity, coating losses, ADCs, blocking filters, etc.

Parameters:
  • wavelengths_nm (jaxtyping.Array)

  • throughputs (jaxtyping.Array)

wavelengths_nm: jaxtyping.Array#
throughputs: jaxtyping.Array#
interp: interpax.Interpolator1D#
get_throughput(wavelength_nm)[source]#

Interpolate throughput at the requested wavelength.

Parameters:

wavelength_nm (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

__repr__()[source]#

One-line summary of throughput-table extent and sample count.

Return type:

str

class optixstuff.OpticalPath[source]#

Bases: equinox.Module

Universal hardware container for a coronagraphic telescope.

Bundles a primary mirror, ordered chain of attenuating elements, a coronagraph, and a detector into a single configuration object. This is the interface passed to simulators (coronagraphoto), exposure time calculators (jaxEDITH), and IFS instruments (coronachrome).

Args:

primary: Primary mirror description. attenuating_elements: Ordered tuple of throughput elements

between the primary and coronagraph (mirrors, filters, etc.).

coronagraph: Coronagraph performance model. detector: Focal-plane detector model. disperser: Optional IFS disperser descriptor; None for imaging mode. n_channels: Number of parallel identical optical-path copies

(AYO shorthand, multiplicative factor on count rates; not a spectral channel count). Default 1.0.

npix_multiplier: IFS signal-spread multiplier on detector pixel

counts. Default 1.0.

speckle: Optional time-varying speckle field (the stochastic

wavefront-error residual on top of the deterministic coronagraph leakage floor); None for a perfect-wavefront path.

primary: optixstuff.primary.AbstractPrimary#
attenuating_elements: tuple[optixstuff.optical_elements.AbstractOpticalElement, Ellipsis]#
coronagraph: optixstuff.coronagraph.AbstractCoronagraph#
detector: optixstuff.detector.AbstractDetector#
disperser: optixstuff.disperser.AbstractDisperser | None = None#
n_channels: float = 1.0#
npix_multiplier: float = 1.0#
speckle: optixstuff.speckle.AbstractSpeckleField | None = None#
classmethod from_default_setup(coronagraph, *, diameter_m=6.0, obscuration=0.0, attenuating_throughput=1.0, detector_shape=(512, 512), pixel_scale_arcsec=0.01, quantum_efficiency=0.9, dark_current_rate_e_per_s=0.0, n_channels=1.0, npix_multiplier=1.0, speckle=None)[source]#

Build an OpticalPath with reasonable HWO-like defaults.

Convenience for notebook / dev-script work: spin up a working OpticalPath by specifying only the coronagraph. All other parameters get sensible defaults that can be overridden.

Args:
coronagraph: One of:
  • an AbstractCoronagraph instance (used as-is),

  • a YIP path (str or pathlib.Path, wrapped with YippyCoronagraph),

  • a yippy.EqxCoronagraph instance (wrapped via YippyCoronagraph(backend=...) so callers can keep using existing yippy code without rebuilding).

diameter_m: Primary mirror diameter [m]. Default 6.0 (HWO

EAC1 baseline).

obscuration: Linear central-obscuration fraction. Default 0. attenuating_throughput: Combined throughput of the optical

chain (one ConstantThroughput). Default 1.0 – a perfect path; override for realistic studies.

detector_shape: Detector (ny, nx) in pixels. Default

(512, 512).

pixel_scale_arcsec: Detector plate scale [arcsec/px]. Default

0.01.

quantum_efficiency: Default 0.9. dark_current_rate_e_per_s: Default 0.0 e-/s/px (perfect detector;

callers add realistic noise when needed).

n_channels: AYO parallel-path multiplier. Default 1.0. npix_multiplier: IFS signal-spread multiplier. Default 1.0. speckle: Optional speckle field attached to the path. Default

None – a perfect-wavefront path.

Returns:

A ready-to-use OpticalPath.

Parameters:
Return type:

OpticalPath

system_throughput(wavelength_nm)[source]#

Total throughput of all attenuating elements.

Args:

wavelength_nm: Wavelength in nanometres.

Returns:

Combined fractional throughput in [0, 1].

Parameters:

wavelength_nm (float)

Return type:

float

__repr__()[source]#

Tree-shaped summary of every component.

Return type:

str

class optixstuff.AbstractPrimary[source]#

Bases: equinox.Module

Abstract interface for a primary aperture.

Any concrete implementation must provide the diameter and collecting area of the primary mirror as scalar values in SI units. These are consumed by exposure time calculators and simulation tools alike.

diameter_m: equinox.AbstractVar[float]#

Primary mirror diameter in metres.

area_m2: equinox.AbstractVar[float]#

Effective collecting area in square metres.

class optixstuff.SegmentedPrimary(diameter_m, area_m2, n_rings, n_segments, segment_gap_m, segment_shape='hexagon', segment_point_to_point_m=None, inscribed_diameter_m=None)[source]#

Bases: AbstractPrimary

A segmented hex primary that carries pupil geometry, not just scalars.

Beyond the diameter and collecting area every primary provides, this describes the segment layout – ring count, segment count, gap, shape – so a diffraction backend (e.g. dLux) can build the pupil from it. optixstuff only DESCRIBES the geometry; it does not propagate wavefronts.

Args:

diameter_m: Circumscribing diameter in metres. area_m2: Effective collecting area in square metres (gap/fill corrected). n_rings: Number of segment rings around the centre segment. n_segments: Total segment count (1 + 3 n (n + 1) for a full layout). segment_gap_m: Inter-segment optical gap in metres. segment_shape: Segment shape; only "hexagon" is supported today.

Parameters:
  • diameter_m (float)

  • area_m2 (float)

  • n_rings (int)

  • n_segments (int)

  • segment_gap_m (float)

  • segment_shape (str)

  • segment_point_to_point_m (float | None)

  • inscribed_diameter_m (float | None)

_diameter_m: float#
_area_m2: float#
segment_gap_m: float#
segment_point_to_point_m: float | None#
inscribed_diameter_m: float | None#
n_rings: int#
n_segments: int#
segment_shape: str#
property diameter_m: float#

Circumscribing diameter in metres.

Return type:

float

property area_m2: float#

Effective collecting area in square metres.

Return type:

float

property segment_flat_to_flat_m: float#

Segment flat-to-flat size in metres.

Exact (point_to_point * sqrt(3) / 2) when the segment size is given; otherwise the legacy circumscribing approximation diameter / (2 n_rings + 1).

Return type:

float

property segment_pitch_m: float#

Centre-to-centre distance of adjacent segments (flat-to-flat + gap).

Return type:

float

property segment_centres_m#

(n_segments, 2) segment centre (x, y) positions in metres.

A flat-top hexagonal lattice (flats up, points along x), the convention of the HWO EAC baseline pupils: the centre segment is first, and adjacent centres are one segment_pitch_m apart.

__repr__()[source]#

One-line summary of diameter, segment layout, and effective area.

Return type:

str

class optixstuff.SimplePrimary(diameter_m, obscuration=0.0, shape_factor=1.0)[source]#

Bases: AbstractPrimary

A simple circular primary mirror with a central obscuration.

Args:

diameter_m: Primary mirror diameter in metres. obscuration: Linear obscuration fraction (0 = no obscuration). shape_factor: Fraction of unobscured area that is collecting

(accounts for struts, segment gaps, etc.). Default 1.0.

Parameters:
_diameter_m: float#
obscuration: float#
shape_factor: float#
property diameter_m: float#

Primary mirror diameter in metres.

Return type:

float

property area_m2: float#

Effective collecting area in square metres.

Return type:

float

__repr__()[source]#

One-line summary of diameter, obscuration, and effective area.

Return type:

str

class optixstuff.AbstractSpeckleField[source]#

Bases: equinox.Module

Abstract interface for time-varying speckle fields.

Implementations can be backed by an analytic generator (physicaloptix), replayed designer/testbed intensity cubes, a fitted reduced-order model, or a learned generator. All produce a coronagraph-plane contrast map through realize().

All wavelength arguments are in nanometres; time_s is seconds since mission start. The returned map is on the field’s native coronagraph plane at pixel_scale_lod; the caller resamples it to the detector grid (as for the coronagraph stellar_intens map).

pixel_scale_lod: equinox.AbstractVar[float]#

Native pixel scale in lambda/D per pixel.

epoch_jd: equinox.AbstractVar[float]#

Julian Date that maps to time_s = 0 – the realization’s clock origin. Consumers (e.g. coronagraphoto.speckle_rate) convert an observation’s absolute JD to the elapsed seconds realize() expects via (start_time_jd - epoch_jd); anchoring the clock here keeps the physical interface in elapsed seconds and avoids feeding large absolute JDs into the temporal synthesis.

abstractmethod realize(*, wavelength_nm, time_s=0.0)[source]#

Speckle contrast delta at a given time and wavelength.

Returns the wavefront-error-induced excess over the deterministic coronagraphic floor – i.e. I(t) - |E_nom|^2, expanded as 2 Re(E_nom* . G eps(t)) + |G eps(t)|^2, in contrast units (fraction of the host-star flux per pixel). It must not include the |E_nom|^2 floor itself: star_rate already applies that via the YIP stellar_intens map, so re-emitting it here would double count. An incoherent-halo implementation returns only the strictly positive |G eps(t)|^2 term (no speckle pinning); a coherent implementation adds the cross term, which carries the bright-tail pinning and requires the complex E_nom.

Evolution is driven by time_s, not a per-call PRNG key: the realization is fixed at construction so the map is deterministic and differentiable, and temporal correlation survives across an exposure / roll sequence.

Args:

wavelength_nm: Wavelength in nanometres. time_s: Time since mission start in seconds.

Returns:

2D float contrast-delta array on the native coronagraph plane.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

class optixstuff.YippyCoronagraph(yip_path=None, *, backend=None, **kwargs)[source]#

Bases: optixstuff.coronagraph.AbstractTableCoronagraph

Coronagraph performance model backed by a yippy YIP interpolation table.

Wraps a yippy EqxCoronagraph via composition: the scalar curves adapt the backend’s interpolation tables, and the native-grid table SPI (stellar_intens / create_psfs / sky_trans / psf_shape / psf_datacube) delegates to the backend, from which AbstractTableCoronagraph serves the sampling-explicit image contract. The _backend field is itself an eqx.Module, so its internal JAX arrays flow through filter_jit and filter_grad normally.

Construction mirrors EqxCoronagraph – pass either a YIP path or an existing EqxCoronagraph instance:

coro = YippyCoronagraph("/path/to/yip")
coro = YippyCoronagraph(backend=existing_eqx_coro)
Parameters:
_backend: yippy.EqxCoronagraph#
property pixel_scale_lod: float#

Native pixel scale in lambda/D per pixel.

Return type:

float

property IWA: float#

Inner working angle in lambda/D.

Return type:

float

property OWA: float#

Outer working angle in lambda/D.

Return type:

float

throughput(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Core throughput from the YIP interpolation table.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

core_area(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Photometric aperture area from the YIP interpolation table.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

core_mean_intensity(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Mean stellar leakage from the YIP interpolation table.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

occulter_transmission(separation_lod, wavelength_nm, *, time_s=0.0)[source]#

Sky transmission from the YIP interpolation table.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • wavelength_nm (jax.typing.ArrayLike)

  • time_s (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

on_axis_psf(wavelength_nm, pixel_scale_rad, npixels)[source]#

Stellar leakage PSF from the YIP stellar intensity model.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

off_axis_psf(wavelength_nm, separation_lod, pixel_scale_rad, npixels)[source]#

Off-axis planet PSF from the YIP PSF interpolator.

Places the planet along the +x axis by convention.

Parameters:
  • wavelength_nm (jax.typing.ArrayLike)

  • separation_lod (jax.typing.ArrayLike)

  • pixel_scale_rad (float)

  • npixels (int)

Return type:

jaxtyping.Array

noise_floor_ayo(separation_lod, ppf=30.0)[source]#

AYO noise floor: core_mean_intensity / ppf.

This is a convenience passthrough to the backend. Not part of the AbstractCoronagraph contract – downstream ETCs should compute noise floors as pure functions.

Parameters:
  • separation_lod (jax.typing.ArrayLike)

  • ppf (float)

Return type:

jax.typing.ArrayLike

raw_contrast(separation_lod)[source]#

Raw contrast from the YIP interpolation table.

Parameters:

separation_lod (jax.typing.ArrayLike)

Return type:

jax.typing.ArrayLike

stellar_intens(stellar_diam_lod)[source]#

Stellar intensity map for a given stellar angular diameter.

Parameters:

stellar_diam_lod (float)

Return type:

jaxtyping.Array

property psf_shape: tuple[int, int]#

Shape of the PSF arrays from the YIP file.

Return type:

tuple[int, int]

property sky_trans: jaxtyping.Array#

Full sky transmission map.

Return type:

jaxtyping.Array

create_psfs(x_lod, y_lod)[source]#

Batched off-axis PSFs at (x_lod, y_lod) source positions.

Delegates to the backend yippy create_psfs closure. Returns a stack of PSF images, one per input source coordinate.

Args:

x_lod: Source x-coordinates in lambda/D, shape (K,). y_lod: Source y-coordinates in lambda/D, shape (K,).

Returns:

PSF stack of shape (K, ny, nx) where (ny, nx) == self.psf_shape.

Parameters:
  • x_lod (jax.typing.ArrayLike)

  • y_lod (jax.typing.ArrayLike)

Return type:

jaxtyping.Array

property psf_datacube: jaxtyping.Array | None#

Pre-computed quarter-symmetric PSF datacube from the backend.

Returns None if the backing EqxCoronagraph was not built with ensure_psf_datacube=True. Consumers that need this for disk convolution should construct the backend with the flag set.

Return type:

jaxtyping.Array | None

__repr__()[source]#

One-line summary of YIP backend metadata.

Return type:

str