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:
- Accessor pattern (above) — clean namespace, discoverable, extensible
- Method on Cutout —
cutout.profiles_at_points(locations, turbine=...) — simpler but mixes concerns
- Enhanced keyword on existing methods —
cutout.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:
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.
Detailed Description
The
convert_and_aggregatefunction currently supports per-cell extraction viacapacity_factor_timeseries=True(withoutmatrix/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:
Other possible approaches include:
cutout.profiles_at_points(locations, turbine=...)— simpler but mixes concernscutout.wind(turbine=..., points=locations)— minimal API surface but overloadswind()/pv()Context
This is common in power system modeling where each bus/substation needs location-specific renewable capacity factors. The current workaround is either:
Cutoutobjects (very slow, ~50x overhead)capacity_factor_timeseries=Trueon a multi-cell cutout and extracting with.sel(x=lon, y=lat, method="nearest")(works, but undocumented until Document per-cell capacity factor extraction with capacity_factor_timeseries #481)convert_wind/convert_pvdirectly (not public API)See #480 for the full performance comparison and use case description.
Possible Implementation
An accessor-based design could look like:
Key design questions:
xr.DataArray(with location coords) or apd.DataFrame(with named columns)?Happy to contribute an implementation once there's agreement on the API direction.