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.
Metadata
Release files for pywrb 0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pywrb-0.2.tar.gz | 3.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pywrb-0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.8 MB
Release files / pywrb-0.2.tar.gz
| Download URL | pywrb-0.2.tar.gz |
|---|---|
| Size | 3.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e5f7da5c6b45c717287f6f2ea634079095147c4f1bc7fcba18a99d071ce403d4
|
|
BLAKE2b-256 checksum How to use checksums |
f7474a9bb874c18a269fba7f1e7e3a85694ac5fcaaa09d0d489ea7dae6f6373b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / pywrb-0.2-py3-none-any.whl
| Download URL | pywrb-0.2-py3-none-any.whl |
|---|---|
| Size | 14.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4507984f03cc38949d31695b66fd8aeb19485371e5a21df1a5de4ce8238550d4
|
|
BLAKE2b-256 checksum How to use checksums |
082a76a26777b0c8bcd07db853469b5e6d17bea0ad2b1eae1d57c760c738ed89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|