diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index acbb91bd..0e040e4b 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -17,6 +17,13 @@ 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** + +* Fill missing irradiation data with zero for ``trigon_model="other"``, as for + ``trigon_model="simple"``. Before, cells without data, e.g. north of 65° N in SARAH + cutouts, returned NaN and made aggregated time series NaN + (https://github.com/PyPSA/atlite/pull/528). + `v0.7.0 `__ (3rd October 2026) ======================================================================================= diff --git a/atlite/pv/irradiation.py b/atlite/pv/irradiation.py index 3cf9f526..b84d6432 100644 --- a/atlite/pv/irradiation.py +++ b/atlite/pv/irradiation.py @@ -362,7 +362,7 @@ def clip(influx: xr.DataArray, influx_max: xr.DataArray) -> xr.DataArray: ds, solar_position, surface_orientation, direct + diffuse ) - total_t = direct_t + diffuse_t + ground_t + total_t = direct_t.fillna(0.0) + diffuse_t.fillna(0.0) + ground_t.fillna(0.0) result: xr.DataArray if irradiation == "total": diff --git a/test/test_irradiation.py b/test/test_irradiation.py new file mode 100644 index 00000000..6d895bc1 --- /dev/null +++ b/test/test_irradiation.py @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: Contributors to atlite +# +# SPDX-License-Identifier: MIT + +"""Tests for the irradiation on tilted surfaces.""" + +import numpy as np +import pandas as pd +import pytest +import xarray as xr + +from atlite.convert import convert_irradiation +from atlite.pv.orientation import get_orientation + + +@pytest.mark.parametrize("trigon_model", ["simple", "other"]) +def test_total_irradiation_is_zero_where_data_is_missing(trigon_model): + time = pd.date_range("2013-06-01 10:00", periods=3, freq="h") + coords = {"time": time, "y": [50.0, 70.0], "x": [5.0]} + + def var(values): + return (("time", "y", "x"), np.broadcast_to(values, (3, 2, 1)).copy()) + + missing = np.array([[1.0], [np.nan]]) + ds = xr.Dataset( + { + "influx_toa": var(1000.0), + "influx_direct": var(300.0 * missing), + "influx_diffuse": var(100.0 * missing), + "albedo": var(0.2), + "solar_altitude": var(0.8 * missing), + "solar_azimuth": var(3.0 * missing), + }, + coords=coords, + ) + ds = ds.assign_coords(lon=("x", coords["x"]), lat=("y", coords["y"])) + orientation = get_orientation({"slope": 30.0, "azimuth": 180.0}) + + res = convert_irradiation(ds, orientation, trigon_model=trigon_model) + + assert (res.sel(y=50.0) > 0).all() + assert (res.sel(y=70.0) == 0).all()