Data Structures and Schemas#

WindKit represents most data as xarray.Dataset objects with specific naming conventions called schemas. A schema defines the required dimensions, coordinates, and variables for a particular data type. This approach enables:

  • Consistent, predictable data structures across all WindKit objects

  • Automatic validation of data structure

  • Interoperability between different WindKit functions

Object Schemas

Each WindKit object type has its own schema. For example, a Binned Wind Climate (BWC) requires:

Dimensions:  (sector, wsbin, ...)
Variables:
    wsfreq  (sector, wsbin, ...)  - wind speed frequency per sector/bin
    wdfreq  (sector, ...)         - wind direction frequency per sector
Coordinates:
    wsbin       - wind speed bin centers
    sector      - sector centers (degrees from North)

Similarly, a Weibull Wind Climate (WWC) requires:

Dimensions:  (sector, ...)
Variables:
    A  (sector, ...)  - Weibull scale parameter
    k  (sector, ...)  - Weibull shape parameter
Coordinates:
    sector  - sector centers

Spatial Schemas

In addition to object-specific schemas, WindKit defines four spatial structures that control how data is organized in space:

  • point - Scattered 3D points where each point has its own (x, y, z) coordinates

  • stacked_point - 2D horizontal points that share common vertical levels

  • raster - Regular 2D grid

  • cuboid - Regular 3D grid

These spatial structures use a consistent naming convention:

Coordinates (all structures):
    west_east    - x coordinate (easting or longitude)
    south_north  - y coordinate (northing or latitude)
    height       - vertical coordinate (meters above ground)
    crs          - coordinate reference system

See Spatial Structures for detailed definitions.

Combining Schemas#

The power of WindKit’s schema system is that object schemas and spatial schemas combine. A wind climate object follows its object schema (BWC, WWC, etc.) and one of the spatial schemas (point, stacked_point, cuboid).

For example, a Binned Wind Climate can be:

BWC at a single point (point structure):

Dimensions:  (point, sector, wsbin)
Coordinates:
    west_east    (point)   - x coordinate
    south_north  (point)   - y coordinate
    height       (point)   - z coordinate
    sector       (sector)  - wind direction sectors
    wsbin        (wsbin)   - wind speed bins
Variables:
    wsfreq  (point, sector, wsbin)  - frequency per location/sector/bin
    wdfreq  (point, sector)         - direction frequency per location/sector

BWC at multiple heights (stacked_point structure):

Dimensions:  (stacked_point, height, sector, wsbin)
Coordinates:
    west_east    (stacked_point)  - x coordinate
    south_north  (stacked_point)  - y coordinate
    height       (height)         - shared vertical levels
    sector       (sector)         - wind direction sectors
    wsbin        (wsbin)          - wind speed bins
Variables:
    wsfreq  (stacked_point, height, sector, wsbin)
    wdfreq  (stacked_point, height, sector)

BWC on a resource grid (cuboid structure):

Dimensions:  (south_north, west_east, height, sector, wsbin)
Coordinates:
    west_east    (west_east)    - x grid coordinates
    south_north  (south_north)  - y grid coordinates
    height       (height)       - vertical levels
    sector       (sector)       - wind direction sectors
    wsbin        (wsbin)        - wind speed bins
Variables:
    wsfreq  (south_north, west_east, height, sector, wsbin)
    wdfreq  (south_north, west_east, height, sector)

This flexibility means the same BWC functions work regardless of whether you have data at a single mast, multiple sites, or an entire resource grid.

Practical Example#

Here’s how schemas combine in practice:

import windkit as wk

# Get path to tutorial data
path = wk.get_tutorial_data("serra_santa_luzia")

# Load a binned wind climate
bwc = wk.read_bwc(path / "bwc.omwc")

# Check its spatial structure
wk.spatial.is_point(bwc)         # True for single-point BWC
wk.spatial.is_stacked_point(bwc) # True for multi-height BWC

# Validate it follows the BWC schema
wk.validate_bwc(bwc)  # Raises if invalid

# The BWC functions work regardless of spatial structure
wwc = wk.weibull_fit(bwc)  # Works for point, stacked_point, or cuboid