Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5f87745
atlite-mrel first commit
Oct 16, 2025
20045e1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 5, 2025
ffb156d
code resolutions for merge
Nov 7, 2025
2b0380e
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 7, 2025
dcffaef
commit to fork
Nov 7, 2025
3383ebc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 7, 2025
7b6872f
fix count message error
Nov 10, 2025
335a67c
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 10, 2025
1b7efd7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 10, 2025
7067490
fix docstring
Nov 10, 2025
3f0c0df
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 10, 2025
7aaae50
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 10, 2025
a1a2aaa
fix syntax
Nov 10, 2025
963896d
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 10, 2025
76f94fd
copyrights cerra
Nov 10, 2025
5f6cfe2
fix syntax
Nov 11, 2025
39eefe6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 11, 2025
ba748f4
convert func
Nov 11, 2025
f2acfc4
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 11, 2025
1de851d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 11, 2025
83ae74a
wec renaming
Nov 14, 2025
669ad8e
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 14, 2025
400b591
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 14, 2025
4a3e2a2
cutout example MREL
Nov 20, 2025
c76e86c
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 20, 2025
124a9d2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
66a2d65
update convert function
Nov 20, 2025
9cb7ff7
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 20, 2025
58d0a2c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
a63d82c
fix output
Nov 20, 2025
0c50fa9
update commit
Nov 20, 2025
d53fdd6
correct syntax
Nov 20, 2025
0c0b726
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Nov 20, 2025
5cc55a8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
8b4ae18
syntax corrections
Nov 20, 2025
9b7cae6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
b06dfd3
delete picture
Nov 20, 2025
0363202
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 20, 2025
270951b
Merge branch 'master' into wecmatrices-datamodules
lmezilis Nov 20, 2025
f2f5cbb
Merge remote-tracking branch 'upstream/master' into wecmatrices-datam…
Aug 25, 2026
cfc84a3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 25, 2026
c6b442a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 25, 2026
3ace155
resolve pre-commit conflicts
Aug 25, 2026
934fbc7
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Aug 25, 2026
4e493e8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 25, 2026
79fbd73
Fix docstrings
Aug 25, 2026
f44b77b
Merge branch 'wecmatrices-datamodules' of https://github.com/lmezilis…
Aug 25, 2026
d8b0602
Fix convert_wave docstring
Aug 25, 2026
c92f9db
Merge remote-tracking branch 'fork/wecmatrices-datamodules' into wecm…
Aug 25, 2026
e3bd195
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 25, 2026
c7d9fef
fix pre-commit issues
Aug 25, 2026
e3d1a3d
mypy issues
Aug 25, 2026
cc35f64
Merge remote-tracking branch 'fork/wecmatrices-datamodules' into wecm…
Aug 25, 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ paper
.idea/
.vscode
AGENTS.md
uv.lock
uv.lock
100 changes: 99 additions & 1 deletion atlite/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from dask.diagnostics import ProgressBar
from numpy import pi
from scipy.sparse import csr_matrix
from tqdm import tqdm

from atlite import csp as cspm
from atlite import hydro as hydrom
Expand All @@ -34,6 +35,7 @@
from atlite.resource import (
get_cspinstallationconfig,
get_solarpanelconfig,
get_waveenergyconverter,
get_windturbineconfig,
windturbine_smooth,
)
Expand Down Expand Up @@ -1098,7 +1100,103 @@ def wind(
)


# irradiation
def convert_wave(
ds: xr.Dataset,
converter: dict,
time_chunk_size: int = 100,
) -> xr.DataArray:
"""
Convert wave height and peak period data into normalized WEC power output.

This function matches each combination of significant wave height and peak period
in the dataset to a corresponding power output from the WEC power matrix.
The resulting power output is normalized by the maximum possible output (capacity)
to obtain the specific generation profile.

Parameters
----------
ds : xarray.Dataset
Input dataset (cutout) containing two variables:
wave_height: significant wave height (m)
wave_period: peak wave period (s)
converter : dict
Dictionary defining the WEC characteristics, including:
Power_Matrix: a power matrix dictionary stored in ``resources/wecgenerator``.
time_chunk_size : int
Size of time chunks for processing large datasets, to limit memory spikes.
Default is 100.

Returns
-------
xarray.DataArray
DataArray of specific power generation values (normalized power output).

Notes
-----
A progress message is printed every one million cases to track computation.
"""
power_matrix = (
pd.DataFrame
.from_dict(converter["Power_Matrix"])
.stack()
.rename_axis(index=["wave_height", "wave_period"])
.where(lambda x: x > 0)
.dropna()
.to_xarray()
)

results = []
steps = np.arange(0, len(ds.time), step=100)

for step in tqdm(
steps, desc="Processing wave data chunks", total=len(steps), unit="time chunk"
):
ds_ = ds.isel(time=slice(step, step + time_chunk_size))
cf = power_matrix.interp(
{"wave_height": ds_.wave_height, "wave_period": ds_.wave_period},
method="nearest",
)
results.append(cf)

da = xr.concat(results, dim="time")
da.attrs["units"] = "kWh/kWp"
da = da.rename("specific generation")

return da.fillna(0)


def wave(cutout, converter, **params):
"""
Compute wave energy generation time series for a given cutout and Wave Energy Converter (WEC) type.

Parameters
----------
cutout : atlite.Cutout
Atlite cutout object containing wave-related data (e.g., `wave_height`, `wave_period`).
wec_type : str, pathlib.Path, or dict
WEC configuration describing the device's power characteristics.

Returns
-------
xarray.DataArray
Time series of normalized wave power generation for the entire cutout area, with units of "kWh/kWp".
The dimensions and resolution follow the input cutout and aggregation parameters.

References
----------
[1] Lavidas G., Mezilis L., Alday M., Baki H., Tan J., Jain A., Engelfried T. and Raghavan V.,
Marine renewables in Energy Systems: Impacts of climate data, generators, energy policies,
opportunities, and untapped potential for 100% decarbonised systems. Energy, Volume 336, 2025,
138359, ISSN 0360-5442, https://doi.org/10.1016/j.energy.2025.138359.
"""
if isinstance(converter, str | Path):
converter = get_waveenergyconverter(converter)

return cutout.convert_and_aggregate(
convert_func=convert_wave, converter=converter, **params
)


def convert_irradiation(
ds: xr.Dataset,
orientation: Callable,
Expand Down
3 changes: 3 additions & 0 deletions atlite/cutout.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
soil_temperature,
solar_thermal,
temperature,
wave,
wind,
)
from atlite.data import available_features, cutout_prepare
Expand Down Expand Up @@ -706,6 +707,8 @@ def layout_from_capacity_list(self, data, col="Capacity"):

wind = wind

wave = wave

irradiation = irradiation

pv = pv
Expand Down
3 changes: 2 additions & 1 deletion atlite/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

"""atlite datasets."""

from atlite.datasets import era5, era5_edh, gebco, glofas, sarah
from atlite.datasets import era5, era5_edh, gebco, glofas, mrel_wave, sarah

modules = {
"era5": era5,
"era5-edh": era5_edh,
"gebco": gebco,
"glofas": glofas,
"sarah": sarah,
"mrel_wave": mrel_wave,
}
88 changes: 88 additions & 0 deletions atlite/datasets/era5.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def nullcontext(): # noqa: D103
],
"temperature": ["temperature", "soil temperature", "dewpoint temperature"],
"runoff": ["runoff"],
"wave": ["wave_height", "wave_period"],
}

static_features = {"height"}
Expand Down Expand Up @@ -384,6 +385,93 @@ def sanitize_runoff(ds: xr.Dataset) -> xr.Dataset:
return ds


def get_data_wave_height(retrieval_params):
"""
Retrieve and compute wave height variable from ERA5.

Parameters
----------
retrieval_params
CDS API retrieval parameters including area, time, and format.

Returns
-------
xr.Dataset
Dataset with variable: wave_height.
"""
ds = retrieve_data(
variable=[
"significant_height_of_combined_wind_waves_and_swell",
],
**retrieval_params,
)
ds = _rename_and_clean_coords(ds)

return ds.rename({"swh": "wave_height"})


def sanitize_wave_height(ds):
"""
Clip wave height values to 0.0.

Parameters
----------
ds : xr.Dataset
Dataset containing the 'wave_height' variable.

Returns
-------
xr.Dataset
Dataset with negative 'wave_height' values clipped to zero.
"""
ds["wave_height"] = ds["wave_height"].clip(min=0.0)

return ds


def get_data_wave_period(retrieval_params):
"""
Retrieve and compute wave period variable from ERA5.

Parameters
----------
retrieval_params
CDS API retrieval parameters including area, time, and format.

Returns
-------
xr.Dataset
Dataset with variable: wave_period.
"""
ds = retrieve_data(
variable=["peak_wave_period"],
**retrieval_params,
)

ds = _rename_and_clean_coords(ds)

return ds.rename({"pp1d": "wave_period"})


def sanitize_wave_period(ds):
"""
Clip wave period values to 0.0.

Parameters
----------
ds : xr.Dataset
Dataset containing the 'wave_period' variable.

Returns
-------
xr.Dataset
Dataset with negative 'wave_period' values clipped to zero.
"""
ds["wave_period"] = ds["wave_period"].clip(min=0.0)

return ds


def get_data_height(retrieval_params: dict[str, Any]) -> xr.Dataset:
"""
Retrieve geopotential and convert to terrain height.
Expand Down
Loading