Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9d8737b
R1: shared northing step, fast DP norther, and the northing fault fix…
aclerc Sep 2, 2026
f8772b3
R1: fix the record-edge false changepoint, add northing plots
aclerc Sep 2, 2026
4a640a9
R1: fix the farm-wide outage artefact -- it was the first pass
aclerc Sep 2, 2026
1f4c689
R1: apply the first-pass fix to v0 too, and clear the scar tissue
aclerc Sep 2, 2026
0539cb3
Add a Greenbyte source adapter (Kelmarsh, Penmanshiel) and road-test …
aclerc Sep 3, 2026
97c86bb
Land the northing subset-consistency study as a driver
aclerc Sep 3, 2026
eeb4a19
R1: stop veer normalisation being defeated by its own de-stepping
aclerc Sep 3, 2026
d96d6dc
Stop tracking development-phase docs (docs/superpowers, CLAUDE.md)
aclerc Sep 3, 2026
240bcf3
R1: north the study path too, and turn the direction feature on by de…
aclerc Sep 3, 2026
9219d92
R1: address PR 138 review -- circular_math tests and typing, src comm…
aclerc Sep 3, 2026
4fbbc87
R1: address Copilot review on PR 138
aclerc Sep 3, 2026
cbe3297
Mark the heavy integration tests slow so the fast gate stays quick
aclerc Sep 3, 2026
1fb32dd
R1: add the natural-case northing probe
aclerc Sep 3, 2026
7e1c77a
R1: the natural probe's minimum reference set needs three devices
aclerc Sep 3, 2026
323d0a9
Re-record the toggle power_model benchmark for the direction feature
aclerc Sep 3, 2026
7baed4c
Define R5 (northing refinement) and record how to update the frozen b…
aclerc Sep 3, 2026
d9072b3
Re-record the power_model benchmark for the direction feature
aclerc Sep 3, 2026
31a168a
Mark R1 done, and close the example re-runs as redundant
aclerc Sep 4, 2026
0cc2792
Placebo discovers its own northing, and the shared step draws its plots
aclerc Sep 4, 2026
55111d6
Record that the campaigns test v1 wind-up, not a field of methods
aclerc Sep 4, 2026
79edcbe
Northing needs a real anchor, and writes the table it discovered
aclerc Sep 4, 2026
47da88e
CF9: record the placebo results with power_model after R1
aclerc Sep 4, 2026
8f87686
Drop the unused northing diagnostics, and put v1 in the coverage gate
aclerc Sep 4, 2026
dcf78ee
A sector level must belong to the row that reads it
aclerc Sep 4, 2026
56eb667
Say when the farm reference falls back, and stop hardcoding the outag…
aclerc Sep 4, 2026
7115087
tidy docstring
aclerc Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ tests/test_data/smarteole/* filter=lfs diff=lfs merge=lfs -text
tests/test_data/wedowind/Turbine_Upgrade_Dataset.zip filter=lfs diff=lfs merge=lfs -text
tests/test_data/hot/scada/* filter=lfs diff=lfs merge=lfs -text
tests/test_data/hot/reanalysis_data/ERA5T_57.50N_-3.25E_100m_1hr_20241231.parquet filter=lfs diff=lfs merge=lfs -text
tests/test_data/hot/northing/*.parquet filter=lfs diff=lfs merge=lfs -text
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ output/
# matplotlib testing
**/result_images/
/docs/v1/extra_docs/

# local working documents, not part of the published project
/CLAUDE.md
/docs/superpowers/
7 changes: 7 additions & 0 deletions benchmarking/baselines/example_prepost_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from benchmarking.baselines.v0_binned import V0BinnedMethod
from benchmarking.harness import Method, StudyConfig, leaderboard, plot_campaign_curves, score_study
from benchmarking.harness.example_hot_study import OracleMethod
from benchmarking.harness.northing import era5_direction
from benchmarking.synthetic import HOT_COLUMNS, HOT_RATED_POWER_KW
from benchmarking.synthetic.make_example_datasets import example_profiles
from benchmarking.synthetic.sources.hill_of_towie import load_hot_scada
Expand Down Expand Up @@ -116,6 +117,11 @@ def run_prepost_study(
out_dir.mkdir(parents=True, exist_ok=True)

context = build_hot_v0_context(data_dir=data_dir, wtg_names=DEFAULT_TURBINE_SUBSET)
# The shared northing step runs per replicate, so every method sees a north-calibrated
# direction that wind-up discovered for itself rather than one supplied to it.
era5_wd = era5_direction(
context.reanalysis_datasets[0].data, pd.DatetimeIndex(base_scada.index.unique()).sort_values()
)
scratch_dir = out_dir / "windup_runs"

all_results = []
Expand Down Expand Up @@ -159,6 +165,7 @@ def run_prepost_study(
methods=methods,
study=study,
profile_name=profile_name,
era5_wd=era5_wd,
on_method_complete=partial(save_per_method_curve, out_dir, profile_name),
)
summary = leaderboard(results)
Expand Down
7 changes: 7 additions & 0 deletions benchmarking/baselines/example_toggle_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from benchmarking.baselines.v0_binned import V0BinnedMethod
from benchmarking.harness import Method, StudyConfig, leaderboard, plot_campaign_curves, score_study
from benchmarking.harness.example_hot_study import OracleMethod
from benchmarking.harness.northing import era5_direction
from benchmarking.synthetic import HOT_COLUMNS, HOT_RATED_POWER_KW, ConstantCpChange
from benchmarking.synthetic.sources.hill_of_towie import load_hot_scada

Expand Down Expand Up @@ -89,6 +90,11 @@ def run_toggle_study(
out_dir.mkdir(parents=True, exist_ok=True)

context = build_hot_v0_context(data_dir=data_dir, wtg_names=DEFAULT_TURBINE_SUBSET)
# The shared northing step runs per replicate, so every method sees a north-calibrated
# direction that wind-up discovered for itself rather than one supplied to it.
era5_wd = era5_direction(
context.reanalysis_datasets[0].data, pd.DatetimeIndex(base_scada.index.unique()).sort_values()
)
scratch_dir = out_dir / "windup_runs"

all_results = []
Expand Down Expand Up @@ -127,6 +133,7 @@ def run_toggle_study(
methods=methods,
study=study,
profile_name=profile_name,
era5_wd=era5_wd,
on_method_complete=partial(save_per_method_curve, out_dir, profile_name),
)
summary = leaderboard(results)
Expand Down
28 changes: 21 additions & 7 deletions benchmarking/baselines/inspect_prepost_hard_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
MIN_PRE_MONTHS,
default_output_root,
)
from benchmarking.baselines.hot_context import build_hot_v0_context
from benchmarking.baselines.hot_context import HotV0Context, build_hot_v0_context
from benchmarking.baselines.naive_ratio import NaiveRatioMethod
from benchmarking.baselines.overnight_common import start_overnight_run
from benchmarking.baselines.overnight_profiles import overnight_profiles
Expand All @@ -61,6 +61,7 @@
treated_activity_mask,
window_row_mask,
)
from benchmarking.harness.northing import era5_direction
from benchmarking.synthetic import HOT_COLUMNS, HOT_RATED_POWER_KW
from benchmarking.synthetic.sources.hill_of_towie import load_hot_scada

Expand Down Expand Up @@ -110,11 +111,17 @@ def _select_replicate(replicates: list[Replicate], test_wtg: str) -> Replicate:


def _pin_case(
scada_df: pd.DataFrame, *, study: StudyConfig, profile_name: str, test_wtg: str, campaign_months: int
scada_df: pd.DataFrame,
*,
study: StudyConfig,
profile_name: str,
test_wtg: str,
campaign_months: int,
era5_wd: pd.Series,
) -> tuple[Replicate, MethodInput, float, CampaignWindow]:
"""Build the pinned replicate, its shared ``MethodInput``, the ground-truth uplift, and the window."""
profile = overnight_profiles()[profile_name]
replicates = build_replicates(scada_df, profile=profile, study=study)
replicates = build_replicates(scada_df, profile=profile, study=study, era5_wd=era5_wd)
rep = _select_replicate(replicates, test_wtg)

windows = campaign_windows(
Expand Down Expand Up @@ -169,13 +176,12 @@ def _power_model(out_dir: Path, era5_hourly_df: pd.DataFrame, *, save_plots: boo
)


def _build_methods(out_dir: Path, *, include_v0: bool) -> list[Method]:
def _build_methods(out_dir: Path, *, context: HotV0Context, include_v0: bool) -> list[Method]:
"""Return the methods to inspect, each writing diagnostics (plots on) into its own subfolder.

One ``power_model`` run folder: with conditional uplift on (the default) it carries the overall
diagnostics plus the conditional CSVs (``conditional/``) and the step-7 implied-shrinkage plot.
"""
context = build_hot_v0_context(wtg_names=DEFAULT_TURBINE_SUBSET)
era5 = context.reanalysis_datasets[0].data
methods: list[Method] = [
NaiveRatioMethod(
Expand Down Expand Up @@ -293,10 +299,18 @@ def inspect_prepost_hard_case(
wtg_names=DEFAULT_TURBINE_SUBSET,
)

context = build_hot_v0_context(wtg_names=DEFAULT_TURBINE_SUBSET)
rep, mi, truth, window = _pin_case(
scada_df, study=study, profile_name=profile_name, test_wtg=test_wtg, campaign_months=campaign_months
scada_df,
study=study,
profile_name=profile_name,
test_wtg=test_wtg,
campaign_months=campaign_months,
era5_wd=era5_direction(
context.reanalysis_datasets[0].data, pd.DatetimeIndex(scada_df.index.unique()).sort_values()
),
)
methods = _build_methods(out_dir, include_v0=include_v0)
methods = _build_methods(out_dir, context=context, include_v0=include_v0)
summary, outputs = _run_methods(methods, mi=mi, truth=truth)

_plot_conditional_uplift(
Expand Down
13 changes: 13 additions & 0 deletions benchmarking/baselines/inspect_wake_steering_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
condition_bins,
plot_conditional_uplift,
)
from benchmarking.harness.northing import era5_direction, north_scada
from benchmarking.synthetic import (
HOT_COLUMNS,
HOT_RATED_POWER_KW,
Expand Down Expand Up @@ -438,6 +439,18 @@ def inspect_wake_steering_case(
era5 = context.reanalysis_datasets[0].data

full_dataset, steering = _build_dataset(scada_df, metadata_df)
# The shared northing step, discovering as it does on every other path -- the methods read
# a north-calibrated direction wind-up worked out, not the table the injection was gated on.
full_dataset = replace(
full_dataset,
synthetic_df=north_scada(
full_dataset.synthetic_df,
columns=HOT_COLUMNS,
north_offsets=None,
rated_power_kw=HOT_RATED_POWER_KW,
era5_wd=era5_direction(era5, pd.DatetimeIndex(full_dataset.synthetic_df.index.unique()).sort_values()),
),
Comment thread
aclerc marked this conversation as resolved.
)
schedule = ToggleSchedule(period=TOGGLE_PERIOD, start=TOGGLE_START)

nadir, half_width = _pair_sector(steering, margin_deg=wd_margin_deg)
Expand Down
168 changes: 0 additions & 168 deletions benchmarking/baselines/old/inspect_short_campaigns.py

This file was deleted.

Loading