Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ Upcoming Release
To use the features already you have to install the ``master`` branch, e.g.
``pip install git+https://github.com/pypsa/atlite``.

**Bug fixes**

* Fix ``ExclusionContainer.add_raster`` ignoring ``codes=0``. The code ``0`` was
treated like a missing ``codes`` argument, so all non-zero cells were excluded
instead of the cells with value ``0``. Numpy arrays are now accepted as
``codes``, and an empty list excludes no cells
(https://github.com/PyPSA/atlite/pull/525).

`v0.7.0 <https://github.com/PyPSA/atlite/releases/tag/v0.7.0>`__ (3rd October 2026)
=======================================================================================

Expand Down
4 changes: 2 additions & 2 deletions atlite/gis.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ def shape_availability(
masked, transform = projected_mask(
d["raster"], geometry, transform, shape, excluder.crs, **kwargs
)
if d["codes"]:
if d["codes"] is not None:
if callable(d["codes"]):
masked_ = d["codes"](masked).astype(bool)
else:
Expand Down Expand Up @@ -598,7 +598,7 @@ def add_raster(
which takes the mask (np.array) as argument and performs a
elementwise condition (must not change the shape). The function may
not be an anonymous (lambda) function.
The default is 1.
The default is None, which excludes all non-zero cells.
buffer : int, optional
Buffer around the excluded areas in units of ExclusionContainer.crs.
Use this to create a buffer around the excluded/included area.
Expand Down
17 changes: 17 additions & 0 deletions test/test_gis.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,23 @@ def test_shape_availability_exclude_raster_codes(ref, raster_codes):
assert ratio == masked.sum() / masked.size


@pytest.mark.parametrize("codes", [0, np.array([0])])
def test_shape_availability_exclude_raster_code_zero(ref, raster, codes):
"""Code 0 is excluded like any other code, not treated as a missing code."""
shapes = gpd.GeoSeries([box(X0, Y0, X1, Y1)], crs=ref.crs)
res = 0.01

excluder = ExclusionContainer(ref.crs, res=res)
excluder.add_raster(raster, codes=[0])
expected, transform = shape_availability(shapes, excluder)

excluder = ExclusionContainer(ref.crs, res=res)
excluder.add_raster(raster, codes=codes)
masked, transform = shape_availability(shapes, excluder)
assert (masked == expected).all()
assert round(masked.sum() / masked.size, 2) == raster_clip


def test_plot_shape_availability(ref, raster):
"""Test plotting of shape availability."""
shapes = gpd.GeoSeries([box(X0, Y0, X1, Y1)], crs=ref.crs)
Expand Down
Loading