PyPSA / PyPSA/atlite

Discussion: API for per-cell / per-point capacity factor extraction

Open
#485 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
402
Forks
134
PR merge metrics
No merged PRs in 30d

Description

Detailed Description

The convert_and_aggregate function currently supports per-cell extraction via capacity_factor_timeseries=True (without matrix/shapes/layout), but there is no higher-level convenience API for extracting profiles at specific point locations. This issue discusses how to best abstract that workflow.

@FabianHofmann suggested considering an accessor-based pattern:

cutout.pv.profiles_at_points(...)
cutout.wind.profiles_at_points(...)

Other possible approaches include:

  1. Accessor pattern (above) — clean namespace, discoverable, extensible
  2. Method on Cutoutcutout.profiles_at_points(locations, turbine=...) — simpler but mixes concerns
  3. Enhanced keyword on existing methodscutout.wind(turbine=..., points=locations) — minimal API surface but overloads wind()/pv()

Context

This is common in power system modeling where each bus/substation needs location-specific renewable capacity factors. The current workaround is either:

  • Creating per-pixel Cutout objects (very slow, ~50x overhead)
  • Using capacity_factor_timeseries=True on a multi-cell cutout and extracting with .sel(x=lon, y=lat, method="nearest") (works, but undocumented until #481)
  • Calling internal convert_wind/convert_pv directly (not public API)

See #480 for the full performance comparison and use case description.

Possible Implementation

An accessor-based design could look like:

@xr.register_dataset_accessor("wind")
class WindAccessor:
    def profiles_at_points(self, locations, turbine, **kwargs):
        """Extract wind capacity factor time series at specific (x, y) points."""
        cf = self._cutout.wind(turbine=turbine, capacity_factor_timeseries=True, **kwargs)
        return cf.sel(x=locations.x, y=locations.y, method="nearest")

Key design questions:

  • Should this return an xr.DataArray (with location coords) or a pd.DataFrame (with named columns)?
  • How should it handle locations that map to the same grid cell (deduplicate computation)?
  • Should it support mixed resources (wind + solar) in a single call?

Happy to contribute an implementation once there's agreement on the API direction.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the convert_and_aggregate function and the internal convert_wind and convert_pv entry points, then compare the existing capacity_factor_timeseries workflow described in the issue. Done means an agreed public API, return type, duplicate-cell behavior, and mixed-resource scope; no file or test is named in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
pandas, python
Domain
api, data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.