Signs and Conventions
=====================

This page centralizes the sign and axis conventions used in Pyralysis for image-space and Fourier-space operations.
It is intended as a practical reference for users implementing pipelines, custom estimators, or validating equations.

.. index::
   single: conventions; signs
   single: Fourier transform; sign convention
   single: cellsize; sign
   single: Nyquist; uv plane

Image Pixel Size Convention (``cellsize``)
------------------------------------------

Internally, Pyralysis enforces a signed 2-element ``cellsize`` in radians:

.. math::
   [\Delta l, \Delta m] = [-|\Delta l|,\; +|\Delta m|]

This is implemented by :mod:`pyralysis.utils.cellsize` and used by :class:`pyralysis.grids.base.Grid`.

- ``cellsize[0]`` maps to the horizontal image axis (:math:`l`) and is stored **negative**.
- ``cellsize[1]`` maps to the vertical image axis (:math:`m`) and is stored **positive**.

Even when a scalar value is provided, Pyralysis expands it to this signed pair.

Direction Cosines Convention (l, m, n)
--------------------------------------

Pyralysis uses the standard radio-interferometry direction-cosine convention relative to a phase center
(:mod:`pyralysis.utils.coordinate_transforms`):

.. math::
   l = \cos(\delta)\sin(\alpha-\alpha_0)

.. math::
   m = \sin(\delta)\cos(\delta_0)-\cos(\delta)\sin(\delta_0)\cos(\alpha-\alpha_0)

.. math::
   n = \sqrt{1-l^2-m^2}

where :math:`(\alpha,\delta)` is sky position and :math:`(\alpha_0,\delta_0)` is the phase center.

UV Cell Size and Axis Mapping
-----------------------------

For padded image size :math:`(N_y, N_x)` and image-space cell sizes
:math:`(\Delta l, \Delta m)`, Pyralysis uses:

.. math::
   \Delta u = \frac{1}{N_x \,\Delta l}, \qquad
   \Delta v = \frac{1}{N_y \,\Delta m}

where:

- :math:`N_x` is the horizontal (width) pixel count.
- :math:`N_y` is the vertical (height) pixel count.
- :math:`\Delta l < 0` and :math:`\Delta m > 0` by convention.

Therefore, ``uvcellsize[0]`` (``du``) is usually negative and ``uvcellsize[1]`` (``dv``) positive.

Nyquist Limits (Useful Rules of Thumb)
--------------------------------------

Given image-space sampling :math:`\Delta l, \Delta m`, the approximate Nyquist support in UV is:

.. math::
   |u|_{\max} \approx \frac{1}{2|\Delta l|}, \qquad
   |v|_{\max} \approx \frac{1}{2|\Delta m|}

And Fourier pixel spacing is:

.. math::
   \delta u = \frac{1}{N_x |\Delta l|}, \qquad
   \delta v = \frac{1}{N_y |\Delta m|}

In practice, padding changes :math:`N_x, N_y`, so it changes Fourier sampling density (pixel spacing) but not the physical baseline coverage of the observed data.

FFT/IDFT Sign Convention
------------------------

Pyralysis exposes both sign conventions via ``sign_convention``:

- ``"negative"`` (default): forward transform uses :math:`e^{-2\pi i(\cdot)}`.
- ``"positive"``: forward transform uses :math:`e^{+2\pi i(\cdot)}`.

In :func:`pyralysis.fft._fft2.fft2` / :func:`pyralysis.fft._fft2.ifft2`, the inverse uses the corresponding opposite-sign primitive mapping to keep the pair consistent for the selected normalization mode.

Phase-Shift Convention (Grid and Visibilities)
----------------------------------------------

For shifting Fourier grids or visibilities to a phase-center offset, Pyralysis uses:

.. math::
   \exp\{-2\pi i(\cdot)\}

specifically in :mod:`pyralysis.utils.fourier.phase_shift`:

.. math::
   F'(u,v)=F(u,v)\exp\{-2\pi i(ux_0+vy_0)\}

.. math::
   V'(u,v,w)=V(u,v,w)\exp\{-2\pi i(ul_0+vm_0+w(n_0-1))\}

This is consistent with the usual Fourier shift theorem for analysis/registration.

IDFT for Visibility to Image
----------------------------

For direct inversion (:func:`pyralysis.dft.idft2`), Pyralysis evaluates:

.. math::
   I(l,m) = \sum_k \omega_k V_k
   \exp\left\{2\pi i\left(u_k l + v_k m + w_k\left(\sqrt{1-l^2-m^2}-1\right)\right)\right\}

with sign flipped if ``sign_convention="positive"`` is selected (i.e., IDFT uses the opposite sign of the forward DFT convention).

Hermitian Symmetry Convention
-----------------------------

When ``hermitian_symmetry=True``, Pyralysis stores only the non-redundant half-plane in ``u`` (via ``rfft2``/``irfft2`` path):

- ``u`` is represented as non-negative indices on the stored grid.
- ``v`` remains centered.

This is a storage/computation optimization for real image-domain inputs and should be interpreted with the same sign conventions above.

Sky-Model Source Placement Factor
---------------------------------

When evaluating analytic sky models into visibility space, Pyralysis uses a **positive** phase factor:

.. math::
   \phi_\text{src}(u,v,w)=\frac{\exp\{+2\pi i(ul_0+vm_0+w(n_0-1))\}}{n_0}

This appears in source modeling utilities (for example, source sky-position factors) and is intentional:

- phase-shift operators that *move existing data* use :math:`\exp\{-2\pi i(\cdot)\}`
- source forward modeling that *synthesizes visibilities from sky components* uses :math:`\exp\{+2\pi i(\cdot)\}` in this implementation

Keep this distinction in mind when mixing custom source terms and post-FFT/visibility shift operations.
