coronagraphoto
==============

.. py:module:: coronagraphoto

.. autoapi-nested-parse::

   Coronagraphic image simulation built on JAX.

   Scene primitives (Star, Planet, Disk, System, Scene, backgrounds) live in
   :mod:`skyscapes`. coronagraphoto consumes a :class:`skyscapes.Scene` and
   produces either deterministic count-rate maps (``*_rate`` functions,
   differentiable, used for fitting and retrievals) or Poisson-realised
   detector readouts (``*_readout`` functions, used for data generation).



Submodules
----------

.. toctree::
   :maxdepth: 1

   /autoapi/coronagraphoto/datasets/index
   /autoapi/coronagraphoto/loaders/index
   /autoapi/coronagraphoto/simulation/index


Functions
---------

.. autoapisummary::

   coronagraphoto.load_scene_from_exovista
   coronagraphoto.disk_rate
   coronagraphoto.disk_readout
   coronagraphoto.planet_rate
   coronagraphoto.planet_readout
   coronagraphoto.star_rate
   coronagraphoto.star_readout
   coronagraphoto.system_rate
   coronagraphoto.system_readout
   coronagraphoto.zodi_rate
   coronagraphoto.zodi_readout


Package Contents
----------------

.. py:function:: load_scene_from_exovista(fits_file, planet_indices = None, only_earths = False, zodi_surface_brightness_mag = 22.0)

   Load a full :class:`skyscapes.Scene` from an ExoVista FITS file.

   Delegates system loading to :func:`skyscapes.from_exovista` and adds
   a default :class:`~skyscapes.background.AYOZodi` background using
   the host star's wavelength grid.

   The earlier ``required_planets`` parameter was removed: variadic
   planet tuples make the "pad to fixed shape" semantics unnecessary,
   and the underlying ``skyscapes.from_exovista`` no longer accepts it.

   Args:
       fits_file: Path to the ExoVista FITS file.
       planet_indices: Planet indices to load (0-based). ``None`` = all.
       only_earths: If True and ``planet_indices`` is None, auto-filter
           Earths.
       zodi_surface_brightness_mag: V-band surface brightness for the
           default zodi background. Default 22.0 (AYO standard).

   Returns:
       ``skyscapes.Scene`` with the loaded system and a default zodi
       background.


.. py:function:: disk_rate(disk, optical_path, *, start_time_jd, wavelength_nm, bin_width_nm, telescope_pa_deg, star, incl_deg, pa_deg)

   Generate the disk count rate on the detector.

   Disks return CONTRAST (dimensionless flux ratio relative to the host
   star); we multiply by ``star.spec_flux_density`` here to convert to
   photon flux density per pixel before resampling and PSF convolution.

   ``incl_deg`` / ``pa_deg`` are the disk's intrinsic orientation in the
   sky frame; ``telescope_pa_deg`` is the telescope's roll. The disk is
   rendered at its intrinsic geometry, then resample_flux rotates the
   rendered image by ``-telescope_pa_deg`` into the detector frame.

   Raises:
       ValueError: if ``optical_path.coronagraph.psf_datacube`` is
           ``None``.


.. py:function:: disk_readout(disk, optical_path, prng_key, *, start_time_jd, exposure_time_s, wavelength_nm, bin_width_nm, telescope_pa_deg, star, incl_deg, pa_deg)

   Process a disk through the provided optical path.

   ``incl_deg`` / ``pa_deg`` are the disk's intrinsic sky-frame
   orientation; ``system_readout`` pulls them from
   ``scene.system.midplane_inc_deg`` / ``midplane_pa_deg`` so every
   disk component in the System renders at the same midplane.


.. py:function:: planet_rate(planet, optical_path, *, start_time_jd, wavelength_nm, bin_width_nm, telescope_pa_deg, star, trig_solver)

   Generate the per-batch planet count rate on the detector.

   Operates on a single ``skyscapes.scene.Planet`` (which internally
   batches K planets sharing the same atmosphere class). The Python
   loop over a heterogeneous ``System.planets`` tuple lives in
   :func:`system_readout`; this function stays inside the per-Planet-type
   JIT cache boundary (see ``brain/Planet Loop Architecture.md``).


.. py:function:: planet_readout(planet, optical_path, prng_key, *, start_time_jd, exposure_time_s, wavelength_nm, bin_width_nm, telescope_pa_deg, star, trig_solver)

   Process a per-batch Planet through the optical path.


.. py:function:: star_rate(star, optical_path, *, start_time_jd, wavelength_nm, bin_width_nm)

   Generate the star count rate on the detector.


.. py:function:: star_readout(star, optical_path, prng_key, *, start_time_jd, exposure_time_s, wavelength_nm, bin_width_nm)

   Process a star through the provided optical path.


.. py:function:: system_rate(scene, optical_path, *, start_time_jd, wavelength_nm, bin_width_nm, telescope_pa_deg, ecliptic_lat_deg, solar_lon_deg)

   Sum of deterministic per-source count rates for a :class:`~skyscapes.Scene`.

   The differentiable companion to :func:`system_readout`. Returns the
   total rate map (electrons/s/pixel, no Poisson noise, no QE multiply)
   summing star, every planet, the optional disk, and the optional zodi.
   Use this for likelihood evaluation, retrievals, or any inference loop
   that needs gradients through the full forward model.


.. py:function:: system_readout(scene, optical_path, prng_key, *, start_time_jd, exposure_time_s, wavelength_nm, bin_width_nm, telescope_pa_deg, ecliptic_lat_deg, solar_lon_deg)

   Simulate a full :class:`~skyscapes.Scene` through the optical path.

   Sums per-source detector readouts. Each source consumes its own
   independent PRNG subkey (see :mod:`jax.random` best practices).

   The Python loop over ``scene.system.planets`` is intentionally
   unjitted -- it orchestrates JIT-cached per-Planet-type kernels (see
   ``brain/Planet Loop Architecture.md``). The expensive math is inside
   each ``planet_readout`` call, not the loop.


.. py:function:: zodi_rate(zodi, optical_path, *, start_time_jd, wavelength_nm, bin_width_nm, ecliptic_lat_deg, solar_lon_deg)

   Generate the zodi count rate on the detector.

   Treats zodi as a spatially uniform surface-brightness source. The
   coronagraph's sky transmission map sets the per-pixel attenuation;
   no PSF convolution is needed (a flat field convolved with any
   normalised PSF returns itself).


.. py:function:: zodi_readout(zodi, optical_path, prng_key, *, start_time_jd, exposure_time_s, wavelength_nm, bin_width_nm, ecliptic_lat_deg, solar_lon_deg)

   Process a zodi source through the provided optical path.


