Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
620a4b5
gh-1238: Move all `importlib.util` lines to their own file
paddyroddy Oct 6, 2026
18389c9
Remove `HAVE_FITSIO` from non-testing bit
paddyroddy Oct 6, 2026
e75aa44
Tidy up JAX and `array-api-strict` fixtures
paddyroddy Oct 6, 2026
7ae5826
Use JAX and `array-api-strict` fixtures
paddyroddy Oct 6, 2026
8593990
Remove duplicate import
paddyroddy Oct 6, 2026
dd77c88
Grammar
paddyroddy Oct 6, 2026
f01601e
Fix lint
paddyroddy Oct 6, 2026
4d78656
Consistent `glass.rng` import
paddyroddy Oct 7, 2026
60372e6
Create wrapper for harmonic transforms
paddyroddy Oct 6, 2026
b164d22
Fix linting
paddyroddy Oct 6, 2026
02d4643
Restore `piwin`, `pol`, ...
paddyroddy Oct 7, 2026
f60c2cb
Fix overloads
paddyroddy Oct 7, 2026
aea630a
Improve docstring
paddyroddy Oct 7, 2026
f2f78c6
Add tests
paddyroddy Oct 7, 2026
3920b94
Add comment on boolean options
paddyroddy Oct 7, 2026
3cd6473
Remove unused `nside`
paddyroddy Oct 7, 2026
6910960
Add `healpy` to test name
paddyroddy Oct 7, 2026
3342073
Remove unused `ang2vec`
paddyroddy Oct 7, 2026
c3ff7a3
Replace `almxfl` with `glass.harmonics.multalm`
paddyroddy Oct 7, 2026
18a5ab7
Remove `get_nside` function
paddyroddy Oct 7, 2026
e1929e3
Make sure `alm` is a real map
paddyroddy Oct 7, 2026
a2ea036
Remove `pol`, `pixwin`, `use_pixel_weights`
paddyroddy Oct 7, 2026
dd131fa
Merge branch 'main' into paddy/issue-1233
paddyroddy Oct 7, 2026
3288daa
Remove array api strict import
paddyroddy Oct 7, 2026
3129a39
Remove imports
paddyroddy Oct 7, 2026
c0eaba7
Use `jnp` fixture
paddyroddy Oct 7, 2026
1b34c25
Remove config
paddyroddy Oct 7, 2026
901d74e
Add comment explaining
paddyroddy Oct 7, 2026
c0fd9ba
Remove unrequired `importorskip` lines
paddyroddy Oct 7, 2026
2c6fbdf
Compare output to `glass.healpix`
paddyroddy Oct 7, 2026
c8c5737
Merge branch 'paddy/issue-1233' into paddy/issue-794
paddyroddy Oct 7, 2026
b7e6501
Merge branch 'paddy/issue-794' into paddy/issue-1243
paddyroddy Oct 7, 2026
952feed
Restore `use_pixel_weights`
paddyroddy Oct 7, 2026
d02f812
Restore docstring
paddyroddy Oct 7, 2026
8f7417c
Remove reference to `pol`
paddyroddy Oct 7, 2026
d140e9e
Sort missing parameters
paddyroddy Oct 7, 2026
ae67de3
Remove the reality fix for map
paddyroddy Oct 7, 2026
b638a27
One line
paddyroddy Oct 7, 2026
8715365
Default to pixel weights
paddyroddy Oct 7, 2026
f4e2360
Always use pixel weights
paddyroddy Oct 7, 2026
919fd2b
Merge branch 'main' into paddy/issue-1243
paddyroddy Oct 7, 2026
83b6d91
Make SHT functions private
paddyroddy Oct 8, 2026
fbc0e2a
Merge branch 'main' into paddy/issue-1243
paddyroddy Oct 8, 2026
11e1882
Ran notebooks
paddyroddy Oct 8, 2026
7e6e9dd
Merge branch 'main' into paddy/issue-1243
paddyroddy Oct 15, 2026
90d8de0
Fix lint
paddyroddy Oct 15, 2026
2c7a8f9
Merge branch 'main' into paddy/issue-1243
paddyroddy Oct 16, 2026
4a8860f
Merge branch 'main' into paddy/issue-1243
paddyroddy Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions docs/modules/healpix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,13 @@ This module should be imported manually if used outside of GLASS::
---------------------

.. autofunction:: ang2pix
.. autofunction:: ang2vec
.. autofunction:: npix2nside
.. autofunction:: nside2npix
.. autofunction:: randang

``healpy`` Functions
--------------------

.. autofunction:: alm2map
.. autofunction:: alm2map_spin
.. autofunction:: almxfl
.. autofunction:: get_nside
.. autofunction:: map2alm
.. autofunction:: pixwin
.. autofunction:: query_strip
.. automethod:: Rotator.rotate_map_pixel
4 changes: 2 additions & 2 deletions examples/2-advanced/legacy-mode.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@
{
"data": {
"text/plain": [
"np.False_"
"False"
]
},
"execution_count": null,
Expand Down Expand Up @@ -537,7 +537,7 @@
{
"data": {
"text/plain": [
"np.True_"
"True"
]
},
"execution_count": null,
Expand Down
8 changes: 1 addition & 7 deletions glass/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,7 @@ def _generate_grf(
alm = xpx.at(alm)[:n].set(xp.real(alm[:n]) + xp.imag(alm[:n]) + 0j) # ty: ignore[not-subscriptable]

# transform alm to maps
yield glass.harmonics.inverse_transform(
alm,
lmax=n - 1,
nside=nside,
pixwin=False,
pol=False,
)
yield glass.harmonics.inverse_transform(alm, lmax=n - 1, nside=nside)


def getcl(
Expand Down
30 changes: 6 additions & 24 deletions glass/harmonics.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import array_api_compat

import glass.healpix as hp
from glass.healpix import _alm2map, _alm2map_spin, _map2alm

if TYPE_CHECKING:
from glass._types import ComplexArray, FloatArray
Expand Down Expand Up @@ -60,8 +60,6 @@ def inverse_transform(
*,
lmax: int,
nside: int,
pixwin: bool = False,
pol: bool = True,
spin: typing.Literal[0] = 0,
) -> FloatArray:
# returns a real scalar map
Expand All @@ -74,8 +72,6 @@ def inverse_transform(
*,
lmax: int,
nside: int,
pixwin: bool = False,
pol: bool = True,
spin: typing.Literal[1, 2],
) -> ComplexArray:
# returns a complex map for spin 1 or 2
Expand All @@ -88,21 +84,17 @@ def inverse_transform(
*,
lmax: int,
nside: int,
pixwin: bool = False,
pol: bool = True,
spin: int,
) -> FloatArray | ComplexArray:
# returns a real or complex map depending on the spin
...


def inverse_transform( # noqa: PLR0913
def inverse_transform(
alm: ComplexArray,
*,
lmax: int,
nside: int,
pixwin: bool = False,
pol: bool = True,
spin: int = 0,
) -> FloatArray | ComplexArray:
"""
Expand All @@ -120,11 +112,6 @@ def inverse_transform( # noqa: PLR0913
The maximum multipole of the spherical harmonic transform.
nside
The nside parameter of the output map.
pixwin
Whether to apply the pixel window function. Has no effect for non-zero
spin.
pol
Whether to compute polarization. Has no effect for non-zero spin.
spin
Spin of the output map. Zero produces a real scalar map; non-zero spin
produces a complex map whose real and imaginary parts are the two
Expand All @@ -138,18 +125,16 @@ def inverse_transform( # noqa: PLR0913
xp = alm.__array_namespace__()

if spin == 0:
return hp.alm2map(alm, nside, lmax=lmax, pixwin=pixwin, pol=pol)
return _alm2map(alm, nside, lmax=lmax)

maps = hp.alm2map_spin([alm, xp.zeros_like(alm)], nside, spin, lmax)
maps = _alm2map_spin([alm, xp.zeros_like(alm)], nside, spin, lmax)
return maps[0] + 1j * maps[1]


def transform(
maps: FloatArray,
*,
lmax: int,
pol: bool = True,
use_pixel_weights: bool = False,
) -> ComplexArray:
"""
Compute the spherical harmonic transform of a map.
Expand All @@ -160,14 +145,11 @@ def transform(
The real-space map to transform.
lmax
The maximum multipole of the spherical harmonic transform.
pol
Whether to compute polarization.
use_pixel_weights
Whether to use pixel weights in the transform.

Returns
-------
The spherical harmonic coefficients resulting from the transform.

"""
return hp.map2alm(maps, lmax=lmax, pol=pol, use_pixel_weights=use_pixel_weights)
# the only time GLASS used _map2alm was with pixel weights
return _map2alm(maps, lmax=lmax, use_pixel_weights=True)
99 changes: 4 additions & 95 deletions glass/healpix.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,11 @@ def _get_healpy_datapath() -> str | None:


@numpy_fallback
def alm2map(
def _alm2map(
alms: ComplexArray | Sequence[ComplexArray],
nside: int,
*,
lmax: int | None = None,
pixwin: bool = False,
pol: bool = True,
) -> FloatArray:
"""
Computes a HEALPix map given the alm.
Expand All @@ -57,28 +55,18 @@ def alm2map(
The nside of the output map.
lmax
Explicitly define lmax.
pixwin
Smooth the alm using the pixel window functions.
pol
If True, assumes input alms are TEB.

Returns
-------
A HEALPix map in RING scheme at nside, or a two-dimensional array
containing the T, Q, and U maps for polarized input.

"""
return healpy.alm2map(
alms,
nside,
lmax=lmax,
pixwin=pixwin,
pol=pol,
)
return healpy.alm2map(alms, nside, lmax=lmax)


@numpy_fallback
def alm2map_spin(
def _alm2map_spin(
alms: Sequence[FloatArray],
nside: int,
spin: int,
Expand Down Expand Up @@ -107,30 +95,6 @@ def alm2map_spin(
return list(outputs)


@numpy_fallback
def almxfl(
alm: ComplexArray,
fl: FloatArray,
) -> ComplexArray:
"""
Multiply alm by a function of l. The function is assumed to be zero where
not defined.

Parameters
----------
alm
The alm to multiply.
fl
The function (at l=0..fl.shape[0]-1) by which alm must be multiplied.

Returns
-------
The new alm array with the function of l applied.

"""
return healpy.almxfl(alm, fl)


@numpy_fallback
def ang2pix(
nside: int,
Expand Down Expand Up @@ -167,61 +131,10 @@ def ang2pix(


@numpy_fallback
def ang2vec(
theta: float | FloatArray,
phi: float | FloatArray,
*,
lonlat: bool = False,
) -> tuple[FloatArray, FloatArray, FloatArray]:
"""
Convert angles to 3D position vector.

Parameters
----------
theta
Angular coordinates of a point on the sphere.
phi
Angular coordinates of a point on the sphere.
lonlat
If True, automatically adjust latitudes to be within [-90, 90] range.

Returns
-------
A normalised 3-vector pointing in the same direction as ``ang``.

"""
x, y, z = healpix.ang2vec(
theta,
phi,
lonlat=lonlat,
)
return x, y, z


@numpy_fallback
def get_nside(m: FloatArray) -> int:
"""
Return the nside of the given map.

Parameters
----------
m
The map to get the nside from.

Returns
-------
The HEALPix nside parameter of the map.

"""
return int(healpy.get_nside(m))


@numpy_fallback
def map2alm(
def _map2alm(
maps: FloatArray | Sequence[FloatArray],
*,
lmax: int | None = None,
pol: bool = True,
use_pixel_weights: bool = False,
Comment thread
paddyroddy marked this conversation as resolved.
) -> ComplexArray:
"""
Expand All @@ -243,9 +156,6 @@ def map2alm(
The input map or a list of n input maps. Must be in ring ordering.
lmax
Maximum l of the power spectrum.
pol
If True, assumes input maps are TQU. If False, only the temperature map
is considered.
use_pixel_weights
If True, use pixel by pixel weighting, healpy will automatically
download the weights, if needed.
Expand All @@ -259,7 +169,6 @@ def map2alm(
maps,
datapath=_get_healpy_datapath(),
lmax=lmax,
pol=pol,
use_pixel_weights=use_pixel_weights,
)

Expand Down
15 changes: 5 additions & 10 deletions glass/lensing.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,17 +289,12 @@ def from_convergence( # noqa: PLR0913
return ()

# get the NSIDE parameter
nside = hp.get_nside(kappa)
nside = hp.npix2nside(kappa.shape[-1])
if lmax is None:
lmax = 3 * nside - 1

# compute alm
alm = glass.harmonics.transform(
kappa,
lmax=lmax,
pol=False,
use_pixel_weights=True,
)
alm = glass.harmonics.transform(kappa, lmax=lmax)

# mode number; all conversions are factors of this.
# Must be float to allow division later
Expand All @@ -315,7 +310,7 @@ def from_convergence( # noqa: PLR0913
lambda a: xp.divide(-2.0, a * (a + 1)),
fill_value=0,
)
alm = hp.almxfl(alm, fl)
alm = glass.harmonics.multalm(alm, fl)

# if potential is requested, compute map and add to output
if potential:
Expand All @@ -329,7 +324,7 @@ def from_convergence( # noqa: PLR0913
# compute deflection alms in place
fl = xp.sqrt(ell * (ell + 1))
# missing spin-1 pixel window function here
alm = hp.almxfl(alm, fl)
alm = glass.harmonics.multalm(alm, fl)

# if deflection is requested, compute spin-1 maps and add to output
if deflection:
Expand All @@ -352,7 +347,7 @@ def from_convergence( # noqa: PLR0913
if discretized:
pw0, pw2 = hp.pixwin(nside, lmax=lmax, pol=True, xp=xp)
fl *= pw2 / pw0
alm = hp.almxfl(alm, fl)
alm = glass.harmonics.multalm(alm, fl)

# transform to shear maps
gamma = glass.harmonics.inverse_transform(alm, lmax=lmax, nside=nside, spin=2)
Expand Down
11 changes: 8 additions & 3 deletions tests/core/test_harmonics.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_inverse_transform_healpy(xp: ModuleType) -> None:
nside = 1
lmax = 2

expected = hp.alm2map(alm, nside=nside, lmax=lmax)
expected = hp._alm2map(alm, nside=nside, lmax=lmax)
actual = glass.harmonics.inverse_transform(alm, lmax=lmax, nside=nside)
xpx.testing.assert_equal(actual, expected)

Expand All @@ -72,7 +72,7 @@ def test_inverse_transform_healpy_spin(
lmax = 2
nside = 1

result = hp.alm2map_spin([alm, xp.zeros_like(alm)], nside, spin, lmax)
result = hp._alm2map_spin([alm, xp.zeros_like(alm)], nside, spin, lmax)
expected = result[0] + 1j * result[1]
actual = glass.harmonics.inverse_transform(alm, lmax=lmax, nside=nside, spin=spin)
xpx.testing.assert_equal(actual, expected)
Expand All @@ -82,6 +82,11 @@ def test_transform_healpy(xp: ModuleType) -> None:
maps = xp.asarray([1.0] * 12)
lmax = 2

expected = hp.map2alm(maps, lmax=lmax)
expected = hp._map2alm(
maps,
lmax=lmax,
# using pixel weights is the default in the transform
use_pixel_weights=True,
)
actual = glass.harmonics.transform(maps, lmax=lmax)
xpx.testing.assert_equal(actual, expected)
Loading
Loading