skyscapes.disk
==============

.. py:module:: skyscapes.disk

.. autoapi-nested-parse::

   Disk hierarchy: extended-source surface brightness maps.



Submodules
----------

.. toctree::
   :maxdepth: 1

   /autoapi/skyscapes/disk/_los/index
   /autoapi/skyscapes/disk/base/index
   /autoapi/skyscapes/disk/composite/index
   /autoapi/skyscapes/disk/exovista/index
   /autoapi/skyscapes/disk/exovista_parametric/index
   /autoapi/skyscapes/disk/grater/index


Classes
-------

.. autoapisummary::

   skyscapes.disk.AbstractDisk
   skyscapes.disk.CompositeDisk
   skyscapes.disk.ExovistaDisk
   skyscapes.disk.ExovistaParametricDisk
   skyscapes.disk.GraterDisk


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

.. py:class:: AbstractDisk

   Bases: :py:obj:`equinox.Module`


   Extended-source surface brightness map.

   Subclasses return contrast (flux ratio relative to the host star) per
   pixel. The concrete ``System`` multiplies by ``star.spec_flux_density``
   to turn that into ph/s/m^2/nm per pixel.

   ``incl_deg`` / ``pa_deg`` are supplied at render time rather than stored
   on the disk so the System's midplane orientation drives every disk
   component consistently. Disks whose geometry is pre-baked into their
   representation (e.g. ``ExovistaDisk``'s contrast cube) may ignore the
   arguments; parametric disks (``GraterDisk``, ``ExovistaParametricDisk``)
   consume them.


   .. py:method:: surface_brightness(wavelength_nm, time_jd, incl_deg, pa_deg)
      :abstractmethod:


      Return contrast per pixel, shape ``(ny, nx)``.



   .. py:method:: spatial_extent()
      :abstractmethod:


      Return ``(width_arcsec, height_arcsec)``.



.. py:class:: CompositeDisk

   Bases: :py:obj:`skyscapes.disk.base.AbstractDisk`


   Sum of multiple disk components rendered on a shared grid.

   Attributes:
       components: Tuple of ``AbstractDisk`` instances. At least one
           component is required. All components must report the same
           ``spatial_extent()`` so their rendered ``(ny, nx)`` arrays
           sum elementwise.


   .. py:attribute:: components
      :type:  tuple[skyscapes.disk.base.AbstractDisk, Ellipsis]


   .. py:method:: __check_init__()

      Reject empty composites and mismatched component extents.



   .. py:method:: surface_brightness(wavelength_nm, time_jd, incl_deg, pa_deg)

      Return the per-pixel sum of all component contrast maps.



   .. py:method:: spatial_extent()

      Return the shared ``(width_arcsec, height_arcsec)``.



   .. py:method:: __repr__()

      Nested summary listing each component disk.



.. py:class:: ExovistaDisk(pixel_scale_arcsec, wavelengths_nm, contrast_cube)

   Bases: :py:obj:`skyscapes.disk.base.AbstractDisk`


   Wavelength-interpolated 3D contrast cube loaded from ExoVista FITS.

   Attributes:
       pixel_scale_arcsec: Pixel scale [arcsec/pixel].
       wavelengths_nm: 1-D wavelength grid [nm], shape ``(n_wl,)``.
       contrast_cube: Contrast cube, shape ``(n_wl, ny, nx)``.


   .. py:attribute:: pixel_scale_arcsec
      :type:  float


   .. py:attribute:: wavelengths_nm
      :type:  jaxtyping.Array


   .. py:attribute:: contrast_cube
      :type:  jaxtyping.Array


   .. py:attribute:: _contrast_interp
      :type:  interpax.CubicSpline


   .. py:method:: surface_brightness(wavelength_nm, time_jd, incl_deg, pa_deg)

      Contrast map at the requested wavelength, shape ``(ny, nx)``.

      ``time_jd``, ``incl_deg``, and ``pa_deg`` are part of the
      AbstractDisk interface but ignored here: the cube is a single
      time snapshot with disk geometry already baked in by the loader.



   .. py:method:: spatial_extent()

      Return ``(width_arcsec, height_arcsec)``.



   .. py:method:: __repr__()

      One-line summary of cube shape, pixel scale, and wavelength grid.



.. py:class:: ExovistaParametricDisk

   Bases: :py:obj:`skyscapes.disk.base.AbstractDisk`


   ExoVista-style disk component (faithful per-component reproduction).

   Attributes (PyTree leaves, fittable):
       r0_AU: Ring center radius [AU].
       dror: Ring fractional width ``Delta r / r0`` (dimensionless).
       rinner_AU: Inner truncation radius [AU]; below this the density
           is suppressed by ``(r/rinner_AU)^3``. Set to a value smaller
           than ``rmin_AU`` to disable.
       hor: Opening angle (Gaussian vertical scale / radius).
       nzodis: Density normalization in zodi units.
       eta: PR-drag / collision-timescale ratio at ``r0 - dr``.
       g0, g1, g2: Three-component HG asymmetry parameters.
       w0, w1, w2: Three-component HG weights. Should sum to 1; not
           enforced.
       rmin_AU: LOS-integration inner bound [AU].
       rmax_AU: LOS-integration outer bound [AU].
       wavelengths_nm: 1-D wavelength grid for ``Ag_grid``. Queries
           outside this range return NaN.
       Ag_grid: Phenomenological albedo scaling vs wavelength.

   Static attributes:
       nx, ny: Output image shape.
       pixel_scale_arcsec: Pixel scale [arcsec/pixel].
       dist_pc: System distance [pc].
       n_slices_los: Number of LOS integration slices.
       n_scale_heights: LOS half-extent in units of the scale height at
           ``rmax_AU`` (default 6.0).


   .. py:attribute:: r0_AU
      :type:  jaxtyping.Array


   .. py:attribute:: dror
      :type:  jaxtyping.Array


   .. py:attribute:: rinner_AU
      :type:  jaxtyping.Array


   .. py:attribute:: hor
      :type:  jaxtyping.Array


   .. py:attribute:: nzodis
      :type:  jaxtyping.Array


   .. py:attribute:: eta
      :type:  jaxtyping.Array


   .. py:attribute:: g0
      :type:  jaxtyping.Array


   .. py:attribute:: g1
      :type:  jaxtyping.Array


   .. py:attribute:: g2
      :type:  jaxtyping.Array


   .. py:attribute:: w0
      :type:  jaxtyping.Array


   .. py:attribute:: w1
      :type:  jaxtyping.Array


   .. py:attribute:: w2
      :type:  jaxtyping.Array


   .. py:attribute:: rmin_AU
      :type:  jaxtyping.Array


   .. py:attribute:: rmax_AU
      :type:  jaxtyping.Array


   .. py:attribute:: wavelengths_nm
      :type:  jaxtyping.Array


   .. py:attribute:: Ag_grid
      :type:  jaxtyping.Array


   .. py:attribute:: nx
      :type:  int


   .. py:attribute:: ny
      :type:  int


   .. py:attribute:: pixel_scale_arcsec
      :type:  float


   .. py:attribute:: dist_pc
      :type:  float


   .. py:attribute:: n_slices_los
      :type:  int


   .. py:attribute:: n_scale_heights
      :type:  float


   .. py:method:: _zmax_AU()

      LOS half-extent in disk-frame z, evaluated at the ring center.

      For ExoVista-style disks the mass is concentrated near ``r0_AU``
      (ring + nearby halo + inward profile), and the radial profile
      decays as ``r^-1.5`` outside. Using ``r0_AU`` rather than the
      LOS-bound ``rmax_AU`` gives an LOS extent matched to where the
      density actually lives, so per-slice dz scales with the scale
      height at the ring rather than with the (much larger) LOS-bound.



   .. py:method:: surface_brightness(wavelength_nm, time_jd, incl_deg, pa_deg)

      Render the ExoVista-style disk on a sky-plane grid.



   .. py:method:: spatial_extent()

      Return ``(width_arcsec, height_arcsec)``.



   .. py:method:: __repr__()

      Compact summary of ring/density/HG parameters + image/Ag grid.



.. py:class:: GraterDisk

   Bases: :py:obj:`skyscapes.disk.base.AbstractDisk`


   Augereau 1999 scattered-light disk.

   Attributes (PyTree leaves, fittable):
       sma_AU: Reference radius [AU] (radial profile peak).
       alpha_in: Inner power-law slope (positive).
       alpha_out: Outer power-law slope (negative).
       ksi0_AU: Vertical scale height at ``sma_AU`` [AU].
       gamma: Vertical profile exponent (2 = Gaussian).
       beta: Flaring index (0 = none, 1 = linear).
       rmin_AU: Inner truncation radius [AU].
       rmax_AU: Outer truncation radius [AU].
       wavelengths_nm: 1-D wavelength grid for ``g_HG_grid`` /
           ``Ag_grid``, shape ``(n_wave,)`` [nm]. Must be sorted.
           ``surface_brightness`` calls outside this range return NaN.
       g_HG_grid: Henyey-Greenstein asymmetry at each grid wavelength.
       Ag_grid: Albedo-like scaling at each grid wavelength.

   Static attributes (compilation-time constants):
       nx, ny: Output image shape.
       pixel_scale_arcsec: Pixel scale [arcsec/pixel].
       dist_pc: System distance [pc].
       n_slices_los: Number of LOS integration slices.
       n_scale_heights: LOS half-extent in units of the local scale
           height at ``rmax_AU`` (default 6.0).


   .. py:attribute:: sma_AU
      :type:  jaxtyping.Array


   .. py:attribute:: alpha_in
      :type:  jaxtyping.Array


   .. py:attribute:: alpha_out
      :type:  jaxtyping.Array


   .. py:attribute:: ksi0_AU
      :type:  jaxtyping.Array


   .. py:attribute:: gamma
      :type:  jaxtyping.Array


   .. py:attribute:: beta
      :type:  jaxtyping.Array


   .. py:attribute:: rmin_AU
      :type:  jaxtyping.Array


   .. py:attribute:: rmax_AU
      :type:  jaxtyping.Array


   .. py:attribute:: wavelengths_nm
      :type:  jaxtyping.Array


   .. py:attribute:: g_HG_grid
      :type:  jaxtyping.Array


   .. py:attribute:: Ag_grid
      :type:  jaxtyping.Array


   .. py:attribute:: nx
      :type:  int


   .. py:attribute:: ny
      :type:  int


   .. py:attribute:: pixel_scale_arcsec
      :type:  float


   .. py:attribute:: dist_pc
      :type:  float


   .. py:attribute:: n_slices_los
      :type:  int


   .. py:attribute:: n_scale_heights
      :type:  float


   .. py:method:: _zmax_AU()

      LOS half-extent in disk-frame z, evaluated at ``rmax_AU``.

      For a flared disk, the scale height grows with radius, so the
      LOS depth that captures the vertical tails at the outer edge
      is larger than ``n_scale_heights * ksi0_AU`` at ``sma_AU``.



   .. py:method:: surface_brightness(wavelength_nm, time_jd, incl_deg, pa_deg)

      Render the Augereau 1999 scattered-light disk on a sky-plane grid.

      ``wavelength_nm`` selects ``g_HG`` and ``Ag`` via cubic-spline
      interpolation over ``wavelengths_nm`` / ``g_HG_grid`` /
      ``Ag_grid``. Queries outside the grid return NaN.
      ``time_jd`` is part of the AbstractDisk interface but ignored
      (static disk).



   .. py:method:: spatial_extent()

      Return ``(width_arcsec, height_arcsec)``.



   .. py:method:: __repr__()

      Compact summary of radial/vertical/HG parameters + image/Ag grid.



