windtab WAsP .tab viewer ← App

Documentation windtab

windtab reads WAsP Observed Wind Climate files (.tab) and produces a wind rose, Weibull fits per sector, a joint probability heatmap, and a sector statistics table. The formulas behind each panel are below.

Privacy & data handling

Your files never leave your browser. windtab runs entirely client-side: no server, no upload, no analytics.

When you load a .tab file, the browser reads it from disk using the File API and runs all parsing and calculation locally. Nothing reaches the network. Close the tab and the data is gone.

Coordinates, site names, and frequency tables stay on your machine. Safe for commercially sensitive wind resource data.

File format

WAsP Observed Wind Climate files are plain text:

Line 1: Site name
Line 2: x_coord   y_coord   height_m
Line 3: n_sectors   speed_scale   direction_offset
Line 4: sector_frequencies...  (space-separated, %)
Line 5+: speed_bin   freq[0]   freq[1]   ...   freq[n−1]  (per-mille, within-sector conditional)

speed_scale multiplies every speed bin value. direction_offset shifts all sector centre angles. Frequencies on line 5+ are conditional on wind direction: how often each speed class occurs given that sector, in parts per thousand. They need not sum to 1000 across sectors.

Wind rose

Each petal's length is the joint probability of that direction sector and speed class occurring together:

Joint probability $$p(i,j) = \frac{f_{ij}}{1000} \times \frac{F_j}{100}$$

fij is the within-sector conditional frequency (per mille) for speed bin i in sector j; Fj is the sector frequency (%). Values sum to 1 across all bins and sectors.

Energy proxy mode weights each petal by speed³, proportional to kinetic energy flux, and more informative than raw frequency for identifying which sectors drive wind resource.

Weibull distribution

Each sector is fitted to a two-parameter Weibull. The PDF:

Weibull PDF $$f(x;\,A,k) = \frac{k}{A}\left(\frac{x}{A}\right)^{k-1}\exp\!\left(-\left(\frac{x}{A}\right)^{k}\right), \quad x > 0$$

A (scale, m/s) sets the characteristic speed; the mean is A Γ(1 + 1/k). k (shape) controls the spread; k near 2 is typical for wind, higher k means more concentrated.

Parameters are estimated by weighted maximum likelihood. The shape k is the root of:

MLE condition for k: solve g(k) = 0 $$g(k) = \frac{1}{k} + \frac{\sum w_i \ln x_i}{\sum w_i} - \frac{\sum w_i x_i^k \ln x_i}{\sum w_i x_i^k} = 0$$

Solved by Newton-Raphson from $k_0 = 2$:

Newton-Raphson update $$k_{n+1} = k_n - \frac{g(k_n)}{g'(k_n)}$$
Derivative of g $$g'(k) = -\frac{1}{k^2} - \frac{\sum w_i x_i^k (\ln x_i)^2 \cdot \sum w_i x_i^k - \left(\sum w_i x_i^k \ln x_i\right)^2}{\left(\sum w_i x_i^k\right)^2}$$

Stops when $|\Delta k| \lt 10^{-10}$ or after 200 iterations. Once k converges, A in closed form:

Scale parameter A (closed form) $$A = \left(\frac{\sum w_i x_i^k}{\sum w_i}\right)^{1/k}$$

Weights wi are within-sector frequencies divided by 1000. Zero-frequency bins are excluded since log(0) is undefined. Fewer than two non-zero bins returns A = k = 0 with no curve drawn.

Joint probability heatmap

The heatmap is the same p(i, j) matrix as the wind rose, with direction on the x-axis, speed on the y-axis, values in %. Clicking a column syncs the sector selection across all panels.