optixstuff.detector#

Detector abstractions and concrete implementations.

Classes#

AbstractDetector

Abstract interface for a focal-plane detector.

IdealDetector

Detector with constant QE and minimal noise sources.

Detector

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

Functions#

dark_current(dark_current_rate_e_per_s, ...)

Draw dark current electrons from a Poisson distribution.

clock_induced_charge(...)

Draw clock-induced charge electrons from a Poisson distribution.

read_noise(read_noise_e, num_frames, shape, prng_key)

Draw read noise from a Gaussian distribution.

Module Contents#

class optixstuff.detector.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

optixstuff.detector.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.detector.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.detector.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.detector.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

class optixstuff.detector.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)[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#

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.

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