Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
073e272
Added angular_variable_depth_mask and angular_los_variable_depth_mask…
mwiet Feb 24, 2025
3f87848
Added new classes to the file's index
mwiet Feb 24, 2025
aa36f81
pre-commit.ci: style fixes
pre-commit-ci[bot] Feb 24, 2025
c7393fd
Updated class to follow CapWords convention
mwiet Feb 24, 2025
31a5335
Updated class to follow CapWords convention
mwiet Feb 24, 2025
cfdaa58
Updated classes in index to follow CapWords convention
mwiet Feb 24, 2025
51b0c1b
Fixed typing of variables throughout
mwiet Feb 24, 2025
d5e5863
Fixed docstrings throughout
mwiet Feb 24, 2025
2a7ea91
Changed np.trapz to np.trapezoid
mwiet Feb 24, 2025
d3eed2f
Fixed ValueError to TypeError
mwiet Feb 24, 2025
07ccec4
Added new citations for glass.observations.AngularLosVariableDepthMask
mwiet Feb 24, 2025
7ce0c2d
Removed references from AngularLosVariableDepthMask docstring and mov…
mwiet Feb 24, 2025
375d148
Fixed outstanding typing issues
mwiet Feb 24, 2025
85a337e
Merge branch 'main' into mwiet/variable-depth
paddyroddy Feb 24, 2025
5a79a47
Fixed np.trapezoid typo
mwiet Feb 24, 2025
37f2183
Fixed np.trapezoid typo
mwiet Feb 24, 2025
c5649b2
Loaded Callable type object
mwiet Feb 24, 2025
0467b0d
Added excemption to PLR0913/too many arguments
mwiet Feb 24, 2025
78d7757
Fixed typo
mwiet Feb 24, 2025
5b1268d
Removd whitespace
mwiet Feb 24, 2025
d5a0491
Added excemption to PLR0913/too many arguments
mwiet Feb 24, 2025
1a1ff3f
Fixed pre-commit issues
mwiet Feb 24, 2025
68d5089
Added excemption to PLR0913/too many arguments
mwiet Feb 24, 2025
7b637f8
Tidy up docstrings
paddyroddy Feb 25, 2025
585ea65
Run pre-commit
paddyroddy Feb 25, 2025
1847e05
Add comma
paddyroddy Feb 25, 2025
b298f4e
Suppress no any return
paddyroddy Feb 25, 2025
368b086
Adjusted typing of vardepth_tomo_functions
mwiet Feb 25, 2025
746e4d8
Ensured consitency in the typing on zbins
mwiet Feb 25, 2025
fb9f83f
Tidied up line length
mwiet Feb 25, 2025
b094792
pre-commit.ci: style fixes
pre-commit-ci[bot] Feb 25, 2025
36d6f0d
Merge branch 'main' into mwiet/variable-depth
paddyroddy Mar 3, 2025
59b17e0
Add notebook from @mwiet and clear output
paddyroddy Mar 6, 2025
6be4bfd
Fix surname
paddyroddy Mar 6, 2025
9c44912
Tidy up imports
paddyroddy Mar 7, 2025
65eecc4
Fix line length
paddyroddy Mar 7, 2025
7e0f2c4
Fix
paddyroddy Mar 7, 2025
56136cd
Fix [NPY002](https://docs.astral.sh/ruff/rules/numpy-legacy-random/)
paddyroddy Mar 7, 2025
2267bee
Remove `plt.show`
paddyroddy Mar 7, 2025
cab715e
Better formatting
paddyroddy Mar 7, 2025
df4e5fc
Import direct from namespace
paddyroddy Mar 7, 2025
3fbd7d0
Suppress plot output
paddyroddy Mar 7, 2025
dd60d4f
Reduce down to one `mollview` plot
paddyroddy Mar 7, 2025
4134346
Add rng keyword arg where possible
paddyroddy Mar 7, 2025
3228dfe
Remove duplicate rng generation
paddyroddy Mar 7, 2025
e518883
Turn off warning
paddyroddy Mar 7, 2025
059ac59
Move notebook
paddyroddy Mar 7, 2025
6f81ecb
Add title
paddyroddy Mar 7, 2025
d61e5f2
Clear output
paddyroddy Mar 7, 2025
b56028b
gh-578: mutable argument should be empty list rather than `None`
paddyroddy Mar 10, 2025
5bc2588
Merge branch 'paddy/issue-578' into mwiet/variable-depth
paddyroddy Mar 10, 2025
a9f32e4
Merge branch 'main' into mwiet/variable-depth
paddyroddy Mar 10, 2025
9bb8f8f
Fix import
paddyroddy Mar 10, 2025
67e028f
Remove `nbstripout` temporarily
paddyroddy Mar 12, 2025
e564a8e
Merge branch 'main' into mwiet/variable-depth
paddyroddy Mar 12, 2025
cd71581
Fix notebook
paddyroddy Mar 12, 2025
996e7e2
Restore
paddyroddy Mar 12, 2025
c8d1f5a
Add RNG
paddyroddy Mar 12, 2025
ab38ee3
Speed up sampling
paddyroddy Mar 12, 2025
d551fc3
Run notebook
paddyroddy Mar 12, 2025
d53e03c
Merge branch 'main' into mwiet/variable-depth
paddyroddy Mar 13, 2025
683b458
Re-use maps
paddyroddy Mar 13, 2025
a5e4c0d
Fix notebook running
paddyroddy Mar 13, 2025
eb412f7
Increase timeout
paddyroddy Mar 13, 2025
21f8cce
Change lmax
paddyroddy Mar 13, 2025
a4efa52
Revert "Increase timeout"
paddyroddy Mar 13, 2025
8746064
Test AngularVariableDepthMask
paddyroddy Mar 13, 2025
3e31f06
Rename notebook
paddyroddy Mar 14, 2025
002785e
2 digit years
paddyroddy Mar 14, 2025
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
1 change: 1 addition & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ More advanced examples doing multiple things at the same time.
examples/2-advanced/cosmic_shear.ipynb
examples/2-advanced/stage_4_galaxies.ipynb
examples/2-advanced/legacy-mode.ipynb
examples/2-advanced/variable-depth.ipynb
6 changes: 6 additions & 0 deletions docs/user/bibliography.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Bibliography
.. [Johnston19] Johnston, H., Georgiou, C., Joachimi, B., et al., 2019,
A&A, 624, A30. doi:10.1051/0004-6361/201834714

.. [Joachimi21] Joachimi B., Lin, C.-A., et al., 2021, A&A, 646, A129.
doi:10.1051/0004-6361/202038831

.. [Lawson95] Lawson, C. L. and Hanson, R. J. (1995), Solving Least Squares
Problems. doi: 10.1137/1.9781611971217

Expand All @@ -43,3 +46,6 @@ Bibliography

.. [Xavier16] Xavier H. S., et al., 2016, MNRAS, 459, 3693.
doi:10.1093/mnras/stw874

.. [Wietesheim-Kramsta24] von Wietersheim-Kramsta M., Lin, K., et al.,
2024, A&A, 695, A223. doi:10.1051/0004-6361/202450487
521 changes: 521 additions & 0 deletions examples/2-advanced/variable-depth.ipynb

Large diffs are not rendered by default.

207 changes: 207 additions & 0 deletions glass/observations.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
----------

.. autofunction:: vmap_galactic_ecliptic
.. class:: AngularVariableDepthMask
.. class:: AngularLosVariableDepthMask

""" # noqa: D400

Expand All @@ -37,6 +39,8 @@
import glass.arraytools

if TYPE_CHECKING:
from collections.abc import Callable

from numpy.typing import NDArray


Expand Down Expand Up @@ -328,3 +332,206 @@ def tomo_nz_gausserr(
binned_nz *= nz

return binned_nz # type: ignore[no-any-return]


class AngularVariableDepthMask:
"""Variable depth mask for tomographic bins.

This class allows to create a mask with a different variable
depth mask in the angular direction for each tomographic bin.

Parameters
----------
vardepth_map
Map of variable which traces the depth per tomographic bin.
n_bins
Number of tomographic bins.
zbins
Shell redshift limits.

"""

def __init__(
self,
vardepth_map: NDArray[np.float64],
n_bins: int,
zbins: list[tuple[float, float]],
) -> None:
self.vardepth_map = vardepth_map
self.n_bins = n_bins
self.zbins = zbins

def check_index(self, index: tuple[int, int]) -> None:
"""Check the index for validity."""
if not isinstance(index, tuple):
raise TypeError("Index must be an tuple of two integers")

if index[0] >= self.n_bins:
raise ValueError("Leading index cannot exceed number of tomographic bins")

if index[1] >= len(self.zbins):
raise ValueError("Trailing index cannot exceed number of shells")

def __getitem__(self, index: tuple[int, int]) -> NDArray[np.float64]:
"""Get the mask for the given index.

Parameters
----------
index
Indices of the tomographic bin and shell pair.

Returns
-------
Mask for the given index.

Raises
------
ValueError
If the index is invalid.

"""
self.check_index(index)

return self.vardepth_map[index[0]] # type: ignore[no-any-return]


class AngularLosVariableDepthMask(AngularVariableDepthMask):
"""Variable depth mask for tomographic bins.

This class allows to create a mask with a different variable
depth mask in both the angular and the line-of-sight directions
for each tomographic bin.

Parameters
----------
vardepth_map
Map of variable which traces the depth per tomographic bin.
If vardepth_tomo_functions is not provided, the values are
treated like a map of galaxy count ratios.
n_bins
Number of tomographic bins.
zbins
Shell redshift limits.
ztomo
Tomographic redshift bin limits.
dndz
Redshift distributions per tomographic bin.
z
Redshift domain of dndz.
dndz_vardepth
Redshift distribution affected by variable depth
(n_bins x len(vardepth_values) x len(z)).
vardepth_values
Variable depth tracer domain/values of dndz_vardepth.
vardepth_los_tracer
Map of the variable depth tracer for line-of-sight direction. If
provided, it is assumed to cover the same domain as vardepth_values.
vardepth_tomo_functions
List of functions which map the input vardepth_map to the ratio
between the galaxy count due to the variable depth and the galaxy
count without variable depth (for each tomographic bin). If
provided, it is assumed that there is one vardepth_map which
traces the variable depth for all tomographic bins.

"""

def __init__( # noqa: PLR0913
self,
vardepth_map: NDArray[np.float64],
n_bins: int,
zbins: list[tuple[float, float]],
ztomo: list[tuple[float, float]],
dndz: NDArray[np.float64],
z: NDArray[np.float64],
dndz_vardepth: NDArray[np.float64],
vardepth_values: NDArray[np.float64],
vardepth_los_tracer: NDArray[np.float64] | None = None,
vardepth_tomo_functions: list[
Callable[[NDArray[np.float64]], NDArray[np.float64]]
]
| None = None,
) -> None:
super().__init__(vardepth_map, n_bins, zbins)
self.ztomo = ztomo
self.dndz = dndz
self.z = z
self.dndz_vardepth = dndz_vardepth
self.vardepth_values = vardepth_values
self.vardepth_los_tracer = vardepth_los_tracer
self.vardepth_tomo_functions = vardepth_tomo_functions

if vardepth_tomo_functions is not None:
self.vardepth_map = np.atleast_2d(vardepth_map).reshape(1, -1)

def get_los_fraction(self, index: tuple[int, int]) -> NDArray[np.float64]:
"""Gets the fraction of galaxies affected by variable depth in the
line-of-sight direction for the given tomographic bin and shell.

Parameters
----------
index
Indices of the tomographic bin and shell pair.

Returns
-------
Fraction of galaxies affected by variable depth in the
line-of-sight direction.

"""
is_in_shell = (self.zbins[index[1]][0] < self.z) & (
self.z <= self.zbins[index[1]][1]
)

n_gal_in_tomo_vardepth = np.trapezoid(
self.dndz_vardepth[index[0]][:, is_in_shell], self.z[is_in_shell]
)
n_gal_in_tomo = np.trapezoid(
self.dndz[index[0]][is_in_shell], self.z[is_in_shell]
)
return np.divide( # type: ignore[no-any-return]
n_gal_in_tomo_vardepth,
n_gal_in_tomo,
out=np.ones_like(n_gal_in_tomo_vardepth),
where=n_gal_in_tomo != 0,
)

def __getitem__(self, index: tuple[int, int]) -> NDArray[np.float64]:
"""Get the mask for the given index.

Parameters
----------
index
Indices of the tomographic bin and shell pair.

Returns
-------
Mask for the given index.

Raises
------
ValueError
If the index is invalid.

"""
self.check_index(index)

if self.vardepth_tomo_functions is None:
angular_vardepth_map = angular_tracer_map = self.vardepth_map[index[0]]
else:
angular_vardepth_map = self.vardepth_tomo_functions[index[0]](
self.vardepth_map[0]
)
angular_tracer_map = self.vardepth_map[0]

los_fraction_vardepth = self.get_los_fraction(index)

if self.vardepth_los_tracer is None:
los_vardepth_map = np.interp(
angular_tracer_map, self.vardepth_values, los_fraction_vardepth
)
else:
los_vardepth_map = np.interp(
self.vardepth_los_tracer, self.vardepth_values, los_fraction_vardepth
)

return np.multiply(angular_vardepth_map, los_vardepth_map) # type: ignore[no-any-return]
85 changes: 85 additions & 0 deletions tests/test_observations.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import healpix
import numpy as np
import pytest
from numpy.typing import NDArray

import glass
import glass.observations


def test_vmap_galactic_ecliptic() -> None:
Expand Down Expand Up @@ -136,3 +138,86 @@ def test_tomo_nz_gausserr() -> None:
# check the shape of the output

np.testing.assert_array_equal(binned_nz.shape, (len(zbins), len(z)))


@pytest.mark.parametrize(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started to add tests yesterday before @ntessore's review. It feels pointless continuing these given the proposed changes.

("vardepth_map", "n_bins", "zbins", "index", "expected_mask"),
[
(
np.array([[1.0, 2.0], [3.0, 4.0]]),
2,
[(0.0, 0.5), (0.5, 1.0)],
(0, 0),
np.array([1.0, 2.0]),
),
(
np.array([[1.0, 2.0], [3.0, 4.0]]),
2,
[(0.0, 0.5), (0.5, 1.0)],
(1, 1),
np.array([3.0, 4.0]),
),
],
ids=["test_valid_index_1", "test_valid_index_2"],
)
def test_getitem_happy_path(
vardepth_map: NDArray[np.float64],
n_bins: int,
zbins: list[tuple[float, float]],
index: tuple[int, int],
expected_mask: NDArray[np.float64],
) -> None:
# Arrange
mask = glass.observations.AngularVariableDepthMask(vardepth_map, n_bins, zbins)

# Act
result = mask[index]

# Assert
np.testing.assert_array_equal(result, expected_mask)


@pytest.mark.parametrize(
("vardepth_map", "n_bins", "zbins", "index", "expected_error"),
[
(
np.array([[1.0, 2.0], [3.0, 4.0]]),
2,
[(0.0, 0.5), (0.5, 1.0)],
(2, 0),
ValueError,
),
(
np.array([[1.0, 2.0], [3.0, 4.0]]),
2,
[(0.0, 0.5), (0.5, 1.0)],
(0, 2),
ValueError,
),
(
np.array([[1.0, 2.0], [3.0, 4.0]]),
2,
[(0.0, 0.5), (0.5, 1.0)],
0,
TypeError,
),
],
ids=[
"test_invalid_index_1",
"test_invalid_index_2",
"test_invalid_index_type",
],
)
def test_getitem_error_cases(
vardepth_map: NDArray[np.float64],
n_bins: int,
zbins: list[tuple[float, float]],
index: tuple[int, int],
expected_error: type[BaseException],
) -> None:
# Arrange
mask = glass.observations.AngularVariableDepthMask(vardepth_map, n_bins, zbins)

# Act & Assert
with pytest.raises(expected_error):
mask[index]