Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d2576ed
feat: introduce pipeline for hydro inflow data
daniel-rdt Jul 21, 2025
5edeafb
feat: infer resolution of input data for each technology and fix unit…
daniel-rdt Jul 24, 2025
277f0e2
feat: add more generalised retrieve for additional tyndp datasets and…
daniel-rdt Jul 25, 2025
d37199f
Merge branch 'master' into feat/74-hydro-inflows
daniel-rdt Jul 31, 2025
cfcd6f6
feat: introduce safe_pyear helper function
daniel-rdt Jul 30, 2025
9bf086b
feat: add verbose option to safe_pyear helper function
daniel-rdt Jul 31, 2025
4a2a6d0
feat: add config section with switch, techs and available years
daniel-rdt Jul 31, 2025
9299cec
feat: build hydro profile file with dimensions bus, time, year, hydro…
daniel-rdt Aug 1, 2025
0165421
feat: add hydro to tyndp test config
daniel-rdt Aug 1, 2025
2cec738
fix: disable tyndp_hydro_profiles in default config
daniel-rdt Aug 1, 2025
bb49919
fix: differentiate hydro profiles in prepare_sector_network.py
daniel-rdt Aug 1, 2025
f0427b8
doc: document new config option
daniel-rdt Aug 1, 2025
0ceee6e
doc: add release note
daniel-rdt Aug 1, 2025
b9e6e00
Resolve merge conflicts
daniel-rdt Aug 11, 2025
9fbf3b2
ci: add explicit ruleorder for tyndp hydro rules
daniel-rdt Aug 12, 2025
9faaccc
doc: add documentation for retrieve_tyndp_hydro_inflows rule
daniel-rdt Aug 12, 2025
9abc99d
Apply suggestions from code review
daniel-rdt Aug 14, 2025
45d6b3b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 14, 2025
c6259e1
refactor: change the order of config parameters for consistency
daniel-rdt Aug 14, 2025
465be65
refactor: rename profile_hydro_tyndp to profile_pemmdb_hydro
daniel-rdt Aug 14, 2025
fb30763
apply more suggestions from code review
daniel-rdt Aug 14, 2025
01b079a
doc: add autodoc for missing hydro profile and pecd rules
daniel-rdt Aug 14, 2025
a752402
refactor: move static variable outside of function
daniel-rdt Aug 14, 2025
d3b0f8b
refactor: remove redundant fill value and clean up GB and UK renaming
daniel-rdt Aug 14, 2025
1baf259
feat: add source parameter for logging of retrieve_additional_tyndp_data
daniel-rdt Aug 14, 2025
0e07ba7
feat: improve input_data_hydro_tyndp formulation
daniel-rdt Aug 15, 2025
79ac928
feat: improve data cleaning
daniel-rdt Aug 15, 2025
f2ed432
Merge branch 'master' into feat/74-hydro-inflows
daniel-rdt Sep 1, 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
13 changes: 13 additions & 0 deletions config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ electricity:
- offwind-h2-fb-oh
- offwind-h2-fl-oh

tyndp_hydro_profiles:
enable: false
technologies:
- Run of River
- Pondage
- Reservoir
- PS Open
- PS Closed
available_years:
- 2030
- 2040
- 2050
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated

estimate_renewable_capacities:
enable: true
from_gem: true
Expand Down
17 changes: 15 additions & 2 deletions config/config.tyndp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ electricity:
base_network: tyndp

# TODO: remove redundant onwind and solar from renewable_carriers list once technologies are included as tyndp_renewable_carriers from PEMMDB data
renewable_carriers: [onwind, solar, solar-hsat, hydro]
tyndp_renewable_carriers: [onwind, solar-pv-utility, solar-pv-rooftop, offwind-ac-fb-r, offwind-ac-fl-r, offwind-dc-fb-r, offwind-dc-fl-r, offwind-dc-fb-oh, offwind-dc-fl-oh, offwind-h2-fb-oh, offwind-h2-fl-oh]
renewable_carriers: [solar, solar-hsat, onwind]
tyndp_renewable_carriers: [hydro, onwind, solar-pv-utility, solar-pv-rooftop, offwind-ac-fb-r, offwind-ac-fl-r, offwind-dc-fb-r, offwind-dc-fl-r, offwind-dc-fb-oh, offwind-dc-fl-oh, offwind-h2-fb-oh, offwind-h2-fl-oh]

pecd_renewable_profiles:
enable: true
Expand All @@ -66,6 +66,19 @@ electricity:
Wind_Onshore:
- onwind

tyndp_hydro_profiles:
enable: true
technologies:
- Run of River
- Pondage
- Reservoir
- PS Open
- PS Closed
available_years:
- 2030
- 2040
- 2050

estimate_renewable_capacities:
# NOTE: technologies that are covered by TYNDP renewable carriers need to be removed from estimation
technologies:
Expand Down
17 changes: 15 additions & 2 deletions config/test/config.tyndp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ electricity:
Link: [H2 pipeline]

# TODO: remove redundant onwind and solar from renewable_carriers list once technologies are included as tyndp_renewable_carriers from PEMMDB data
renewable_carriers: [onwind, solar, solar-hsat]
tyndp_renewable_carriers: [onwind, solar-pv-utility, solar-pv-rooftop, offwind-ac-fb-r, offwind-ac-fl-r, offwind-dc-fb-r, offwind-dc-fl-r, offwind-dc-fb-oh, offwind-dc-fl-oh, offwind-h2-fb-oh, offwind-h2-fl-oh]
renewable_carriers: [solar, solar-hsat, onwind]
tyndp_renewable_carriers: [hydro, onwind, solar-pv-utility, solar-pv-rooftop, offwind-ac-fb-r, offwind-ac-fl-r, offwind-dc-fb-r, offwind-dc-fl-r, offwind-dc-fb-oh, offwind-dc-fl-oh, offwind-h2-fb-oh, offwind-h2-fl-oh]

pecd_renewable_profiles:
enable: true
Expand All @@ -78,6 +78,19 @@ electricity:
Wind_Onshore:
- onwind

tyndp_hydro_profiles:
enable: true
technologies:
- Run of River
- Pondage
- Reservoir
- PS Open
- PS Closed
available_years:
- 2030
- 2040
- 2050

estimate_renewable_capacities:
# NOTE: technologies that are covered by TYNDP renewable carriers need to be removed from estimation
technologies:
Expand Down
4 changes: 4 additions & 0 deletions doc/configtables/electricity.csv
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ pecd_renewable_profiles,,,
-- technologies,,,
-- -- {pecd_tech},--,str,The PECD tech whose PECD profile is used. These PECD tech and their profiles are mapped to ``tyndp_renewable_carriers``.
-- -- -- {tyndp_renewable_carriers},--,str,The `tyndp_renewable_carriers` for which the PECD profiles must be used. All `tyndp_renewable_carriers` must be mapped to a PECD profile. Non-TYNDP renewable carriers use the default renewable profiles.
tyndp_hydro_profiles,,,
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
-- enable,,bool,Activate PEMMDB hyddro inflow profiles from 2024 TYNDP instead of default hydro profiles.
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
-- available_years,--,list,"List of years for which PEMMDB hydro inflows data is available."
-- technologies,--,list,The hydro technology for which PEMMDB hydro inflows data shall be prepared. Technologies can be any of {Run of River, Pondage, Reservoir, PS Open, PS Closed}.
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
estimate_renewable_capacities,,,
-- enable,,bool,Activate routine to estimate renewable capacities in rule :mod:`add_electricity`. This option should not be used in combination with pathway planning ``foresight: myopic`` or ``foresight: perfect`` as renewable capacities are added differently in :mod:`add_existing_baseyear`.
-- from_gem,--,bool,Add renewable capacities from `Global Energy Monitor's Global Solar Power Tracker <https://globalenergymonitor.org/projects/global-solar-power-tracker/>`_ and `Global Energy Monitor's Global Wind Power Tracker <https://globalenergymonitor.org/projects/global-wind-power-tracker/>`_.
Expand Down
2 changes: 2 additions & 0 deletions doc/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Upcoming Open-TYNDP Release

* Add complete compatibility for processing and preparation of PECD v3.1 renewable profiles (Solar PV rooftop, Solar PV utility, Onshore Wind, Offshore Wind, Solar CSP) (https://github.com/open-energy-transition/open-tyndp/pull/71). These profiles are used for the TYNDP 2024 and replace the default ERA5- and SARAH3-based profiles processed with Atlite. This implementation serves to facilitate a sub-workflow for creation of the renewable profiles, but does not yet attach them to any technologies.

* Introduce processing of PEMMDB hydro inflows data for different hydro technologies (Run of River, Pondage, Reservoir, PS Open, PS Closed) from 2024 TYNDP into hydro inflow profiles (https://github.com/open-energy-transition/open-tyndp/pull/77). This implementation serves to facilitate a sub-workflow for creation of the hydro inflow profiles, but does not yet attach them to any hydro technologies.
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated


Upcoming PyPSA-Eur Release
================
Expand Down
7 changes: 6 additions & 1 deletion doc/retrieve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,9 @@ None.
Rule ``retrieve_tyndp_pecd_data``
====================================

.. automodule:: retrieve_tyndp_pecd_data
.. automodule:: retrieve_additional_tyndp_data

Rule ``retrieve_tyndp_hydro_inflows``
Comment thread
daniel-rdt marked this conversation as resolved.
====================================

.. automodule:: retrieve_additional_tyndp_data
73 changes: 73 additions & 0 deletions rules/build_electricity.smk
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,79 @@ rule build_hydro_profile:
"../scripts/build_hydro_profile.py"


rule clean_tyndp_hydro_inflows:
params:
snapshots=config_provider("snapshots"),
drop_leap_day=config_provider("enable", "drop_leap_day"),
input:
hydro_inflows_dir="data/tyndp_2024_bundle/Hydro Inflows",
onshore_buses=resources("busmap_base_s_all.csv"),
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
output:
hydro_inflows_tyndp=resources(
"hydro_inflows_tyndp_{tech}_{planning_horizons}.csv"
),
log:
logs("clean_tyndp_hydro_inflows_{tech}_{planning_horizons}.log"),
threads: 4
benchmark:
benchmarks("clean_tyndp_hydro_inflows_{tech}_{planning_horizons}")
conda:
"../envs/environment.yaml"
script:
"../scripts/clean_tyndp_hydro_inflows.py"


def input_data_hydro_tyndp(w):
return {
f"hydro_inflow_tyndp_{tech}_{pyear}": resources(
f"hydro_inflows_tyndp_{tech}_{str(pyear)}.csv"
)
for pyear in set(
[
safe_pyear(
year,
config_provider(
"electricity", "tyndp_hydro_profiles", "available_years"
)(w),
"PEMMDB hydro",
verbose=False,
)
for year in config_provider("scenario", "planning_horizons")(w)
]
)
for tech in config_provider(
"electricity", "tyndp_hydro_profiles", "technologies"
)(w)
}

Comment thread
daniel-rdt marked this conversation as resolved.

rule build_tyndp_hydro_profile:
params:
snapshots=config_provider("snapshots"),
drop_leap_day=config_provider("enable", "drop_leap_day"),
planning_horizons=config_provider("scenario", "planning_horizons"),
available_years=config_provider(
"electricity", "tyndp_hydro_profiles", "available_years"
),
technologies=config_provider(
"electricity", "tyndp_hydro_profiles", "technologies"
),
input:
unpack(input_data_hydro_tyndp),
output:
profile=resources("profile_hydro_tyndp.nc"),
log:
logs("build_tyndp_hydro_profile.log"),
benchmark:
benchmarks("build_tyndp_hydro_profile")
resources:
mem_mb=5000,
conda:
"../envs/environment.yaml"
script:
"../scripts/build_tyndp_hydro_profile.py"


rule build_line_rating:
params:
snapshots=config_provider("snapshots"),
Expand Down
5 changes: 5 additions & 0 deletions rules/build_sector.smk
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,11 @@ rule prepare_sector_network:
if config_provider("sector", "h2_topology_tyndp")(w)
else []
),
profile_hydro_tyndp=branch(
config_provider("electricity", "tyndp_hydro_profiles", "enable"),
resources("profile_hydro_tyndp.nc"),
[],
),
output:
resources(
"networks/base_s_{clusters}_{opts}_{sector_opts}_{planning_horizons}.nc"
Expand Down
17 changes: 16 additions & 1 deletion rules/retrieve.smk
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,30 @@ if config["enable"]["retrieve"]:
params:
# TODO Integrate into Zenodo tyndp data bundle
tyndp_bundle="data/tyndp_2024_bundle",
url="https://storage.googleapis.com/open-tyndp-data-store/PECD.zip",
output:
dir=directory("data/tyndp_2024_bundle/PECD"),
log:
"logs/retrieve_tyndp_pecd_data.log",
retries: 2
script:
"../scripts/retrieve_tyndp_pecd_data.py"
"../scripts/retrieve_additional_tyndp_data.py"

rule retrieve_tyndp_hydro_inflows:
params:
# TODO Integrate into Zenodo tyndp data bundle
tyndp_bundle="data/tyndp_2024_bundle",
url="https://storage.googleapis.com/open-tyndp-data-store/Hydro_Inflows.zip",
output:
dir=directory("data/tyndp_2024_bundle/Hydro Inflows"),
log:
"logs/retrieve_tyndp_hydro_inflows.log",
retries: 2
script:
"../scripts/retrieve_additional_tyndp_data.py"
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated

ruleorder: retrieve_tyndp_bundle > retrieve_tyndp_pecd_data > clean_pecd_data
ruleorder: retrieve_tyndp_bundle > retrieve_tyndp_hydro_inflows > clean_tyndp_hydro_inflows

rule retrieve_countries_centroids:
output:
Expand Down
83 changes: 83 additions & 0 deletions scripts/build_tyndp_hydro_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# SPDX-FileCopyrightText: Open Energy Transition gGmbH
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
#
# SPDX-License-Identifier: MIT
"""
Build hydroelectric inflow time-series for each country based on TYNDP hydro inflow data.
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated

Outputs
-------

- ``resources/profile_hydro_tyndp.nc``:

=================== ================ =========================================================
Field Dimensions Description
=================== ================ =========================================================
inflow bus, time, Inflow to the state of charge (in MW),
year, hydro_tech e.g. due to river inflow in hydro reservoir.
=================== ================ =========================================================
"""

import logging

import pandas as pd
import xarray as xr
from tqdm.contrib.itertools import product

from scripts._helpers import (
configure_logging,
get_snapshots,
safe_pyear,
set_scenario_config,
)

logger = logging.getLogger(__name__)

if __name__ == "__main__":
if "snakemake" not in globals():
from scripts._helpers import mock_snakemake

snakemake = mock_snakemake("build_tyndp_hydro_profile")
configure_logging(snakemake)
set_scenario_config(snakemake)

time = get_snapshots(snakemake.params.snapshots, snakemake.params.drop_leap_day)

years_in_time = pd.DatetimeIndex(time).year.unique()

technologies = snakemake.params.technologies
pyears = snakemake.params.planning_horizons

inflows = []

for year, technology in product(pyears, technologies):
logger.info(
f"Extracting hydro inflows for year {year} for technology {technology}..."
Comment thread
daniel-rdt marked this conversation as resolved.
Outdated
)
year_i = year
# falling back to latest available pyear if not in list of available years
year = safe_pyear(
int(year),
available_years=snakemake.params.available_years,
source="PEMMDB hydro inflow",
)

inflow = (
pd.read_csv(
snakemake.input[f"hydro_inflow_tyndp_{technology}_{year}"],
parse_dates=True,
index_col=0,
)
.rename_axis("time")
.reset_index()
.melt(id_vars=["time"], var_name="bus", value_name="profile")
.assign(year=year_i, hydro_tech=technology)
.set_index(["bus", "time", "year", "hydro_tech"])
.to_xarray()
)

inflows.append(inflow)

ds = xr.merge(inflows)
ds = ds.sel(time=time)

ds.to_netcdf(snakemake.output.profile)
Loading
Loading