Binned Wind Climate (BWC)#

The binned wind climate contains a histogram representation of the wind for different wind direction sectors. In WAsP, this is called an “Observed Wind Climate” and is stored in .tab and .owc files.

Data Structure#

BWC objects are xarray.Dataset with the following schema:

Dimensions:  (sector, wsbin, ...)
Variables:
    wsfreq  (sector, wsbin, ...)  - wind speed frequency per sector/bin
    wdfreq  (sector, ...)         - wind direction frequency per sector

In addition to the core coordinates, BWC objects contain:

  • wsbin - wind speed bin centers

  • wsfloor, wsceil - bin boundaries

  • sector - sector centers

  • sector_floor, sector_ceil - sector boundaries

I/O#

Format

Read

Write

Description

.tab

yes

yes

WAsP TAB format

.owc

yes

no

WAsP Observed Wind Climate

.omwc

yes

no

WAsP Observed Mesoscale Wind Climate

.nc

yes

via .to_netcdf()

NetCDF format

Reading:

windkit.read_bwc() reads binned wind climates:

bwc = wk.read_bwc("bwc.omwc", crs="EPSG:4326")

Writing:

windkit.bwc_to_file() writes binned wind climates to .tab files:

wk.bwc_to_file(bwc, "output.tab")

Creating from Arrays#

wsbins = np.linspace(0.0, 30.0, 31)
wdbins = np.linspace(-15.0, 345.0, 13)

wsfreq = np.random.rand(30, 12)
wsfreq = wsfreq / wsfreq.sum(axis=0)

wdfreq = np.random.rand(12)
wdfreq = wdfreq / wdfreq.sum()

bwc = xr.Dataset(
    data_vars=dict(
        wsfreq=(("wsbin", "sector"), wsfreq),
        wdfreq=(("sector",), wdfreq),
    ),
    coords=dict(
        wsbin=(("wsbin",), (wsbins[1:] + wsbins[:-1]) / 2.0),
        wsfloor=(("wsbin",), wsbins[:-1]),
        wsceil=(("wsbin",), wsbins[1:]),
        sector=(("sector",), (wdbins[1:] + wdbins[:-1]) / 2.0),
        sector_floor=(("sector_floor",), np.mod(wdbins[:-1], 360)),
        sector_ceil=(("sector_ceil",), np.mod(wdbins[1:], 360)),
    )
)
bwc
<xarray.Dataset> Size: 4kB
Dimensions:       (wsbin: 30, sector: 12, sector_floor: 12, sector_ceil: 12)
Coordinates:
  * wsbin         (wsbin) float64 240B 0.5 1.5 2.5 3.5 ... 26.5 27.5 28.5 29.5
    wsfloor       (wsbin) float64 240B 0.0 1.0 2.0 3.0 ... 26.0 27.0 28.0 29.0
    wsceil        (wsbin) float64 240B 1.0 2.0 3.0 4.0 ... 27.0 28.0 29.0 30.0
  * sector        (sector) float64 96B 0.0 30.0 60.0 90.0 ... 270.0 300.0 330.0
  * sector_floor  (sector_floor) float64 96B 345.0 15.0 45.0 ... 285.0 315.0
  * sector_ceil   (sector_ceil) float64 96B 15.0 45.0 75.0 ... 285.0 315.0 345.0
Data variables:
    wsfreq        (wsbin, sector) float64 3kB 0.05767 0.05324 ... 0.04793
    wdfreq        (sector) float64 96B 0.03072 0.08441 ... 0.09398 0.1051

Creating from TSWC#

windkit.bwc_from_tswc() creates BWC from time series data:

# First create a TSWC
tswc = xr.Dataset(
    data_vars=dict(
        wind_speed = xr.DataArray(np.random.rand(1000)*15, dims=['time']),
        wind_direction = xr.DataArray(np.random.rand(1000)*360, dims=['time']),
    ),
    coords=dict(
        time = pd.date_range('2020-01-01', periods=1000, freq='h'),
        height = 80.0,
    )
)
tswc = tswc.expand_dims("stacked_point").assign_coords(
    west_east = (("stacked_point",), [10.0]),
    south_north = (("stacked_point",), [56.0]),
)
tswc = wk.spatial.set_crs(tswc, crs=4326)

# Convert to BWC
bwc = wk.bwc_from_tswc(tswc)

Combining BWCs#

windkit.combine_bwcs() combines multiple BWC datasets into one:

# Create two BWCs at different locations
bwc1 = bwc.expand_dims("point").assign_coords(
    west_east=(("point",), [10.0]),
    south_north=(("point",), [56.0]),
    height=(("point",), [80.0]),
)
bwc1 = wk.spatial.set_crs(bwc1, crs=4326)

bwc2 = bwc.expand_dims("point").assign_coords(
    west_east=(("point",), [11.0]),
    south_north=(("point",), [57.0]),
    height=(("point",), [80.0]),
)
bwc2 = wk.spatial.set_crs(bwc2, crs=4326)

# Combine into one dataset
combined = wk.combine_bwcs([bwc1, bwc2])
print(f"Combined BWC points: {wk.spatial.count_spatial_points(combined)}")
Combined BWC points: 1

Validation#

wk.is_bwc(bwc)
True