Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions doc/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

* Migrate the Sphinx/RST-based documentation to MkDocs/Markdown, as a follow-up to the [upstream migration](https://github.com/PyPSA/pypsa-eur/pull/2162) ([754](https://github.com/open-energy-transition/open-tyndp/pull/754)).

* Improve docstring formatting and add missing type hints (https://github.com/open-energy-transition/open-tyndp/pull/759).

**Developers Note**

* Change GitHub issue templates to comply with ISO security checks ([#714](https://github.com/open-energy-transition/open-tyndp/pull/714), [#730](https://github.com/open-energy-transition/open-tyndp/pull/730)).
Expand Down
67 changes: 58 additions & 9 deletions scripts/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,11 +1143,11 @@ def extract_grid_data_tyndp(
Parameters
----------
links : pd.DataFrame
DataFrame with raw links to extract grid information from
DataFrame with raw links to extract grid information from.
replace_dict : dict
Dictionary with region names to replace
Dictionary with region names to replace.
expand_from_index : bool
Whether to expand the bus0 and bus1 from index or directly use the columns
Whether to expand the bus0 and bus1 from index or directly use the columns.
idx_prefix : str, optional
Prefix to prepend to generated indices.
idx_connector : str, optional
Expand All @@ -1160,7 +1160,7 @@ def extract_grid_data_tyndp(
Returns
-------
pd.DataFrame
DataFrame with extracted grid data information with nominal capacity in input unit, bus0 and bus1
DataFrame with extracted grid data information with nominal capacity in input unit, bus0 and bus1.
"""

if expand_from_index:
Expand Down Expand Up @@ -1231,7 +1231,7 @@ def safe_pyear(
Returns
-------
year_new : int
Safe pyear adjusted for available years
Safe pyear adjusted for available years.
"""

if not available_years:
Expand Down Expand Up @@ -1341,6 +1341,16 @@ def get_version(hash_len: int = 9) -> str:
- If HEAD is exactly at a tag: returns the tag name (e.g., "v1.2.3")
- If HEAD is beyond a tag: returns "tag+g{hash}" (e.g., "v1.2.3+g1a2b3c4d")
- If no tags found: returns just the commit hash (e.g., "1a2b3c4d5")

Parameters
----------
hash_len : int, optional
Number of characters to use from the commit hash. Defaults to 9.

Returns
-------
str
Version string derived from the git repository state.
"""
try:
repo = git.Repo(search_parent_directories=True)
Expand Down Expand Up @@ -1434,7 +1444,21 @@ def convert_units(


def check_cyear(cyear: int, scenario: str) -> int:
"""Check if the climatic year is valid for the given scenario."""
"""
Check if the climatic year is valid for the given scenario.

Parameters
----------
cyear : int
Climatic year to validate.
scenario : str
TYNDP scenario name.

Returns
-------
int
Valid climatic year, falling back to 2009 if the input is not available.
"""

valid_years = {
"NT": [1995, 2008, 2009],
Expand Down Expand Up @@ -1604,9 +1628,21 @@ def interpolate_demand(
return result


def find_free_port(start_port=8050, max_attempts=50):
def find_free_port(start_port: int = 8050, max_attempts: int = 50) -> int:
"""
Find the first available port starting from start_port.

Parameters
----------
start_port : int, optional
Port number to begin scanning from. Defaults to 8050.
max_attempts : int, optional
Maximum number of ports to check before raising an error. Defaults to 50.

Returns
-------
int
First available port number in the scanned range.
"""
for port in range(start_port, start_port + max_attempts):
try:
Expand Down Expand Up @@ -1703,8 +1739,21 @@ def align_demand_to_snapshots(
demand: pd.DataFrame, snapshots: pd.DatetimeIndex, format: str = None
) -> pd.DataFrame:
"""
Convert demand index to DatetimeIndex, adjust year to match snapshots,
and reindex to snapshots.
Convert demand index to DatetimeIndex, adjust year to match snapshots, and reindex to snapshots.

Parameters
----------
demand : pd.DataFrame
Demand time series with a datetime-compatible index.
snapshots : pd.DatetimeIndex
Target snapshot index to align demand to.
format : str, optional
Datetime format string for parsing the demand index. Defaults to None.

Returns
-------
pd.DataFrame
Demand data reindexed to the provided snapshots.
"""

demand.index = pd.to_datetime(demand.index, format=format)
Expand Down
26 changes: 13 additions & 13 deletions scripts/add_brownfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ def add_brownfield(
Parameters
----------
n : pypsa.Network
Network to add brownfield to
Network to add brownfield to.
n_p : pypsa.Network
Previous network to get brownfield from
Previous network to get brownfield from.
year : int
Planning year
h2_retrofit : bool
Whether to allow hydrogen pipeline retrofitting
h2_retrofit_capacity_per_ch4 : float
Ratio of hydrogen to methane capacity for pipeline retrofitting
capacity_threshold : float
Threshold for removing assets with low capacity
offshore_hubs_tyndp : bool
Whether to enable offshore hubs
h2_topology_tyndp : bool
Whether to enable TYNDP Hydrogen topology
Planning year.
h2_retrofit : bool, optional
Whether to allow hydrogen pipeline retrofitting. Default is False.
h2_retrofit_capacity_per_ch4 : float, optional
Ratio of hydrogen to methane capacity for pipeline retrofitting. Default is None.
capacity_threshold : float, optional
Threshold for removing assets with low capacity. Default is None.
offshore_hubs_tyndp : bool, optional
Whether to enable offshore hubs. Default is False.
h2_topology_tyndp : bool, optional
Whether to enable TYNDP Hydrogen topology. Default is False.
carriers_tyndp : list[str]
List of TYNDP carriers included in the model.
"""
Expand Down
2 changes: 1 addition & 1 deletion scripts/build_snapshot_weightings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# SPDX-License-Identifier: MIT
"""
Defines the time aggregation, known as ``snapshot_weightings``, to be used for sector-coupled network.
Defines the time aggregation, known as `snapshot_weightings`, to be used for sector-coupled network.

Description
-----------
Expand Down
42 changes: 30 additions & 12 deletions scripts/build_tyndp_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,20 @@
IBFI_COORD = (63.0, 25.0)


def format_bz_names(s: str):
def format_bz_names(s: str) -> str:
"""
Standardize bidding zone name formats to Open-TYNDP conventions.

Parameters
----------
s : str
Raw bidding zone name string to format.

Returns
-------
str
Formatted bidding zone name with standardized region codes.
"""
s = s.replace("FR-C", "FR15").replace("UK-N", "UKNI").replace("UK", "GB")
return s

Expand All @@ -100,7 +113,7 @@ def extract_shape_by_bbox(

Parameters
----------
gdf : GeoDataFrame
gdf : gpd.GeoDataFrame
GeoDataFrame containing country geometries.
country : str
The country code or name to filter.
Expand All @@ -117,7 +130,7 @@ def extract_shape_by_bbox(

Returns
-------
GeoDataFrame
gpd.GeoDataFrame
Updated GeoDataFrame with the extracted shape separated.
"""
country_gdf = gdf.explode().query(f"country == '{country}'").reset_index(drop=True)
Expand Down Expand Up @@ -226,9 +239,9 @@ def build_buses(
Path to bidding zone shape file.
countries : list[str]
List of countries to consider.
bidding_shapes : GeoDataFrame
bidding_shapes : gpd.GeoDataFrame
A GeoDataFrame including bidding zone geometry, representative point and id.
country_shapes : GeoDataFrame
country_shapes : gpd.GeoDataFrame
A GeoDataFrame including country geometry and representative point.
geo_crs : CRS, optional
Comment thread
tgilon marked this conversation as resolved.
Outdated
Coordinate reference system for geographic calculations. Defaults to GEO_CRS.
Expand Down Expand Up @@ -329,14 +342,19 @@ def add_links_missing_attributes(

Parameters
----------
- links (pd.DataFrame): DataFrame of links with 'bus0' and 'bus1' columns.
- buses (gpd.GeoDataFrame): GeoDataFrame of electrical buses including country and coordinates.
- geo_crs (CRS, optional): Coordinate reference system for geographic calculations. Defaults to GEO_CRS.
- distance_crs (CRS, optional): Coordinate reference system for distance calculations. Defaults to DISTANCE_CRS.
links : pd.DataFrame
DataFrame of links with bus0 and bus1 columns.
buses : gpd.GeoDataFrame
GeoDataFrame of electrical buses including country and coordinates.
geo_crs : str, optional
Comment thread
AndreasHD11 marked this conversation as resolved.
Coordinate reference system for geographic calculations. Defaults to GEO_CRS.
distance_crs : str, optional
Coordinate reference system for distance calculations. Defaults to DISTANCE_CRS.

Returns
-------
- links: DataFrame with added geometry columns.
gpd.GeoDataFrame
GeoDataFrame of links with added geometry columns.
"""
links = links.merge(
buses["geometry"], how="left", left_on="bus0", right_index=True
Expand Down Expand Up @@ -418,7 +436,7 @@ def build_links(
----------
grid_fn : str | Path
Path to bidding zone shape file.
buses : GeoDataFrame
buses : gpd.GeoDataFrame
A GeoDataFrame of electrical buses including country and coordinates.
geo_crs : CRS, optional
Coordinate reference system for geographic calculations. Defaults to GEO_CRS.
Expand All @@ -427,7 +445,7 @@ def build_links(

Returns
-------
GeoDataFrame
gpd.GeoDataFrame
A GeoDataFrame including NTC from the reference grid.
"""
links = pd.read_excel(grid_fn)
Expand Down
15 changes: 10 additions & 5 deletions scripts/cba/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def get_link_attrs(project: pd.Series, costs: pd.DataFrame) -> dict:
Return length, underwater_fraction, and capital_cost for a new DC link.

The capital_cost is computed using the same per-km formula as
``add_electricity.py`` to ensure consistency with existing network
`add_electricity.py` to ensure consistency with existing network
links:

``capital_cost = length * ((1 - uf) * overhead + uf * submarine) + inverter``
`capital_cost = length * ((1 - uf) * overhead + uf * submarine) + inverter`

Parameters
----------
Expand All @@ -24,8 +24,13 @@ def get_link_attrs(project: pd.Series, costs: pd.DataFrame) -> dict:
underwater_fraction.
costs : pd.DataFrame
Technology costs table (indexed by technology name) with a
``capital_cost`` column containing annualized EUR/MW or EUR/MW/km
`capital_cost` column containing annualized EUR/MW or EUR/MW/km
values.

Returns
-------
dict
Dictionary with keys length, underwater_fraction, and capital_cost.
"""
length = float(project.get("length_km", 0))
uf = float(project.get("underwater_fraction", 0))
Expand Down Expand Up @@ -57,9 +62,9 @@ def filter_projects_by_specs(
Parameters
----------
project_list : list[str]
List of all available project names to filter from
List of all available project names to filter from.
spec_list : list[str], str, or None
List of specifications, a single specification string, or None to return all projects
List of specifications, a single specification string, or None to return all projects.

Returns
-------
Expand Down
27 changes: 18 additions & 9 deletions scripts/cba/average_indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,27 @@
}


def average_indicators_csv(input_files, output_file, planning_horizon):
def average_indicators_csv(
input_files: list[str], output_file: str, planning_horizon: int | str
) -> None:
"""
Concatenate multiple CSV files into one using the csv module.

Args:
input_files: List of paths to input CSV files
output_file: Path to output CSV file

The function:
1. Reads the header from the first file
2. Writes all rows from all files to the output
3. Ensures all files have the same header structure
Reads the header from the first file, writes all rows from all files to the
output, and ensures all files have the same header structure.

Parameters
----------
input_files : list[str]
List of paths to input CSV files.
output_file : str
Path to output CSV file.
planning_horizon : int or str
Planning horizon year used for climatic year weighting.

Returns
-------
None
"""
if not input_files:
logger.warning("No input files provided")
Expand Down
14 changes: 7 additions & 7 deletions scripts/cba/build_msv_snapshot_weightings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
Generate snapshot weightings for MSV extraction temporal aggregation.

Produces a CSV with resampled snapshot weightings at the configured
MSV extraction resolution. Follows the same logic as ``time_aggregation.py``
MSV extraction resolution. Follows the same logic as `time_aggregation.py`
for the supported resolution formats:

- ``false``: No aggregation, outputs empty CSV
- ``"Nsn"``: Representative snapshots (e.g., "2sn"), outputs empty CSV
(handled directly by ``set_temporal_aggregation``)
- ``"Nh"``: Hourly resampling (e.g., "24H", "48H"), outputs resampled weightings
- `false`: No aggregation, outputs empty CSV
- `"Nsn"`: Representative snapshots (e.g., "2sn"), outputs empty CSV
(handled directly by `set_temporal_aggregation`)
- `"Nh"`: Hourly resampling (e.g., "24H", "48H"), outputs resampled weightings

**Inputs**

- ``resources/cba/networks/reference_{planning_horizons}.nc``: Reference network
- `resources/cba/networks/reference_{planning_horizons}.nc`: Reference network

**Outputs**

- ``resources/cba/msv_snapshot_weightings_{planning_horizons}.csv``: Snapshot weightings
- `resources/cba/msv_snapshot_weightings_{planning_horizons}.csv`: Snapshot weightings
"""

import logging
Expand Down
Loading