Archive probability snapshots and wire them into training
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from src.analysis.probability_snapshot_archive import append_probability_snapshot
|
||||
|
||||
|
||||
def test_append_probability_snapshot_writes_jsonl(tmp_path: Path):
|
||||
archive_path = tmp_path / "probability_training_snapshots.jsonl"
|
||||
|
||||
append_probability_snapshot(
|
||||
city_name="ankara",
|
||||
local_date="2026-03-20",
|
||||
observation_time="2026-03-20T12:00:00+03:00",
|
||||
temp_symbol="°C",
|
||||
raw_mu=15.2,
|
||||
raw_sigma=1.2,
|
||||
deb_prediction=15.4,
|
||||
ens_data={"p10": 14.8, "median": 15.8, "p90": 17.9},
|
||||
current_forecasts={"ECMWF": 15.8, "GFS": 14.1},
|
||||
max_so_far=15.0,
|
||||
peak_status="before",
|
||||
probabilities=[{"value": 15, "probability": 0.552}],
|
||||
shadow_probabilities=[{"value": 15, "probability": 0.324}],
|
||||
calibration_summary={
|
||||
"engine": "legacy",
|
||||
"mode": "emos_shadow",
|
||||
"calibration_version": "emos-test",
|
||||
"calibration_source": "artifacts/probability_calibration/default.json",
|
||||
"calibrated_mu": 15.1,
|
||||
"calibrated_sigma": 1.25,
|
||||
},
|
||||
archive_path=str(archive_path),
|
||||
)
|
||||
|
||||
lines = archive_path.read_text(encoding="utf-8").strip().splitlines()
|
||||
assert len(lines) == 1
|
||||
payload = json.loads(lines[0])
|
||||
assert payload["city"] == "ankara"
|
||||
assert payload["date"] == "2026-03-20"
|
||||
assert payload["raw_mu"] == 15.2
|
||||
assert payload["ensemble"]["median"] == 15.8
|
||||
assert payload["prob_snapshot"][0]["v"] == 15
|
||||
assert payload["shadow_prob_snapshot"][0]["v"] == 15
|
||||
assert payload["calibration_version"] == "emos-test"
|
||||
|
||||
|
||||
def test_append_probability_snapshot_skips_near_duplicate(tmp_path: Path):
|
||||
archive_path = tmp_path / "probability_training_snapshots.jsonl"
|
||||
kwargs = dict(
|
||||
city_name="ankara",
|
||||
local_date="2026-03-20",
|
||||
observation_time="2026-03-20T12:00:00+03:00",
|
||||
temp_symbol="°C",
|
||||
raw_mu=15.2,
|
||||
raw_sigma=1.2,
|
||||
deb_prediction=15.4,
|
||||
ens_data={"p10": 14.8, "median": 15.8, "p90": 17.9},
|
||||
current_forecasts={"ECMWF": 15.8, "GFS": 14.1},
|
||||
max_so_far=15.0,
|
||||
peak_status="before",
|
||||
probabilities=[{"value": 15, "probability": 0.552}],
|
||||
shadow_probabilities=[{"value": 15, "probability": 0.324}],
|
||||
calibration_summary={
|
||||
"engine": "legacy",
|
||||
"mode": "emos_shadow",
|
||||
"calibration_version": "emos-test",
|
||||
"calibration_source": "artifacts/probability_calibration/default.json",
|
||||
"calibrated_mu": 15.1,
|
||||
"calibrated_sigma": 1.25,
|
||||
},
|
||||
archive_path=str(archive_path),
|
||||
)
|
||||
|
||||
append_probability_snapshot(**kwargs)
|
||||
append_probability_snapshot(**kwargs)
|
||||
|
||||
lines = archive_path.read_text(encoding="utf-8").strip().splitlines()
|
||||
assert len(lines) == 1
|
||||
|
||||
|
||||
def test_append_probability_snapshot_writes_on_bucket_change(tmp_path: Path):
|
||||
archive_path = tmp_path / "probability_training_snapshots.jsonl"
|
||||
base_kwargs = dict(
|
||||
city_name="ankara",
|
||||
local_date="2026-03-20",
|
||||
observation_time="2026-03-20T12:00:00+03:00",
|
||||
temp_symbol="°C",
|
||||
raw_mu=15.2,
|
||||
raw_sigma=1.2,
|
||||
deb_prediction=15.4,
|
||||
ens_data={"p10": 14.8, "median": 15.8, "p90": 17.9},
|
||||
current_forecasts={"ECMWF": 15.8, "GFS": 14.1},
|
||||
max_so_far=15.0,
|
||||
peak_status="before",
|
||||
shadow_probabilities=[{"value": 15, "probability": 0.324}],
|
||||
calibration_summary={
|
||||
"engine": "legacy",
|
||||
"mode": "emos_shadow",
|
||||
"calibration_version": "emos-test",
|
||||
"calibration_source": "artifacts/probability_calibration/default.json",
|
||||
"calibrated_mu": 15.1,
|
||||
"calibrated_sigma": 1.25,
|
||||
},
|
||||
archive_path=str(archive_path),
|
||||
)
|
||||
|
||||
append_probability_snapshot(
|
||||
probabilities=[{"value": 15, "probability": 0.552}],
|
||||
**base_kwargs,
|
||||
)
|
||||
append_probability_snapshot(
|
||||
probabilities=[{"value": 16, "probability": 0.552}],
|
||||
**base_kwargs,
|
||||
)
|
||||
|
||||
lines = archive_path.read_text(encoding="utf-8").strip().splitlines()
|
||||
assert len(lines) == 2
|
||||
@@ -0,0 +1,45 @@
|
||||
from scripts.fit_probability_calibration import _extract_samples
|
||||
|
||||
|
||||
def test_extract_samples_prefers_snapshot_rows_for_same_city_day():
|
||||
history = {
|
||||
"ankara": {
|
||||
"2026-03-19": {
|
||||
"actual_high": 11.0,
|
||||
"mu": 10.8,
|
||||
"deb_prediction": 10.9,
|
||||
"forecasts": {"ECMWF": 10.5, "GFS": 11.2},
|
||||
"probability_features": {
|
||||
"ens_median": 10.7,
|
||||
"ensemble_spread": 0.8,
|
||||
"peak_status": "before",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
snapshot_rows = [
|
||||
{
|
||||
"city": "ankara",
|
||||
"date": "2026-03-19",
|
||||
"timestamp": "2026-03-19T12:00:00+03:00",
|
||||
"raw_mu": 11.2,
|
||||
"raw_sigma": 1.1,
|
||||
"deb_prediction": 11.0,
|
||||
"ensemble": {"p10": 10.0, "median": 11.1, "p90": 12.2},
|
||||
"multi_model": {"ECMWF": 10.5, "GFS": 11.2},
|
||||
"max_so_far": 10.9,
|
||||
"peak_status": "in_window",
|
||||
}
|
||||
]
|
||||
|
||||
samples, filled = _extract_samples(
|
||||
history,
|
||||
settlement_history={},
|
||||
snapshot_rows=snapshot_rows,
|
||||
)
|
||||
|
||||
assert filled == 0
|
||||
assert len(samples) == 1
|
||||
assert samples[0]["sample_source"] == "snapshot"
|
||||
assert samples[0]["raw_mu"] == 11.2
|
||||
assert samples[0]["peak_flag"] == 0.5
|
||||
Reference in New Issue
Block a user