hwoutils.transforms
===================

.. py:module:: hwoutils.transforms

.. autoapi-nested-parse::

   Image transformation utilities.

   Flux-conserving resampling and sub-pixel image operations. All functions
   are JIT-compilable and differentiable.



Functions
---------

.. autoapisummary::

   hwoutils.transforms.ccw_rotation_matrix
   hwoutils.transforms.shift_image
   hwoutils.transforms.resample_flux
   hwoutils.transforms.downsample_psf
   hwoutils.transforms.downsample_psfs


Module Contents
---------------

.. py:function:: ccw_rotation_matrix(rotation_deg)

   Return the counter-clockwise rotation matrix for a given angle.

   Args:
       rotation_deg: Rotation angle in degrees. Positive = counter-clockwise.

   Returns:
       2x2 rotation matrix as a JAX array.


.. py:function:: shift_image(image, shift_y, shift_x, order = 3, mode = 'constant', cval = 0.0)

   Shift an image with sub-pixel precision.

   Uses inverse mapping: to shift content by (+dy, +dx), sample from
   (y-dy, x-dx).

   Args:
       image: 2D input image.
       shift_y: Shift in Y direction (pixels). Positive = Down.
       shift_x: Shift in X direction (pixels). Positive = Right.
       order: Interpolation order passed to ``map_coordinates``. Default
           is 3, which uses the Keys cubic convolution kernel (see
           ``docs/interpolation.md``).
       mode: Boundary handling mode.
       cval: Value for 'constant' mode outside boundaries.

   Returns:
       Shifted image with same shape as input.


.. py:function:: resample_flux(f_src, pixscale_src, pixscale_tgt, shape_tgt, rotation_deg = 0.0, order = 3)

   Resample an image onto a new grid while conserving total flux.

   Performs an affine transformation (rotation and scaling) to map
   the source image onto a target grid. Converts to surface brightness,
   interpolates, then converts back to integrated flux per pixel.

   Args:
       f_src: Source image (2D) with integrated flux per pixel.
       pixscale_src: Pixel scale of source image.
       pixscale_tgt: Pixel scale of target image (same units as src).
       shape_tgt: Target shape (ny_tgt, nx_tgt).
       rotation_deg: CCW rotation angle in degrees.
       order: Interpolation order passed to ``map_coordinates``. Default
           is 3, which uses the Keys cubic convolution kernel -- a true
           interpolant with partition of unity at integer grid spacing
           that conserves flux on integer downsampling of band-limited
           inputs. See ``docs/interpolation.md``.

   Returns:
       Resampled image with total flux conserved. Shape: (ny_tgt, nx_tgt).


.. py:function:: downsample_psf(psf, src_pixscale, target_shape)

   Downsample a PSF to target shape while conserving total flux.

   Args:
       psf: The source PSF image (2D array).
       src_pixscale: The pixel scale of the source PSF (in lambda/D or
           other consistent units).
       target_shape: The target shape (ny_tgt, nx_tgt).

   Returns:
       Tuple of (resampled_psf, new_pixscale).


.. py:function:: downsample_psfs(psfs, src_pixscale, target_shape)

   Downsample a stack of PSFs to target shape while conserving total flux.

   Args:
       psfs: Stack of PSF images with shape (N, H, W).
       src_pixscale: The pixel scale of the source PSFs.
       target_shape: The target shape (ny_tgt, nx_tgt) for each PSF.

   Returns:
       Tuple of (resampled_psfs, new_pixscale).


