Wind Climate Formats#
.tab - Binned Wind Climate#
Text format storing wind speed frequency distributions per sector.
Functions: read_tab(), write_tab(), format_tab()
Normalization: read_tab returns frequencies normalized to 0-1.
write_tab and format_tab accept 0-1 values and convert to per-mille (wsfreq)
and percent (wdfreq) for the file format.
Return structure:
{
"wsfreq": np.ndarray, # (n_wsbins, n_sectors) - wind speed frequencies (0-1)
"wdfreq": np.ndarray, # (n_sectors,) - direction frequencies (0-1)
"wsbins": np.ndarray, # (n_wsbins + 1,) - bin edges
"coords": {
"south_north": float,
"west_east": float,
"height": float,
},
"metadata": {"description": str},
}
Example:
from windkit.io.wasp import read_tab, write_tab, format_tab
# Read
data = read_tab("measurements.tab")
print(data["wsfreq"].shape) # (30, 12) for 30 bins, 12 sectors
print(data["wdfreq"].sum()) # Close to 1.0
# Write
write_tab("output.tab",
data["wsfreq"], data["wdfreq"], data["wsbins"],
data["coords"], data["metadata"])
# Format as string (without writing to file)
tab_string = format_tab(
data["wsfreq"], data["wdfreq"], data["wsbins"],
data["coords"], data["metadata"])
.owc / .omwc - Observed Wind Climate#
XML format for observed wind climate data from measurements. Stores wind speed
frequency distributions per sector, similar to .tab but in XML.
Functions: read_owc(), parse_owc_element()
Normalization: read_owc returns frequencies as stored in the XML (0-1).
Return structure:
{
"wsfreq": np.ndarray, # (n_wsbins, n_sectors) - wind speed frequencies (0-1)
"wdfreq": np.ndarray, # (n_sectors,) - direction frequencies (0-1)
"wsbins": np.ndarray, # (n_wsbins + 1,) - bin edges
"coords": {
"south_north": float,
"west_east": float,
"height": float,
},
"metadata": {"description": str},
}
Example:
from windkit.io.wasp import read_owc
# Read
data = read_owc("observed.omwc")
print(data["wsfreq"].shape) # (30, 12) for 30 bins, 12 sectors
print(data["wdfreq"].sum()) # Close to 1.0
Note
The .owc and .omwc formats are read-only. There is no write_owc
function; use write_tab() to export binned wind
climate data.
.lib - Generalized Wind Climate Library#
Text format for generalized wind climate with Weibull parameters across multiple roughness classes and heights.
Functions: read_lib(), write_lib(), format_lib()
Normalization: read_lib returns wdfreq normalized to 0-1.
write_lib and format_lib accept 0-1 values and convert to percent
for the file format. A and k are raw Weibull parameters.
Return structure:
{
"A": np.ndarray, # (n_sectors, n_heights, n_roughnesses) - Weibull scale
"k": np.ndarray, # (n_sectors, n_heights, n_roughnesses) - Weibull shape
"wdfreq": np.ndarray, # (n_sectors, n_roughnesses) - direction freq (0-1)
"gen_roughness": np.ndarray, # (n_roughnesses,) - roughness classes
"gen_height": np.ndarray, # (n_heights,) - generalized heights
"coords": {
"south_north": float or None,
"west_east": float or None,
"height": float or None,
},
"metadata": {"description": str},
}
Example:
from windkit.io.wasp import read_lib, write_lib, format_lib
# Read
data = read_lib("climate.lib")
print(data["A"].shape) # (12, 5, 5) for 12 sectors, 5 heights, 5 roughnesses
print(data["wdfreq"].sum(axis=0)) # Close to 1.0 per roughness class
# Write
write_lib("output.lib",
data["A"], data["k"], data["wdfreq"],
data["gen_roughness"], data["gen_height"],
data["coords"], data["metadata"])
# Format as string (without writing to file)
lib_string = format_lib(
data["A"], data["k"], data["wdfreq"],
data["gen_roughness"], data["gen_height"],
data["coords"], data["metadata"])
.rsf / .wrg - Resource Grid#
Fixed-width text format storing, for each site in a set of sites, the
location, height, sector-wise and combined Weibull wind climate, and a power
column. A .wrg file is a .rsf file with one extra header line
describing the regular grid (Nx Ny Xmin Ymin cell_size); both are handled
by the same functions, and the header is detected automatically on read.
Functions: read_rsf(), write_rsf(), format_rsf()
Normalization: the sector-wise values are descaled on read and rescaled on
write by the format’s fixed factors — A by 10, k by 100 and wdfreq
by 1000 (per mille to 0-1 fractions). The power column is returned raw: the
file does not record whether it holds power density [W/m2] or power
production [Wh/y], so interpreting it is left to the caller.
Return structure:
{
"name": np.ndarray, # (n_points,) - site names
"coords": {
"west_east": np.ndarray, # (n_points,)
"south_north": np.ndarray, # (n_points,)
"height": np.ndarray, # (n_points,)
},
"site_elev": np.ndarray, # (n_points,) - site elevation [m]
"A": np.ndarray, # (n_points, n_sectors) - Weibull scale [m/s]
"k": np.ndarray, # (n_points, n_sectors) - Weibull shape
"wdfreq": np.ndarray, # (n_points, n_sectors) - direction freq (0-1)
"A_combined": np.ndarray, # (n_points,) - total-distribution Weibull scale
"k_combined": np.ndarray, # (n_points,) - total-distribution Weibull shape
"power": np.ndarray, # (n_points,) - power column, raw
"header": dict or None, # {"nx", "ny", "xmin", "ymin", "cell_size"}
}
Example:
from windkit.io.wasp import read_rsf, write_rsf, format_rsf
# Read (.rsf and .wrg alike)
data = read_rsf("resource.wrg")
print(data["A"].shape) # (n_points, n_sectors)
print(data["header"]) # grid header dict, or None for a plain .rsf
# Write (pass header=... to produce a .wrg grid header line)
write_rsf("output.wrg",
data["A"], data["k"], data["wdfreq"],
data["A_combined"], data["k_combined"],
data["power"], data["site_elev"], data["coords"],
name=data["name"], header=data["header"])
# Format as string (without writing to file)
rsf_string = format_rsf(
data["A"], data["k"], data["wdfreq"],
data["A_combined"], data["k_combined"],
data["power"], data["site_elev"], data["coords"])
.gwc - Generalized Wind Climate (XML)#
XML format for a generalized wind climate at one location: Weibull parameters
and sector frequencies on a grid of reference roughness lengths and reference
heights. WAsP writes the RveaGeneralisedMeanWindClimate element either as
the document root or nested inside a WaspHierarchyMember, and identifies a
wind rose’s grid cell by number, by value, or by number with the values listed
once in a StandardConditions element; all of these are read. The grid must
be complete: a cell without a wind rose, a cell with two, or a rose missing a
sector raises ValueError rather than coming out as zeros.
Functions: read_gwc(), parse_gwc_element()
Normalization: read_gwc returns wdfreq normalized to 0-1 along the
sector axis, like read_lib. Unlike .lib, the format stores a sector
frequency per (height, roughness) cell, so wdfreq is 3-D. A and k
are raw Weibull parameters.
Coordinates: the element may embed a RveaLatitudeLongitudeCoordinate
and a Description; read_gwc also falls back to a
RveaAnemometerSiteDetails element anywhere in the file, which is where a
WAsP-exported hierarchy keeps the mast position and height. Anything still
unknown is None. parse_gwc_element reads the element only.
Return structure:
{
"A": np.ndarray, # (n_sectors, n_heights, n_roughnesses) - Weibull scale
"k": np.ndarray, # (n_sectors, n_heights, n_roughnesses) - Weibull shape
"wdfreq": np.ndarray, # (n_sectors, n_heights, n_roughnesses) - direction freq (0-1)
"sector": np.ndarray, # (n_sectors,) - sector centre angles in degrees
"gen_roughness": np.ndarray, # (n_roughnesses,) - roughness classes
"gen_height": np.ndarray, # (n_heights,) - generalized heights
"coords": {
"south_north": float or None,
"west_east": float or None,
"height": float or None,
},
"metadata": {"description": str or None},
# The mesoscale climate the generalization used; None when absent
"barometric_reference": dict or None, # reference air density conditions
"stability_inputs": dict or None, # (n_sectors,) arrays, WAsP 12.8+
"geostrophic_shear": dict or None, # (n_sectors,) arrays, WAsP 12.8+
}
The keys of the three mesoscale climate dicts are listed in
parse_gwc_element() and use the variable names PyWAsP
uses. For a generalized wind climate in a WAsP workspace,
windkit.Workspace.get_mesoclimate() returns the stability inputs and
geostrophic shear as a dataset ready to pass to PyWAsP, and
windkit.Workspace.get_air_density_reference() returns the barometric
reference.
Example:
from windkit.io.wasp import read_gwc
data = read_gwc("climate.gwc")
print(data["A"].shape) # (12, 5, 5) for 12 sectors, 5 heights, 5 roughnesses
print(data["wdfreq"].sum(axis=0)) # 1.0 in every (height, roughness) cell
Note
The .gwc format is read-only. There is no write_gwc function. To
export as .lib, pass write_lib() a 2-D
wdfreq – one height’s slice, e.g. data["wdfreq"][:, 0, :] –
since .lib stores one frequency per roughness.