skyscapes
=========

.. py:module:: skyscapes

.. autoapi-nested-parse::

   Astrophysical scene modeling for HWO direct imaging.

   Public API:

   - :mod:`skyscapes.scene` -- star + planet + system hierarchy, plus the
     top-level ``Scene`` container.
   - :mod:`skyscapes.disk` -- extended-source surface brightness maps.
   - :mod:`skyscapes.physical_model` -- phase/wavelength-dependent
     planet-to-star contrast (reflective, emissive, future joint models).
   - :mod:`skyscapes.background` -- field-of-view background sources (zodi, ...).
   - :mod:`skyscapes.io` -- data loaders (e.g. ExoVista FITS).

   For convenience, ``Scene``, ``System``, and ``from_exovista`` are hoisted to
   the top level, so common flows can write
   ``from skyscapes import Scene, System, from_exovista``.
   Mix-and-match construction goes through the submodules
   (``skyscapes.disk.ExovistaDisk``, ``skyscapes.physical_model.GridPhysicalModel``,
   ``skyscapes.background.AYOZodi``, ...).



Submodules
----------

.. toctree::
   :maxdepth: 1

   /autoapi/skyscapes/_repr/index
   /autoapi/skyscapes/background/index
   /autoapi/skyscapes/datasets/index
   /autoapi/skyscapes/disk/index
   /autoapi/skyscapes/io/index
   /autoapi/skyscapes/physical_model/index
   /autoapi/skyscapes/scene/index


Attributes
----------

.. autoapisummary::

   skyscapes.__version__


Classes
-------

.. autoapisummary::

   skyscapes.Scene
   skyscapes.System


Functions
---------

.. autoapisummary::

   skyscapes.from_exovista


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

.. py:data:: __version__
   :value: 'unknown'


.. py:function:: from_exovista(fits_file, planet_indices = None, only_earths = False)

   Load an ExoVista FITS file into a ``scene.System``.

   The system's midplane inclination and position angle (FITS star
   header keys ``I`` and ``PA``) are applied at load time as a frame
   rotation of each planet's state vector before its Keplerian
   elements are computed. The same angles are stored as
   ``System.midplane_inc_deg`` and ``System.midplane_pa_deg`` for
   downstream diagnostic use.

   Args:
       fits_file: Path to 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.

   Returns:
       ``scene.System`` with star, planets (tuple), disk, and midplane metadata.


.. py:class:: Scene

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


   Field-of-view container: planetary system + named background sources.

   Attributes:
       system: The planetary system (star + planets + disk).
       zodi: Optional zodiacal-light background (any
           :mod:`skyscapes.background` zodi variant).


   .. py:attribute:: system
      :type:  skyscapes.scene.system.System


   .. py:attribute:: zodi
      :type:  skyscapes.background.Zodi | None
      :value: None



   .. py:property:: star

      Convenience accessor for the host star.



   .. py:property:: planets

      Convenience accessor for the planet tuple.



   .. py:property:: disk

      Convenience accessor for the system's disk (may be ``None``).



   .. py:method:: __repr__()

      Tree-shaped summary of the contained system + zodi.



.. py:class:: System

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


   Astrophysical scene: star + tuple of planets + optional disk.

   Attributes:
       star: Host star (``AbstractStar``).
       planets: Variable-length tuple of ``Planet``.
       trig_solver: Scalar Kepler-trig solver (static; see
           ``orbix.kepler.shortcuts.grid.get_grid_solver``). Required --
           callers must provide a built solver, not None.
       disk: Optional extended-source disk (``AbstractDisk | None``).
       midplane_inc_deg: System midplane inclination [deg] in the
           barycentric -> sky frame. Default 0.0 means "midplane = sky"
           and is intentionally indistinguishable from a real face-on
           system at this inclination; this ambiguity is acceptable
           because the field is diagnostic-only after load (no runtime
           hot path consults it). Populated by ``io.from_exovista``
           from the FITS star header. After load, frame rotation has
           already been baked into each ``Planet``'s orbital elements.
       midplane_pa_deg: System midplane position angle [deg]. Same
           semantics as ``midplane_inc_deg``.


   .. py:attribute:: star
      :type:  skyscapes.scene.star.AbstractStar


   .. py:attribute:: planets
      :type:  tuple[skyscapes.scene.planet.Planet, Ellipsis]


   .. py:attribute:: trig_solver
      :type:  collections.abc.Callable


   .. py:attribute:: disk
      :type:  skyscapes.disk.AbstractDisk | None
      :value: None



   .. py:attribute:: midplane_inc_deg
      :type:  float
      :value: 0.0



   .. py:attribute:: midplane_pa_deg
      :type:  float
      :value: 0.0



   .. py:property:: n_planets
      :type: int


      Total number of planets across all composed ``Planet`` modules.



   .. py:method:: positions(t_jd)

      Concatenated on-sky positions, shape ``(2, K_total, T)``.



   .. py:method:: contrasts(wavelength_nm, t_jd)

      Per-planet contrast, shape ``(K_total, T)``.



   .. py:method:: planet_flux_densities(wavelength_nm, t_jd)

      Per-planet flux density [ph/s/m^2/nm], shape ``(K_total, T)``.



   .. py:method:: alpha_dMag(t_jd)

      Per-planet projected separation + dMag, each shape ``(K_total, T)``.



   .. py:method:: __repr__()

      Tree-shaped summary: star + planets + disk + midplane geometry.



