Skip to content

Fix corine bool and offshore keyerror#2113

Open
MarcoAnarmo wants to merge 7 commits intoPyPSA:masterfrom
MarcoAnarmo:fix/corine-bool-and-offshore-keyerror
Open

Fix corine bool and offshore keyerror#2113
MarcoAnarmo wants to merge 7 commits intoPyPSA:masterfrom
MarcoAnarmo:fix/corine-bool-and-offshore-keyerror

Conversation

@MarcoAnarmo
Copy link
Copy Markdown

@MarcoAnarmo MarcoAnarmo commented Mar 4, 2026

Closes #2111 and #2112.

Changes proposed in this Pull Request

Fixes two detected bugs in the renewable availability/profiles pipeline when using offshore technologies with corine: false and non-standard country lists:

  • determine_availability_matrix _MD_UA.py: Convert corine to an empty dict when set to false, preventing TypeError on "key" in corine checks.
  • build_renewable_profiles.py: Filter offshore buses against clustered regions index to avoid KeyError for buses dropped during clustering.

Used config file: config.osm_eem.yaml

Checklist

  • I tested my contribution locally and it works as intended.
  • Code and workflow changes are sufficiently documented.
  • Changed dependencies are added to pixi.toml (using pixi add <dependency-name>).
  • Changes in configuration options are added in config/config.default.yaml.
  • Changes in configuration options are documented in doc/configtables/*.csv.
  • For new data sources or versions, these instructions have been followed.
  • A release note doc/release_notes.rst is added.

When corine is set to false for offshore technologies, convert it to an empty dict so downstream 'key in corine' checks are skipped.

Fixes PyPSA#2111
Filter availability matrix buses against clustered regions index to avoid KeyError when countries' offshore zones are dropped.

Fixes PyPSA#2112
Copilot AI review requested due to automatic review settings March 4, 2026 12:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes two crash scenarios in the renewable availability/profiles pipeline when running offshore technologies with corine: false and/or country lists that lead to offshore regions being dropped during clustering.

Changes:

  • Guard corine config parsing in determine_availability_matrix_MD_UA.py so non-dict values (e.g. false) don’t break "key" in corine checks.
  • Filter offshore region indices against available clustered offshore regions in build_renewable_profiles.py.
  • Add a fallback in average-distance calculation to avoid KeyError when a bus is missing from regions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
scripts/determine_availability_matrix_MD_UA.py Adds a type guard to treat non-dict corine config values as “disabled” instead of crashing.
scripts/build_renewable_profiles.py Avoids KeyError for missing offshore buses by intersecting indices and skipping missing buses in distance calculation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

if snakemake.wildcards.technology.startswith("offwind"):
# for offshore regions, the shortest distance to the shoreline is used
offshore_regions = availability.coords["bus"].values
offshore_regions = np.intersect1d(offshore_regions, regions.index)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtering offshore_regions only when selecting regions leaves availability (and later resource_regions/class_masks) still containing buses that were dropped during clustering. This can produce profiles/potentials for buses that have no corresponding offshore distance geometry and makes outputs inconsistent (e.g. class_regions written only for the filtered bus set). Consider subsetting availability to the same offshore_regions intersection here (and similarly filter resource_regions after loading) so all downstream computations operate on a consistent bus index.

Suggested change
offshore_regions = np.intersect1d(offshore_regions, regions.index)
offshore_regions = np.intersect1d(offshore_regions, regions.index)
# align availability with the filtered offshore regions to keep a consistent bus index
availability = availability.sel(bus=offshore_regions)

Copilot uses AI. Check for mistakes.
Comment on lines 297 to +299
for bus, bin in bus_bins:
if bus not in regions.index:
average_distance.append(0.0)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appending 0.0 for buses missing from regions.index silently produces a plausible-looking distance and can mask data issues (and leave inconsistent outputs if those buses still have nonzero potential). Prefer to ensure those buses are removed upstream (e.g. by subsetting availability/class_masks to the regions bus set), or use NaN plus a clear warning/error so downstream consumers don’t interpret missing geometry as zero distance.

Suggested change
for bus, bin in bus_bins:
if bus not in regions.index:
average_distance.append(0.0)
# Identify buses present in the layout but missing geometry in regions
missing_buses = {bus for bus, _ in bus_bins} - set(regions.index)
if missing_buses:
logger.warning(
"Average distance could not be computed for %d bus(es) missing from "
"`regions.index`: %s. Distances for these buses will be set to NaN.",
len(missing_buses),
", ".join(sorted(map(str, missing_buses))),
)
for bus, bin in bus_bins:
if bus not in regions.index:
# Mark missing geometry explicitly instead of assuming zero distance
average_distance.append(np.nan)

Copilot uses AI. Check for mistakes.
MarcoAnarmo and others added 5 commits March 19, 2026 13:48
When clustering.simplify_network.to_380 is set to false, skip simplify_network_to_380() so that original voltage levels and transformers are preserved in the simplified network.
Add v_nom to custom_line_groupers so lines at different voltage levels are not merged. Pass with_country=True to cluster_regions so the output region shapefiles retain a country column for downstream scripts.
Use the 'country' column (when available) instead of slicing the first two characters of the bus name. Also subset sjoin to geometry-only to avoid extra columns and deduplicate plants in overlapping regions.
Write an empty availability matrix and exit early when no valid region geometries exist. Guard WDPA polygon/point reads behind geometry checks to prevent errors on empty GeoDataFrames.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

determine_availability_matrix_MD_UA crashes when corine: false

2 participants