Time Series Wind Climate (TSWC)#

The time series wind climate contains a time series of wind_speed and wind_direction. It is the most basic wind climate from which all others can be derived, retaining all original information.

Data Structure#

TSWC objects are xarray.Dataset with the following schema:

Dimensions:  (time, ...)
Variables:
    wind_speed      (time, ...)  - wind speed in m/s
    wind_direction  (time, ...)  - wind direction in degrees

In addition to the core spatial coordinates, TSWC objects contain the time dimension.

I/O#

Format

Read

Write

Description

.csv

yes

no

Comma-separated values

.txt

yes

no

WindPRO time series export

.nc

yes

via .to_netcdf()

NetCDF format

.yaml

yes

yes

windIO (experimental)

Reading:

windkit.read_tswc() reads time series wind climates:

# Read from NetCDF
tswc = wk.read_tswc("wind_data.nc")

# Read from CSV
tswc = wk.read_tswc("wind_data.csv", crs="EPSG:4326")

Writing:

TSWC can be written to NetCDF using xarray’s built-in method:

tswc.to_netcdf("output.nc")

windkit.tswc_to_file() writes TSWC to windIO YAML files:

wk.tswc_to_file(tswc, "output.yaml")

Creating from Arrays#

tswc = xr.Dataset(
    data_vars=dict(
        wind_speed = xr.DataArray(np.random.rand(100, 3)*10, dims=['time', 'height']),
        wind_direction = xr.DataArray(np.random.rand(100, 3)*360, dims=['time', 'height']),
    ),
    coords=dict(
        time = (("time",), pd.date_range('2020-01-01', periods=100, freq='h')),
        height = (("height"), [10, 50, 100]),
    )
)
print(tswc)
<xarray.Dataset> Size: 6kB
Dimensions:         (time: 100, height: 3)
Coordinates:
  * time            (time) datetime64[us] 800B 2020-01-01 ... 2020-01-05T03:0...
  * height          (height) int64 24B 10 50 100
Data variables:
    wind_speed      (time, height) float64 2kB 2.579 2.367 9.965 ... 4.439 7.558
    wind_direction  (time, height) float64 2kB 287.1 131.6 168.3 ... 71.74 76.05

To add spatial information:

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)
tswc
<xarray.Dataset> Size: 6kB
Dimensions:         (time: 100, height: 3, stacked_point: 1)
Coordinates:
  * time            (time) datetime64[us] 800B 2020-01-01 ... 2020-01-05T03:0...
  * height          (height) int64 24B 10 50 100
    west_east       (stacked_point) float64 8B 10.0
    south_north     (stacked_point) float64 8B 56.0
    crs             int8 1B 0
Dimensions without coordinates: stacked_point
Data variables:
    wind_speed      (stacked_point, time, height) float64 2kB 2.579 ... 7.558
    wind_direction  (stacked_point, time, height) float64 2kB 287.1 ... 76.05

Creating from DataFrame#

windkit.tswc_from_dataframe() creates TSWC from pandas DataFrames:

data = {
    "wind_speed_10m": np.random.rand(100)*10,
    "wind_speed_50m": np.random.rand(100)*10,
    "wind_direction_10m": np.random.rand(100)*360,
    "wind_direction_50m": np.random.rand(100)*360,
}

df = pd.DataFrame(
    data,
    index=pd.date_range('2020-01-01', periods=100, freq='h'),
)

height_to_columns = {
    10: ("wind_speed_10m", "wind_direction_10m"),
    50: ("wind_speed_50m", "wind_direction_50m"),
}

tswc = wk.tswc_from_dataframe(
    df,
    west_east=10.0,
    south_north=56.0,
    crs=4326,
    height_to_columns=height_to_columns,
)
tswc
<xarray.Dataset> Size: 4kB
Dimensions:         (time: 100, height: 2, stacked_point: 1)
Coordinates:
  * time            (time) datetime64[us] 800B 2020-01-01 ... 2020-01-05T03:0...
  * height          (height) int64 16B 10 50
    west_east       (stacked_point) float64 8B 10.0
    south_north     (stacked_point) float64 8B 56.0
    crs             int8 1B 0
Dimensions without coordinates: stacked_point
Data variables:
    wind_speed      (time, height, stacked_point) float64 2kB 6.716 ... 6.987
    wind_direction  (time, height, stacked_point) float64 2kB 263.9 ... 223.3
Attributes:
    history:          2026-09-29T09:46:27+00:00:\twindkit==2.2.0\twk.tswc_fro...
    Conventions:      CF-1.8
    Package name:     windkit
    Package version:  2.2.0
    Creation date:    2026-09-29T09:46:27+00:00
    Object type:      Time Series Wind Climate

Creating Synthetic Data#

windkit.create_tswc() creates a synthetic TSWC with realistic temporal and spatial correlations, useful for testing and prototyping:

from windkit.spatial import create_point

out_locs = create_point(500000, 6200000, 100, 32632)
tswc = wk.create_tswc(out_locs, weibull_A=7.5, weibull_k=2.0)
tswc
<xarray.Dataset> Size: 841kB
Dimensions:         (point: 1, time: 52560)
Coordinates:
    height          (point) int64 8B 100
    south_north     (point) int64 8B 6200000
    west_east       (point) int64 8B 500000
  * time            (time) datetime64[us] 420kB 2001-01-01 ... 2001-12-31T23:...
    crs             int8 1B 0
Dimensions without coordinates: point
Data variables:
    wind_speed      (point, time) float32 210kB 4.231 4.196 ... 6.313 5.425
    wind_direction  (point, time) float32 210kB 214.1 211.5 ... 148.2 157.8
Attributes:
    Conventions:      CF-1.8
    history:          2026-09-29T09:46:27+00:00:\twindkit==2.2.0\t"point")\n2...
    Package name:     windkit
    Package version:  2.2.0
    Creation date:    2026-09-29T09:46:28+00:00
    Object type:      Time Series Wind Climate

Pass not_empty=False to create a NaN-filled TSWC skeleton instead.

Pass fields="stability" to add the surface-layer stability variables temp_scale and ustar_over_pblh, correlated with the wind speed as they are in a mesoscale reference run. Both are surface-layer scales, so they carry no height dimension while the wind keeps its own. The raw mesoscale fields those are derived from - PSFC, T2, UST, HFX, LH, PBLH, Q2, ZNT, LANDMASK and elevation, in WRF naming - come from windkit.create_surface_fields(), which takes the same fields argument when both groups are needed in one correlated dataset:

stab_tswc = wk.create_tswc(out_locs, fields="stability")
sorted(stab_tswc.data_vars)
['temp_scale', 'ustar_over_pblh', 'wind_direction', 'wind_speed']

windkit.create_tswc_pair() generates a pair of correlated synthetic TSWCs, useful for testing long-term correction (MCP) methods. The two datasets share the same time axis but differ in Weibull parameters and directional bias:

ref_tswc, tgt_tswc = wk.create_tswc_pair(
    out_locs,
    weibull_A=(6.0, 8.0),
    weibull_k=(1.6, 2.2),
    target_r2=0.8,
)
ref_tswc
<xarray.Dataset> Size: 841kB
Dimensions:         (point: 1, time: 52560)
Coordinates:
    height          (point) int64 8B 100
    south_north     (point) int64 8B 6200000
    west_east       (point) int64 8B 500000
  * time            (time) datetime64[us] 420kB 2001-01-01 ... 2001-12-31T23:...
    crs             int8 1B 0
Dimensions without coordinates: point
Data variables:
    wind_speed      (point, time) float32 210kB 2.933 2.904 2.75 ... 4.838 4.002
    wind_direction  (point, time) float32 210kB 214.1 211.5 ... 148.2 157.8
Attributes:
    Conventions:      CF-1.8
    history:          2026-09-29T09:46:27+00:00:\twindkit==2.2.0\t"point")\n2...
    Package name:     windkit
    Package version:  2.2.0
    Creation date:    2026-09-29T09:46:29+00:00
    Object type:      Time Series Wind Climate

Validation#