Clamp EMOS calibrated mu to observed max and add tests
This commit is contained in:
@@ -378,6 +378,10 @@ def apply_probability_calibration(
|
||||
blend_alpha_mu = max(0.0, min(1.0, _coalesce_float(blending_cfg.get("alpha_mu"), 1.0)))
|
||||
blend_alpha_sigma = max(0.0, min(1.0, _coalesce_float(blending_cfg.get("alpha_sigma"), 1.0)))
|
||||
calibrated_mu = _blend_value(raw_mu, calibrated_mu, blend_alpha_mu)
|
||||
if max_so_far is not None:
|
||||
observed_floor = _sf(max_so_far)
|
||||
if observed_floor is not None and calibrated_mu < observed_floor:
|
||||
calibrated_mu = observed_floor
|
||||
calibrated_sigma = max(0.1, _blend_value(raw_sigma, calibrated_sigma, blend_alpha_sigma))
|
||||
calibrated_sigma = _clamp_sigma(raw_sigma, calibrated_sigma, sigma_constraints)
|
||||
calibrated_distribution, calibrated_sorted = _bucket_probabilities(
|
||||
|
||||
@@ -132,6 +132,37 @@ def test_primary_mode_switches_to_calibrated_distribution(tmp_path):
|
||||
assert result["distribution"][0]["value"] >= 10
|
||||
|
||||
|
||||
def test_primary_mode_respects_observed_max_floor(tmp_path):
|
||||
calibration_path = _write_calibration(tmp_path)
|
||||
features = build_probability_features(
|
||||
city_name="ankara",
|
||||
raw_mu=32.0,
|
||||
raw_sigma=1.0,
|
||||
deb_prediction=32.0,
|
||||
ens_data={"median": 31.5, "p10": 30.0, "p90": 34.0},
|
||||
current_forecasts={"Open-Meteo": 32.0, "MGM": 31.8},
|
||||
max_so_far=33.0,
|
||||
peak_status="in_window",
|
||||
local_hour_frac=14.0,
|
||||
)
|
||||
|
||||
result = apply_probability_calibration(
|
||||
city_name="ankara",
|
||||
temp_symbol="°C",
|
||||
raw_mu=32.0,
|
||||
raw_sigma=1.0,
|
||||
max_so_far=33.0,
|
||||
legacy_distribution=[{"value": 33, "range": "[32.5~33.5)", "probability": 0.7}],
|
||||
features=features,
|
||||
calibration_path=str(calibration_path),
|
||||
mode=ENGINE_MODE_EMOS_PRIMARY,
|
||||
)
|
||||
|
||||
assert result["engine"] == "emos"
|
||||
assert result["calibrated_mu"] >= 33.0
|
||||
assert all(row["value"] >= 33 for row in result["distribution"])
|
||||
|
||||
|
||||
def test_fit_calibration_returns_metrics():
|
||||
samples = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user