healpix_analyse.down ==================== .. py:module:: healpix_analyse.down .. autoapi-nested-parse:: down.py ======= HEALPix resolution-reduction operator for the ``healpix_analyse`` package. Reduces the HEALPix resolution by a factor of 2: nside_out = nside_in // 2 N_out = N_in // 4 Two modes: "smooth" -- weighted Gaussian average over a disc (linear, differentiable). "maxpool" -- non-linear max over the 4 direct NESTED children. Works on the full sphere or on a partial-sky subset. Resolution is exposed through the Grid4Earth ``level`` convention, with ``nside = 2**level``. Accepts numpy arrays or torch tensors of shape ``[N]`` or ``[B, N]`` and returns an output of the same type and number of dimensions. Dependencies: numpy, torch, healpy. Attributes ---------- .. autoapisummary:: healpix_analyse.down.ArrayLike Classes ------- .. autoapisummary:: healpix_analyse.down.HealPixDown Module Contents --------------- .. py:data:: ArrayLike .. py:class:: HealPixDown(level: int, mode: str = 'smooth', ellipsoid: str = 'WGS84', radius_deg: Optional[float] = None, sigma_deg: Optional[float] = None, weight_norm: str = 'l1', cell_ids: Optional[ArrayLike] = None, device: Optional[Union[str, torch.device]] = None, dtype: torch.dtype = torch.float32) Bases: :py:obj:`torch.nn.Module` HEALPix downsampling: reduce resolution by a factor of 2. Reduces ``level`` → ``level - 1`` using either a Gaussian-weighted sparse matrix (``mode="smooth"``) or a max-pooling over the 4 direct NESTED children (``mode="maxpool"``). Can operate on the full sphere or on a partial-sky subset. :Parameters: * **level** (:py:class:`int`) -- Input Grid4Earth/HEALPix level. Must be an integer ≥ 1. The corresponding HEALPix resolution is ``nside_in = 2**level``. When ``cell_ids`` is ``None``, the input is expected to have ``N = 12 * nside_in**2`` pixels. * **mode** (``{"smooth", "maxpool"}``, *default* ``"smooth"``) -- Downsampling strategy. *smooth* -- differentiable Gaussian-weighted average (linear). *maxpool* -- non-linear max over 4 NESTED children (fast). * **radius_deg** (:py:class:`float` or :py:obj:`None`) -- Angular radius of the Gaussian kernel (degrees). Defaults to ~3 times the fine pixel size. Only used for ``mode="smooth"``. * **sigma_deg** (:py:class:`float` or :py:obj:`None`) -- Gaussian sigma (degrees). Defaults to ``radius_deg / 2``. Only used for ``mode="smooth"``. * **weight_norm** (``{"l1", "l2", "none"}``, *default* ``"l1"``) -- Normalisation applied per output pixel in ``mode="smooth"``: *l1* -- sum of weights = 1 (preserves constant fields). *l2* -- sum of squares = 1 (preserves local energy). *none* -- raw Gaussian weights (not recommended). * **cell_ids** (:py:class:`array-like` of :py:class:`int` or :py:obj:`None`) -- Pixel indices (NESTED ordering) of the input sub-map. If ``None``, the operator covers the full sphere. * **device** (:py:class:`torch.device` or :py:class:`str` or :py:obj:`None`) -- Device for the sparse matrix and computations. Defaults to CUDA if available, else CPU. * **dtype** (:py:class:`torch.dtype`, *default* :py:class:`torch.float32`) -- Floating-point dtype for the sparse matrix values. .. admonition:: Examples Full sphere: >>> import numpy as np >>> from healpix_analyse.down import HealPixDown >>> level = 6 >>> nside = 2**level >>> x = np.random.randn(12 * nside**2) # [N] >>> down = HealPixDown(level=level) >>> y, cell_ids_out = down(x) >>> y.shape (12288,) # 12 * 32**2 Partial sky: >>> import healpy as hp >>> cell_ids = hp.query_disc(nside, hp.ang2vec(np.pi/2, 0), 0.3, nest=True) >>> down = HealPixDown(level=level, cell_ids=cell_ids) >>> y, coarse_ids = down(x[cell_ids]) .. py:attribute:: device .. py:attribute:: dtype :value: Ellipsis .. py:attribute:: ellipsoid :value: '' .. py:attribute:: level_in .. py:attribute:: level_out .. py:attribute:: level .. py:attribute:: nside_in .. py:attribute:: nside_out .. py:attribute:: N_in_full .. py:attribute:: N_out_full .. py:attribute:: mode :value: '' .. py:attribute:: weight_norm :value: '' .. py:attribute:: partial .. py:property:: cell_ids_out :type: numpy.ndarray Output cell ids (coarse-resolution NESTED indices). .. py:method:: forward(x: ArrayLike) -> Tuple[ArrayLike, numpy.ndarray] Apply the downsampling operator. :Parameters: **x** (:py:class:`numpy.ndarray` or :py:class:`torch.Tensor`, :py:class:`shape [N]` or :py:class:`[B`, :py:class:`N]`) -- Input map(s) at fine resolution ``nside_in``. When ``cell_ids`` was given at construction, ``N`` must equal ``len(cell_ids)``. Otherwise ``N = 12 * nside_in**2``. :returns: * **y** (:py:class:`same type as x`, :py:class:`shape [N_out]` or :py:class:`[B`, :py:class:`N_out]`) -- Downsampled map(s) at coarse resolution ``nside_out``. * **cell_ids_out** (:py:class:`np.ndarray`) -- NESTED pixel indices of the output pixels at ``nside_out``.