1. Overview

Generates P10/P90 percentile power curves from consolidated wind turbine SCADA data following IEA Wind Task 19 Ice Loss Method (GitHub, BSD-3-Clause).

Purpose: Baseline curves from ice-free operation for icing/degradation detection.

Scope: Pipeline Step 6_2 (Step 6_2 Wind Power Curve Reference Icing.py) implements Task 19 reference curve generation. Downstream icing detection is implemented separately in Step 8_7 (Step 8_7 Wind Icing Detection.py).

Key Principles: Non-parametric percentiles, standard SCADA only, automatic filtering, temperature-aware.

Percentiles: P10 (lower bound), P90 (upper bound) - robust to outliers vs. mean +/- std.

Required input columns (consolidated 10-min point names): WindSpeed.10min, ActivePower.10min, AmbientTemperature.10min, OperationStateComposite.10min, OperationCategory.10min.

2. Pipeline

Validation -> Preprocessing -> Binning/Aggregation -> Interpolation -> Curve Generation
  1. Validation: Check required consolidated columns are present
  2. Preprocessing: Convert to DataFrame, apply one combined mask for state, category, and temperature
  3. Binning/Aggregation: Group by wind speed bins (bin_size=0.5 in Step 6_2; algorithm default is 1.0), compute P10/P90/mean/std/count/CV per bin
  4. Interpolation: Interpolate CV-excluded P10/P90/mean values; skip turbines if NaNs remain
  5. Curve Generation: Create P10 and P90 WindPowerCurve objects with metadata - WindIcingRefPowerCurveGeneration.run() returns tuple[list[WindPowerCurve], list[WindPowerCurve]] as (p10_curves, p90_curves). - Pipeline Step 6_2 reads WIND_WTG_CONSOLIDATED_BASE_TABLE (fact_wtg_consolidated_base_10m) and uploads the curves as REFERENCE_CURVE records. - Pipeline Step 6_2 passes bin_size=0.5; the algorithm default is bin_size=1.0 when not overridden. - P10 records use schema Wind Power Curve Icing P10 and label Icing_reference_p10; P90 records use schema Wind Power Curve Icing P90 and label Icing_reference_p90.

3. Data Filtering (Task 19)

Objective: Ice-free, normal production operation only.

Filter Criteria Why Impact
Operation State pitch_control (3) + torque_control (4) from OperationStateComposite.10min Normal production modes only ~5-15%
Operation Category Category 0 (normal operation) Excludes manual/maintenance/test ~1-5%
Temperature AmbientTemperature.10min between 3 degC and 40 degC, inclusive Critical: 3 degC ensures ice-free baseline. 40 degC excludes thermal issues ~20-40% (cold sites)

Implementation: The code applies state, category, and temperature together in one boolean mask.

Note: Step 6_2 does not read derate or curtailment flag columns. Derated/curtailed points are excluded only insofar as the consolidated operation category is not 0.

4. Binning

Implementation: _create_aligned_bins() uses np.arange(bin_start, bin_end, bin_size), where bin_start = floor(min_windspeed / bin_size) * bin_size and bin_end = ceil(max_windspeed / bin_size) * bin_size + bin_size.

Default: Algorithm default is 1.0 m/s. Pipeline Step 6_2 overrides this with 0.5 m/s.

X values: Left bin edge, rounded according to bin size precision.

Alternatives rejected: Fixed count (variable width), quantile-based (data-dependent)

5. Aggregation

Per-bin (single groupby): P10, P90, mean, std, count, CV (std/mean)

P10/P90 Rationale: Non-parametric, robust to outliers, define performance boundaries. Task 19 standard (P5/P95 too extreme, P25/P75 too narrow, mean+/-std assumes Gaussian).

CV Filtering (Task 19): CV > 0.7 (default) flags scattered/unreliable bins (turbulence, mixed modes, sensor issues). Interpolate or exclude.

6. Interpolation

Method: For bins where cv > cv_threshold, P10, P90, and mean are temporarily set to NaN and filled with interpolate(method="linear", limit_direction="both", limit=2) when at least two non-excluded bins exist.

Quality Safeguard: - Filled gaps: curve generated OK - Remaining NaN in P10, P90, or mean after interpolation: Entire turbine excluded

Rationale: All-or-nothing ensures complete, reliable curves for icing detection. Incomplete curves = misleading results.

6.1 Downstream Icing Detection

Step 8_7 (Step 8_7 Wind Icing Detection.py) loads only P10 icing reference curves (Wind Power Curve Icing P10) and runs WindIcingDetection.

Detection inputs are consolidated turbine data plus mandatory derate and curtailment flags from WIND_WTG_DERATE_CURTAILMENT_TABLE (fact_wtg_derate_curtailment_10m).

WindIcingDetection flags icing when filtered production points are below P10 * adaptive_threshold and AmbientTemperature.10min < 3.0, then keeps only sequences with at least 3 consecutive points. Defaults are min_uncertainty=0.03, max_uncertainty=0.15, slope_parameter=6.0, cut_in_threshold=0.05, and rated_power_fraction_threshold=0.98.

Detection writes WIND_WTG_ICING_TABLE (fact_wtg_icing_10m) with IcingFlag, IcingPowerLosses.10m, and IcingEnergyLosses.10m.

7. Code Quality

  • _create_power_curve() helper (DRY)
  • _interpolate_excluded_bins() with safeguards
  • Logging for skipped turbines, generation counts, and warnings when interpolation leaves gaps

8. Future

Parallel processing, adaptive binning, statistical outlier removal, seasonal curves, confidence intervals, real-time updates. Backward compatibility required.

9. Summary

Balances simplicity, performance, flexibility, Task 19 compliance. Prioritizes correctness, maintainability, transparency.

10. References

IEA Wind Task 19: Ice Loss Method v2.2.2 (BSD-3-Clause)

Standards: IEC 61400-12-1, IEA Ice Classification

Adaptation: bazeanalytics framework (BaseAlgorithm, wind_schema, WindPowerCurve, type annotations). Pipeline Step 6_2 implements the reference-curve generation part of the icing workflow.

Disclaimer: Independent implementation; views not necessarily IEA Task 19/IEA.