From b2f15ae7d8c09069c39b795e3de3c6a97623dc25 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sun, 19 Apr 2026 14:15:46 +0800 Subject: [PATCH] Clarify intraday suppression headlines --- tests/test_country_networks.py | 32 ++++++++++++++++++++++++++++++++ web/analysis_service.py | 21 +++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/tests/test_country_networks.py b/tests/test_country_networks.py index e51d8490..cef3153f 100644 --- a/tests/test_country_networks.py +++ b/tests/test_country_networks.py @@ -312,6 +312,38 @@ def test_intraday_meteorology_suppressed_cloud_rain_case(): assert any(item["direction"] == "suppress" for item in payload["signal_contributions"]) +def test_intraday_meteorology_structural_cap_does_not_claim_taf_cloud_rain(): + payload = _build_intraday_meteorology( + { + "local_time": "11:30", + "temp_symbol": "°C", + "current": {"temp": 39.0, "max_so_far": 39.0}, + "deb": {"prediction": 40.4}, + "probabilities": {"distribution": [{"value": 42, "probability": 0.35}]}, + "peak": {"first_h": 12, "last_h": 16, "status": "before"}, + "deviation_monitor": {"direction": "cold", "severity": "strong", "current_delta": -1.4}, + "vertical_profile_signal": { + "heating_setup": "suppressed", + "suppression_risk": "medium", + "summary_zh": "边界层混合偏弱,午后上修需要后续观测确认。", + }, + "taf": { + "signal": { + "available": True, + "suppression_level": "low", + "disruption_level": "low", + "summary_zh": "TAF 在峰值窗口暂未提示明显云雨压温。", + } + }, + } + ) + + assert "结构信号压制" in payload["headline"] + assert "TAF 云雨层暂未构成主压温理由" in payload["headline"] + assert "存在云雨或结构压制" not in payload["headline"] + assert any(item["label"] == "TAF 云雨扰动" and item["direction"] == "support" for item in payload["signal_contributions"]) + + def test_intraday_meteorology_handles_sparse_observations(): payload = _build_intraday_meteorology( { diff --git a/web/analysis_service.py b/web/analysis_service.py index 908f2251..70e15f1e 100644 --- a/web/analysis_service.py +++ b/web/analysis_service.py @@ -1320,6 +1320,11 @@ def _build_intraday_meteorology(data: Dict[str, Any]) -> Dict[str, Any]: taf_suppression = str(taf_signal.get("suppression_level") or "").lower() taf_disruption = str(taf_signal.get("disruption_level") or "").lower() + taf_has_cloud_rain_cap = taf_suppression in {"medium", "high"} or taf_disruption in { + "medium", + "high", + } + structural_cap = False if taf_signal.get("available") or taf_suppression: available_layers += 1 if taf_suppression == "high" or taf_disruption == "high": @@ -1405,8 +1410,20 @@ def _build_intraday_meteorology(data: Dict[str, Any]) -> Dict[str, Any]: headline_en = "The peak window has passed; the read now shifts toward confirming the final high rather than chasing further upside." confidence = "high" if available_layers >= 2 else "medium" elif suppress_score >= support_score + 2: - headline = "峰值存在云雨或结构压制,当前更偏防守高温上修。" - headline_en = "Cloud/rain or structural suppression is capping the peak; defend against aggressive high-temperature upside for now." + structural_cap = any( + signal.get("direction") == "suppress" + and signal.get("label") in {"边界层结构", "站网对比", "日内节奏"} + for signal in signals + ) + if taf_has_cloud_rain_cap and structural_cap: + headline = "峰值同时存在 TAF 云雨扰动和结构压制,当前更偏防守高温上修。" + headline_en = "Both TAF cloud/rain disruption and structural signals are capping the peak; defend against aggressive high-temperature upside for now." + elif taf_has_cloud_rain_cap: + headline = "TAF 提示峰值窗口有云雨扰动,当前更偏防守高温上修。" + headline_en = "TAF flags cloud/rain disruption near the peak window; defend against aggressive high-temperature upside for now." + else: + headline = "峰值主要受结构信号压制,TAF 云雨层暂未构成主压温理由。" + headline_en = "The peak is mainly capped by structural signals; TAF cloud/rain is not the primary suppression reason for now." confidence = "high" if available_layers >= 3 else "medium" elif support_score >= suppress_score + 2: headline = "峰值仍有上修空间,后续重点看峰值窗口内报文能否继续抬升。"