foscat.HealBili#
HealBili: Bilinear weights from a curvilinear (theta, phi) source grid to arbitrary HEALPix targets.
This module provides a class HealBili that, given a curvilinear source grid of angular coordinates (theta[y,x], phi[y,x]) on the sphere (e.g., a tangent-plane grid built on an ellipsoid), computes bilinear interpolation weights to map values from that grid onto arbitrary target directions specified by HEALPix angles (heal_theta[n], heal_phi[n]).
Key idea#
Because the source grid is not rectilinear in index-space, we cannot assume a simple affine mapping from (i,j) to angles. Instead, for each target direction (theta_h, phi_h), we:
locate a nearby source cell (seed) by nearest neighbor search on the unit sphere;
consider up to 4 candidate quads around the seed: [(i0,j0),(i0+1,j0),(i0,j0+1),(i0+1,j0+1)];
project the 4 corner unit vectors and the target onto a local tangent plane built at the quad barycenter;
invert the bilinear mapping f(s,t) from the quad corners to the plane point using Newton, retrieving (s,t) in [0,1]^2;
build the 4 bilinear weights [(1-s)(1-t), s(1-t), (1-s)t, st] and the 4 linear indices into the source image (row-major, j*W + i).
If no candidate quad cleanly contains the point, we choose the one with the smallest residual in the plane and clamp (s,t) to [0,1].
The code is NumPy-only by default, but can optionally use scipy.spatial.cKDTree for a faster nearest neighbor seed search by setting prefer_kdtree=True (falls back automatically if SciPy is absent).
Usage#
>>> hb = HealBili(src_theta, src_phi, prefer_kdtree=True)
>>> I, W = hb.compute_weights(heal_theta, heal_phi)
>>> # Apply to a source image `img` of shape (H,W):
>>> vals = hb.apply_weights(img, I, W) # shape (N,)
All angles must be in radians. theta is colatitude (0 at north pole), phi is longitude in [0, 2*pi).
Classes#
Compute bilinear interpolation weights from a curvilinear (theta, phi) grid to HEALPix targets. |
Module Contents#
- class foscat.HealBili.HealBili(src_theta: numpy.ndarray, src_phi: numpy.ndarray, *, prefer_kdtree: bool = False)[source]#
Compute bilinear interpolation weights from a curvilinear (theta, phi) grid to HEALPix targets.
- Parameters:
src_theta (
np.ndarray,shape (H,W)) – Source colatitude (radians) at each grid node.src_phi (
np.ndarray,shape (H,W)) – Source longitude (radians) at each grid node.prefer_kdtree (
bool, defaultFalse) – If True and SciPy is available, use cKDTree on unit vectors for a faster nearest-neighbor seed. Falls back to blocked brute-force dot-product search otherwise.
- src_theta#
- src_phi#
- prefer_kdtree = False#
- compute_weights(level, cell_ids: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray][source]#
Compute bilinear weights/indices for target HEALPix angles.
- Parameters:
cell_ids (
np.ndarray,shape (N,)) – Target cell_ids .- Returns:
I (
np.ndarray,shape (4,N),dtype=int64) – Linear indices of the 4 source corners per target (row-major: j*W + i). Invalid corners are -1.W (
np.ndarray,shape (4,N),dtype=float64) – Bilinear weights aligned with I. Weights are set to 0.0 for invalid corners and normalized to sum to 1 when at least one corner is valid.
- apply_weights(img: numpy.ndarray, I: numpy.ndarray, W: numpy.ndarray) numpy.ndarray[source]#
Apply precomputed (I, W) to a source image to obtain values at the HEALPix targets.
- Parameters:
img (
np.ndarray,shape (H,W)) – Source image values defined on the same grid as (src_theta, src_phi).I (
np.ndarray,shape (4,N),dtype=int64) – Linear indices (row-major) of corner samples; -1 for invalid corners.W (
np.ndarray,shape (4,N),dtype=float64) – Bilinear weights aligned with I.
- Returns:
vals (
np.ndarray,shape (N,)) – Interpolated values at the target directions.