Wind Resource binary reader and writer
Project description
pywrb
The pywrb library for reading and writing WRB files.
Features
- Read and write WRB files
- xarray integration for reading and writing datasets
- Variable naming convention encodes present dimensions via
_at_directionand_at_wind_speedsuffixes - Surface variables (
elevation,roughness_length,vegetation_height,ground_porosity) are always 2D wrbinfoCLI for inspecting WRB file metadata- Cloud storage support via fsspec (optional)
Requirements
- Python 3.10+
- NumPy
Optional:
- xarray + rioxarray (
pip install pywrb[xarray]) - fsspec for cloud/remote file access (
pip install fsspec)
Installation
pip install pywrb # core only
pip install pywrb[xarray] # with xarray support
pip install pywrb[dev] # with development dependencies
Usage
xarray interface
For most use cases the xarray interface is recommended. Variables are named after their block meaning, with _at_direction and _at_wind_speed suffixes added automatically when those dimensions are present in the blocks. Surface variables (elevation, roughness_length, vegetation_height, ground_porosity) are always 2D and never receive suffixes.
Reading and plotting
import xarray as xr
ds = xr.open_dataset("wind_resource.wrb", engine="pywrb")
# 2D surface variable
ds["elevation"].plot.imshow()
# Select a height and plot mean wind speed across the site
ds["mean_wind_speed"].sel(heights=100).plot.imshow()
# Directional mean wind speed — one panel per direction
ds["mean_wind_speed_at_direction"].sel(heights=100).plot(col="directions", col_wrap=4)
Supported fields
Variable names map directly to pywrb.WRB_BLOCK_MEANING. The table below shows the base name; append _at_direction and/or _at_wind_speed when those dimensions are present.
| xarray variable | WRB_BLOCK_MEANING |
always 2D |
|---|---|---|
elevation |
ELEVATION |
✓ |
roughness_length |
ROUGHNESS_LENGTH |
✓ |
vegetation_height |
VEGETATION_HEIGHT |
✓ |
ground_porosity |
GROUND_POROSITY |
✓ |
mean_wind_speed |
MEAN_WIND_SPEED |
|
weibull_scale |
WEIBULL_SCALE |
|
weibull_shape |
WEIBULL_SHAPE |
|
power |
POWER |
|
turbulence_intensity |
TURBULENCE_INTENSITY |
|
inflow_angle |
INFLOW_ANGLE |
|
probability |
PROBABILITY |
|
air_density |
AIR_DENSITY |
|
vertical_velocity |
VERTICAL_VELOCITY |
|
wind_shear_exponent |
WIND_SHEAR_EXPONENT |
|
eloss |
ELOSS |
|
uncertainty |
UNCERTAINTY |
Writing
To write a dataset to WRB, variable names must follow the naming convention above. The dataset must have a CRS set via rioxarray. The example below creates a typical wind resource dataset with omnidirectional and directional Weibull parameters, turbulence intensity, and surface variables:
import xarray as xr
import numpy as np
n_x, n_y, n_directions, n_wind_speed, n_heights = 128, 128, 12, 10, 3
ds = xr.Dataset(
data_vars=dict(
weibull_scale=(
["x", "y", "heights"],
np.random.randn(n_x, n_y, n_heights),
),
weibull_shape=(
["x", "y", "heights"],
np.random.randn(n_x, n_y, n_heights),
),
weibull_scale_at_direction=(
["x", "y", "directions", "heights"],
np.random.randn(n_x, n_y, n_directions, n_heights),
),
weibull_shape_at_direction=(
["x", "y", "directions", "heights"],
np.random.randn(n_x, n_y, n_directions, n_heights),
),
turbulence_intensity_at_direction_at_wind_speed=(
["x", "y", "directions", "wind_speeds", "heights"],
np.random.randn(n_x, n_y, n_directions, n_wind_speed, n_heights),
),
elevation=(["x", "y"], np.ones((n_x, n_y))),
roughness_length=(["x", "y"], np.ones((n_x, n_y))),
),
coords=dict(
x=(["x"], np.arange(n_x)),
y=(["y"], np.arange(n_y)),
directions=(["directions"], np.linspace(0, 360, n_directions, endpoint=False)),
wind_speeds=(["wind_speeds"], np.linspace(6, 15, n_wind_speed)),
heights=(["heights"], [100, 150, 200]),
),
)
ds = ds.rio.write_crs("epsg:4326")
ds.pywrb.to_wrb("output.wrb")
Low-level interface
The low-level interface provides direct access to individual WRB blocks. This is useful for exotic data that the xarray interface does not cover.
Reading an existing WRB file:
import pywrb
with pywrb.open("wind_resource.wrb", mode="r") as wrb:
for block, data in wrb:
if block["meaning"] == pywrb.WRB_BLOCK_MEANING.ELEVATION:
print(data)
Writing a new WRB file:
import numpy as np
import pywrb
data = np.ones((10, 10))
with pywrb.open(
"output.wrb",
mode="w",
crs="EPSG:25832",
minx=0, miny=0, maxx=900, maxy=900,
resolutionx=100, resolutiony=100,
heights=[100],
directions=0,
wind_speeds=[],
) as wrb:
wrb.add_block(data=data, meaning=pywrb.WRB_BLOCK_MEANING.ELEVATION, unit=pywrb.WRB_UNIT.METER)
wrb.add_block(data=data + 1, meaning=pywrb.WRB_BLOCK_MEANING.MEAN_WIND_SPEED, height=100)
wrb.write()
A file-like object can also be passed directly, which is useful for integrating with other libraries:
with open("wind_resource.wrb", "rb") as f:
with pywrb.WRBFile(f) as wrb:
print(wrb.shape)
Cloud storage with fsspec
Remote files can be opened by passing a URI directly to WRBFile or pywrb.open(). Any URI scheme supported by fsspec works (s3://, gs://, az://, etc.):
pip install fsspec s3fs
import pywrb
import xarray as xr
# Low-level
with pywrb.open("s3://my-bucket/wind_resource.wrb", mode="r") as wrb:
print(wrb.shape)
# xarray
ds = xr.open_dataset("s3://my-bucket/wind_resource.wrb", engine="pywrb")
Alternatively, open the file yourself with fsspec and pass the file object in:
import fsspec
import pywrb
with fsspec.open("s3://my-bucket/wind_resource.wrb", "rb") as f:
with pywrb.WRBFile(f) as wrb:
print(wrb.shape)
CLI
wrbinfo prints metadata about a WRB file, similar to gdalinfo:
wrbinfo wind_resource.wrb
Driver: WRB v2
CRS: epsg:32632
Size: 127 x 127 (width x height)
Origin: (439887.0, 4833898.0)
Pixel: (200.0, 200.0)
Extent: (439887.0, 4833898.0) - (465087.0, 4859098.0)
Directions (16): [0.0, 22.5, 45.0, ...]
Heights (1): [80]
Speeds (0): []
Blocks (69):
[ 0] ELEVATION
[ 1] ROUGHNESS_LENGTH
[ 2] WEIBULL_SCALE height=80.0
...
JSON output is also supported:
wrbinfo wind_resource.wrb --format json
Limitations
Multi-regime files
The WRB format supports multi-regime datasets where blocks carry a probability < 1.0, indicating they belong to one of several wind regimes that together sum to 1.0. The low-level WRBFile interface and wrbinfo CLI can read these files, but the xarray interface does not support them and will raise a NotImplementedError. Single-regime files (probability = 1.0, the default) are fully supported.
Contributing
Contributions to pywrb are welcome! If you'd like to contribute, please fork the repository and submit a pull request.
License
pywrb is licensed under the MIT License.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pywrb-0.2.tar.gz.
File metadata
- Download URL: pywrb-0.2.tar.gz
- Upload date:
- Size: 3.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5f7da5c6b45c717287f6f2ea634079095147c4f1bc7fcba18a99d071ce403d4
|
|
| MD5 |
9e8cc89f3ddbcc3b3fd8e3b2e19f8216
|
|
| BLAKE2b-256 |
f7474a9bb874c18a269fba7f1e7e3a85694ac5fcaaa09d0d489ea7dae6f6373b
|
File details
Details for the file pywrb-0.2-py3-none-any.whl.
File metadata
- Download URL: pywrb-0.2-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4507984f03cc38949d31695b66fd8aeb19485371e5a21df1a5de4ce8238550d4
|
|
| MD5 |
f3c9e92afd9149ea7ef5480dc0035dd4
|
|
| BLAKE2b-256 |
082a76a26777b0c8bcd07db853469b5e6d17bea0ad2b1eae1d57c760c738ed89
|