Long-Term Correction (LTC)#

Long-term correction extends a short on-site measurement campaign to represent the long-term wind climate at a site. WindKit provides Measure-Correlate-Predict (MCP) methods that learn the relationship between a short-term target and a long-term reference, then apply it to the full reference record.

MCP Workflow#

  1. A long-term reference station provides many years of wind data.

  2. Short-term target measurements at the project site overlap the reference (the concurrent period).

  3. An MCP model is fitted on the concurrent period, learning a per-sector mapping from reference to target wind speeds.

  4. The fitted model is applied to the full reference record to produce a long-term corrected wind climate at the site.

Data Requirements#

Both reference and target datasets must be time series wind climates (TSWC) containing wind_speed and wind_direction over a time dimension.

  • Single-point datasets only (one spatial location per dataset).

  • The reference and target must share the same time coordinates during the concurrent period.

For testing, windkit.create_tswc_pair() generates a correlated synthetic pair:

out_locs = create_point(500000, 6200000, 80, 32632)
period_lt = pd.date_range("2004-01-01", "2009-01-01", freq="1h", inclusive="left")
period_st = pd.date_range("2008-01-01", "2009-01-01", freq="1h", inclusive="left")

tgt_lt, ref_lt = wk.create_tswc_pair(
    out_locs,
    date_range=period_lt,
    weibull_A=(6.0, 8.0),
    weibull_k=(1.6, 2.2),
    target_r2=0.8,
    speed_tau=14400.0,
)
ref_st = ref_lt.sel(time=period_st)
tgt_st = tgt_lt.sel(time=period_st)

Available Methods#

WindKit provides two sectorwise MCP regression methods:

Method

Regression

Variance

Noise option

LinRegMCP

Ordinary least squares

Compresses variance

predict_with_noise()

VarRatMCP

Variance ratio (σy / σx)

Preserves variance ratio

Both methods fit one independent linear model per wind direction sector (default 12 sectors of 30°).

Fitting and Predicting#

The API follows the scikit-learn fit / predict pattern:

model = LinRegMCP(n_sectors=12)
model.fit(ref_st, tgt_st)

# Deterministic prediction (conditional mean)
pred_lt = model.predict(ref_lt)

# Prediction with noise (recovers variance)
pred_lt_noisy = model.predict_with_noise(ref_lt, seed=42)

Recovering Variance with Noise#

Deterministic MCP predictions lie on the regression line — every predicted wind speed is the conditional mean for its sector. This compresses the variance of the predicted distribution, clipping the high-wind tail where most energy is produced.

predict_with_noise() adds Gaussian noise sampled from the per-sector residual standard deviation, N(0, residual_std), re-inflating the distribution to its proper width. Negative wind speeds are clipped to zero.

pred_lt_det = model.predict(ref_lt)
pred_lt_noisy = model.predict_with_noise(ref_lt, seed=42)

ws_true = tgt_lt.wind_speed.values.flatten()
print(f"Site true std:          {np.std(ws_true):.3f} m/s")
print(f"LinReg (deterministic): {np.std(pred_lt_det.wind_speed.values):.3f} m/s")
print(f"LinReg (with noise):    {np.std(pred_lt_noisy.wind_speed.values):.3f} m/s")
Site true std:          3.447 m/s
LinReg (deterministic): 3.040 m/s
LinReg (with noise):    3.340 m/s

When to use which:

  • Energy yield estimation — use predict_with_noise to preserve the distribution shape, especially the high-wind tail.

  • Regression diagnostics — use predict for clean deterministic output when evaluating model fit quality.

Model Evaluation#

calc_scores() computes four metrics comparing predicted and observed wind speeds:

Metric

Interpretation

Coefficient of determination — 1.0 is perfect.

RMSE

Root mean squared error (m/s) — lower is better.

Mean bias

Systematic over/under-prediction (m/s) — 0 is unbiased.

EMD

Earth mover’s distance — distribution shape similarity.

pred_st = model.predict(ref_st)
scores = calc_scores(tgt_st, pred_st, name="LinReg", period="Concurrent")
print(scores.to_string(index=False))
  Name     Period    Metric    Score
LinReg Concurrent       R^2 0.796049
LinReg Concurrent      RMSE 1.570163
LinReg Concurrent Mean bias 0.000000
LinReg Concurrent       EMD 0.386572

Configuration Options#

All MCP classes accept these parameters at construction:

n_sectors (int, default 12)

Number of wind direction sectors. Each sector gets an independent regression model.

quantiles (bool, default False)

If True, sectors are defined by equal-probability quantiles of the wind direction distribution rather than constant widths.

ws_cutoff (float, default 0.0)

Wind speed threshold — observations below this value are excluded from fitting.

VarRatMCP additionally accepts:

fit_intercept (bool, default True)

Whether to fit an intercept term. Set to False to force the regression through the origin.

See Also#