|
3 | 3 | Overview |
4 | 4 | ======== |
5 | 5 |
|
6 | | -TODO |
| 6 | +**pyvisual** is a thin wrapper around `PyVista <https://docs.pyvista.org/>`_ |
| 7 | +that adds spherical-coordinate awareness, observer controls, and rendering |
| 8 | +utilities tuned to solar and magnetohydrodynamic (MHD) datasets. It is developed |
| 9 | +and maintained by `Predictive Science Inc. (PSI) <https://www.predsci.com/>`_ and |
| 10 | +is tightly coupled to the PSI data ecosystem — in particular |
| 11 | +`psi-io <https://predsci.com/doc/psi-io/guide/index.html>`_ (HDF4/HDF5 file I/O) |
| 12 | +and `mapflpy <https://predsci.com/doc/mapflpy/>`_ (magnetic fieldline tracing). |
| 13 | +Any rectilinear grid defined in spherical coordinates is compatible with the API, |
| 14 | +regardless of whether it originates from a PSI model. |
| 15 | + |
| 16 | +.. attention:: |
| 17 | + |
| 18 | + Because **pyvisual** renders through PyVista and VTK, it is *strongly* |
| 19 | + recommended to read the `PyVista documentation <https://docs.pyvista.org/>`_ |
| 20 | + alongside this guide. **pyvisual** exposes only a focused subset of PyVista's |
| 21 | + capabilities; familiarity with the underlying library unlocks considerably more |
| 22 | + flexibility. |
| 23 | + |
| 24 | +Coordinate Conventions |
| 25 | +----------------------- |
| 26 | + |
| 27 | +**pyvisual** uses two coordinate frames throughout. |
| 28 | + |
| 29 | +Spherical frame (``'spherical'``) |
| 30 | + Coordinates are ordered :math:`(r, \theta, \phi)`, where :math:`r` is the |
| 31 | + radial distance in solar radii :math:`R_\odot`, :math:`\theta` is the |
| 32 | + colatitude measured from the north pole, and :math:`\phi` is the longitude. |
| 33 | + This is the native PSI convention; all model data is stored in this frame. |
| 34 | + Accepted aliases include ``'rtp'``, ``'polar'``, ``'psi'``, and any permutation |
| 35 | + of the individual axis letters (``'r'``, ``'tp'``, etc.). |
| 36 | + |
| 37 | +Cartesian frame (``'cartesian'``) |
| 38 | + Coordinates are ordered :math:`(x, y, z)`, where :math:`+\hat{z}` points |
| 39 | + toward solar north (``SOLAR_NORTH = [0, 0, 1]``). This is the frame used |
| 40 | + internally by PyVista and VTK for all rendering. |
| 41 | + Accepted aliases include ``'xyz'``, ``'cart'``, ``'rectilinear'``, and any |
| 42 | + permutation of the individual axis letters. |
| 43 | + |
| 44 | +Conversion between the two frames is handled transparently — methods that accept a |
| 45 | +``frame`` argument convert to Cartesian before passing data to PyVista. |
| 46 | + |
| 47 | +The Plotter: ``Plot3d`` |
| 48 | +----------------------- |
| 49 | + |
| 50 | +:class:`~pyvisual.core.plot3d.Plot3d` is the primary entry point. It subclasses |
| 51 | +:class:`pyvista.Plotter` and mixes in four functional areas: |
| 52 | + |
| 53 | +.. code-block:: python |
| 54 | +
|
| 55 | + from pyvisual import Plot3d |
| 56 | +
|
| 57 | + plotter = Plot3d() |
| 58 | + plotter.add_sun() |
| 59 | + plotter.show() |
| 60 | +
|
| 61 | +All keyword arguments accepted by :class:`pyvista.Plotter` (lighting, window size, |
| 62 | +off-screen rendering, etc.) are also accepted by :class:`~pyvisual.core.plot3d.Plot3d`. |
| 63 | + |
| 64 | +Mixin Areas |
| 65 | +----------- |
| 66 | + |
| 67 | +The four mixin classes that compose :class:`~pyvisual.core.plot3d.Plot3d` are |
| 68 | +defined in :mod:`pyvisual.core.mixins`. |
| 69 | + |
| 70 | +Observer controls (:class:`~pyvisual.core.mixins.ObserverMixin`) |
| 71 | + Sets the camera position and orientation using spherical coordinates. The |
| 72 | + observer location is expressed as a :class:`~pyvisual.core._typing.SphericalCoordinate` |
| 73 | + :math:`(r, \theta, \phi)`, and the API also exposes the line-of-sight FOV angle |
| 74 | + and a position angle measured from solar north. A live camera-state readout can |
| 75 | + be displayed to inspect the current view parameters interactively. |
| 76 | + |
| 77 | +Solar geometry (:class:`~pyvisual.core.mixins.GeometryMixin`) |
| 78 | + Adds reference geometry to a scene: the Sun sphere (radius |
| 79 | + :math:`1\,R_\odot`), spherical shells at arbitrary radii, planar discs |
| 80 | + (e.g., the ecliptic plane), longitude/latitude grid lines, and the Thomson |
| 81 | + sphere (the sphere of unit optical depth for Thomson scattering, centered |
| 82 | + halfway between the Sun and the observer). |
| 83 | + |
| 84 | +Structured-grid slices (:class:`~pyvisual.core.mixins.GridMeshMixin`) |
| 85 | + Renders data from structured :math:`(r, \theta, \phi)` grids. Supports |
| 86 | + 1-D line slices, 2-D surface slices, and 3-D volume slices, as well as |
| 87 | + isosurface contours. Coordinate arrays may be supplied as independent 1-D |
| 88 | + axis arrays or as pre-broadcast 3-D arrays. |
| 89 | + |
| 90 | +Stacked-coordinate rendering (:class:`~pyvisual.core.mixins.StackMeshMixin`) |
| 91 | + Renders data where all coordinate axes share the same array shape — for |
| 92 | + example, in-situ spacecraft trajectories or traced fieldlines. Supports |
| 93 | + single points, point clouds, splines, magnetic fieldline bundles, and |
| 94 | + free-form surfaces. |
| 95 | + |
| 96 | +Mesh Classes |
| 97 | +------------ |
| 98 | + |
| 99 | +Two mesh classes are provided for loading and manipulating model data before |
| 100 | +adding it to a plotter. |
| 101 | + |
| 102 | +:class:`~pyvisual.core.mesh3d.SphericalMesh` |
| 103 | + Wraps :class:`pyvista.RectilinearGrid` with a spherical-frame tag. Can be |
| 104 | + constructed from an HDF4/HDF5 file path, raw :math:`(r, \theta, \phi)` + data |
| 105 | + arrays, or an existing PyVista dataset. Supports the full NumPy arithmetic |
| 106 | + suite (``+``, ``-``, ``*``, ``/``, ``**``, etc.) and |
| 107 | + :meth:`~object.__array_ufunc__` so that expressions such as |
| 108 | + ``np.log10(mesh)`` work element-wise on the active scalar field. |
| 109 | + |
| 110 | +:class:`~pyvisual.core.mesh3d.CartesianMesh` |
| 111 | + The Cartesian counterpart, wrapping :class:`pyvista.StructuredGrid`. It shares |
| 112 | + the same operator API as :class:`~pyvisual.core.mesh3d.SphericalMesh`. |
| 113 | + |
| 114 | +Both classes are available from the top-level package:: |
| 115 | + |
| 116 | + from pyvisual import SphericalMesh, CartesianMesh |
| 117 | + |
| 118 | +PSI Data Ecosystem |
| 119 | +------------------ |
| 120 | + |
| 121 | +**pyvisual** is designed for use with model output produced by PSI's MAS |
| 122 | +(Magnetohydrodynamics Around a Sphere) code, stored in HDF4 or HDF5 files using |
| 123 | +Fortran-order array layout. File I/O is handled by |
| 124 | +`psi-io <https://predsci.com/doc/psi-io/guide/index.html>`_, which is a required |
| 125 | +dependency. Fieldline tracing (for use with |
| 126 | +:class:`~pyvisual.core.mixins.StackMeshMixin`) is provided by |
| 127 | +`mapflpy <https://predsci.com/doc/mapflpy/>`_, an optional dependency installed |
| 128 | +via the ``tracing`` extra. |
| 129 | + |
| 130 | +For a more general solar-physics visualization toolkit with coordinate-frame |
| 131 | +awareness beyond what **pyvisual** provides, consider |
| 132 | +`sunkit-pyvista <https://docs.sunpy.org/projects/sunkit-pyvista/en/latest/>`_. |
| 133 | + |
| 134 | +.. seealso:: |
| 135 | + |
| 136 | + :ref:`installation` |
| 137 | + How to install **pyvisual** and its optional dependencies. |
| 138 | + |
| 139 | + :doc:`/gallery/index` |
| 140 | + Worked examples covering basic scenes, slicing, fieldlines, and observer setup. |
| 141 | + |
| 142 | + `PyVista documentation <https://docs.pyvista.org/>`_ |
| 143 | + The upstream library that **pyvisual** extends. |
0 commit comments