Skip to content

build_renewable_profiles crashes for offshore buses missing from clustered regions #2112

@MarcoAnarmo

Description

@MarcoAnarmo

Version Checks (indicate both or one)

  • I have confirmed this bug exists on the lastest release of PyPSA-Eur.

  • I have confirmed this bug exists on the current master branch of PyPSA-Eur.

Issue Description

When building offshore renewable profiles, some buses present in the availability matrix don't exist in the clustered offshore regions (e.g. BE0 26, GB2 132, IE3 43). This happens because certain countries' offshore zones get dropped during clustering. The script crashes in two places:

Location 1. When indexing regions with the availability matrix buses.
Location 2. When computing average distances.

This affects scripts/build_renewable_profiles.py.

Reproducible Example

1. Include countries whose offshore regions may get dropped during clustering (e.g. GB, IE) in the config:


countries:
  - GB
  - IE
  - BE
  - NL
  # ...


2. Run the renewable profiles rule for any offwind technology:


snakemake solve_elec_networks --configfile ./config/config.yaml --cores 14


3. This produces the following error traceback:

Location 1:


File "build_renewable_profiles.py", line 163, in <module>
    regions = regions.loc[offshore_regions]
KeyError: "['BE0 26', 'GB2 132', 'IE3 43', ...] not in index"


Location 2:


File "build_renewable_profiles.py", line 305, in <module>
    distances = co.distance(regions[bus]).div(1e3)
KeyError: 'BE0 26'

Expected Behavior

Proposed fix — Location 1

Filter the availability matrix bus names to only those present in the clustered regions using np.intersect1d:

# Before
offshore_regions = availability.coords["bus"].values
regions = regions.loc[offshore_regions]

# After
offshore_regions = availability.coords["bus"].values
offshore_regions = np.intersect1d(offshore_regions, regions.index)
regions = regions.loc[offshore_regions]

Proposed fix — Location 2

Skip buses that are not in regions.index during the average distance loop:

# Before
for bus, bin in bus_bins:
    row = layoutmatrix.sel(bus=bus, bin=bin).data
    nz_b = row != 0
    row = row[nz_b]
    co = coords[nz_b]
    distances = co.distance(regions[bus]).div(1e3)
    average_distance.append((distances * (row / row.sum())).sum())

# After
for bus, bin in bus_bins:
    if bus not in regions.index:
        average_distance.append(0.0)
        continue
    row = layoutmatrix.sel(bus=bus, bin=bin).data
    nz_b = row != 0
    row = row[nz_b]
    co = coords[nz_b]
    distances = co.distance(regions[bus]).div(1e3)
    average_distance.append((distances * (row / row.sum())).sum())

Installed Versions

Details Replace this line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions