feat(forecast): Rust forecast crate, bit-for-bit with the Python serving path
CI / Test suite (push) Successful in 1m2s
CI / Format & lint (push) Successful in 22s
Rust / fmt, clippy, test, build (push) Successful in 9m53s
Security / Dependency vulnerabilities (push) Successful in 1m52s
Security / Static analysis (push) Successful in 20s
Security / License report (push) Successful in 1m41s
CI / Test suite (push) Successful in 1m2s
CI / Format & lint (push) Successful in 22s
Rust / fmt, clippy, test, build (push) Successful in 9m53s
Security / Dependency vulnerabilities (push) Successful in 1m52s
Security / Static analysis (push) Successful in 20s
Security / License report (push) Successful in 1m41s
Phase 2a of docs/RUST_REWRITE.md. rust/forecast (ping-forecast) ports the serving half of src/ml: the HII mirror gap fill, the hourly grid, every feature (pandas' Kahan rolling sums included), the Mae Ngat dam frame, HistGradientBoosting tree inference, the heuristic fallback, stale-threshold handling and the P.1 flood-stage probabilities. Hand-over from Python (src/ml/export.py): - models/flood_<station>.json.gz next to each joblib bundle; train_all() writes it, retrain.sh promotes it, `python -m src.ml.export` exports existing ones. - rust/forecast/flood_config.json: thresholds, stages, leads and notify constants, compiled in. tests/test_model_export.py fails while it differs from the Python source. Parity (rust/forecast/tests/parity.rs, fixtures from testdata/gen_forecast_fixtures.py on the production code path): four scenarios incl. the 2024 flood with RID lagging behind HII. Merged readings, all features and all levels identical; with all 15 local models 377/384 probabilities bit-identical, the rest within 2 ulp (exp). Python refactor without behaviour change: predict.forecasts_from_long, and get_latest_forecasts/load_latest/serving_frame take now/rain for reproducible comparisons; the HII query orders its rows.
This commit is contained in:
1 parent
6d4beae65a
commit
5c4f464383
31 files changed
+2889
-29
No files matched your search
@@ -0,0 +1,348 @@
|
||||
{
|
||||
"thresholds": {
|
||||
"*": [
|
||||
3.0,
|
||||
4.5
|
||||
],
|
||||
"P.1": [
|
||||
3.7,
|
||||
4.2
|
||||
],
|
||||
"P.103": [
|
||||
5.95,
|
||||
6.75
|
||||
],
|
||||
"P.20": [
|
||||
2.35,
|
||||
2.8
|
||||
],
|
||||
"P.21": [
|
||||
3.2,
|
||||
3.6
|
||||
],
|
||||
"P.4A": [
|
||||
3.4,
|
||||
3.9
|
||||
],
|
||||
"P.5": [
|
||||
4.55,
|
||||
4.95
|
||||
],
|
||||
"P.67": [
|
||||
2.45,
|
||||
2.9
|
||||
],
|
||||
"P.75": [
|
||||
3.2,
|
||||
3.65
|
||||
],
|
||||
"P.76": [
|
||||
5.35,
|
||||
5.45
|
||||
],
|
||||
"P.77": [
|
||||
4.3,
|
||||
4.9
|
||||
],
|
||||
"P.81": [
|
||||
5.15,
|
||||
6.3
|
||||
],
|
||||
"P.82": [
|
||||
3.4,
|
||||
3.75
|
||||
],
|
||||
"P.84": [
|
||||
3.45,
|
||||
3.9
|
||||
],
|
||||
"P.85": [
|
||||
2.9,
|
||||
3.35
|
||||
],
|
||||
"P.87": [
|
||||
3.75,
|
||||
4.05
|
||||
],
|
||||
"P.92": [
|
||||
2.95,
|
||||
3.6
|
||||
]
|
||||
},
|
||||
"flood_stages": {
|
||||
"P.1": [
|
||||
{
|
||||
"stage": 1,
|
||||
"level": 3.7,
|
||||
"discharge_cms": 405.0
|
||||
},
|
||||
{
|
||||
"stage": 2,
|
||||
"level": 3.9,
|
||||
"discharge_cms": 438.0
|
||||
},
|
||||
{
|
||||
"stage": 3,
|
||||
"level": 4.0,
|
||||
"discharge_cms": 458.0
|
||||
},
|
||||
{
|
||||
"stage": 4,
|
||||
"level": 4.1,
|
||||
"discharge_cms": 478.0
|
||||
},
|
||||
{
|
||||
"stage": 5,
|
||||
"level": 4.2,
|
||||
"discharge_cms": 493.0
|
||||
},
|
||||
{
|
||||
"stage": 6,
|
||||
"level": 4.3,
|
||||
"discharge_cms": 508.0
|
||||
},
|
||||
{
|
||||
"stage": 7,
|
||||
"level": 4.6,
|
||||
"discharge_cms": 558.0
|
||||
}
|
||||
]
|
||||
},
|
||||
"upstream_leads": {
|
||||
"P.1": [
|
||||
[
|
||||
"P.103",
|
||||
1
|
||||
],
|
||||
[
|
||||
"P.67",
|
||||
7
|
||||
],
|
||||
[
|
||||
"P.21",
|
||||
9
|
||||
],
|
||||
[
|
||||
"P.75",
|
||||
12
|
||||
],
|
||||
[
|
||||
"P.4A",
|
||||
12
|
||||
],
|
||||
[
|
||||
"P.92",
|
||||
15
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
17
|
||||
]
|
||||
],
|
||||
"P.103": [
|
||||
[
|
||||
"P.67",
|
||||
6
|
||||
],
|
||||
[
|
||||
"P.21",
|
||||
8
|
||||
],
|
||||
[
|
||||
"P.75",
|
||||
11
|
||||
],
|
||||
[
|
||||
"P.4A",
|
||||
11
|
||||
],
|
||||
[
|
||||
"P.92",
|
||||
14
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
16
|
||||
]
|
||||
],
|
||||
"P.21": [
|
||||
[
|
||||
"P.67",
|
||||
1
|
||||
],
|
||||
[
|
||||
"P.75",
|
||||
3
|
||||
],
|
||||
[
|
||||
"P.4A",
|
||||
3
|
||||
],
|
||||
[
|
||||
"P.92",
|
||||
6
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
8
|
||||
]
|
||||
],
|
||||
"P.67": [
|
||||
[
|
||||
"P.75",
|
||||
5
|
||||
],
|
||||
[
|
||||
"P.4A",
|
||||
5
|
||||
],
|
||||
[
|
||||
"P.92",
|
||||
8
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
10
|
||||
]
|
||||
],
|
||||
"P.75": [
|
||||
[
|
||||
"P.92",
|
||||
3
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
5
|
||||
]
|
||||
],
|
||||
"P.4A": [
|
||||
[
|
||||
"P.92",
|
||||
3
|
||||
],
|
||||
[
|
||||
"P.20",
|
||||
5
|
||||
]
|
||||
],
|
||||
"P.92": [
|
||||
[
|
||||
"P.20",
|
||||
2
|
||||
]
|
||||
],
|
||||
"P.20": [],
|
||||
"P.5": [
|
||||
[
|
||||
"P.1",
|
||||
12
|
||||
],
|
||||
[
|
||||
"P.103",
|
||||
13
|
||||
]
|
||||
],
|
||||
"P.81": [
|
||||
[
|
||||
"P.1",
|
||||
4
|
||||
],
|
||||
[
|
||||
"P.103",
|
||||
5
|
||||
]
|
||||
],
|
||||
"P.82": [],
|
||||
"P.84": [],
|
||||
"P.87": [],
|
||||
"P.77": [],
|
||||
"P.85": [],
|
||||
"P.76": []
|
||||
},
|
||||
"dam_stations": [
|
||||
"P.1",
|
||||
"P.103",
|
||||
"P.21",
|
||||
"P.5",
|
||||
"P.67",
|
||||
"P.81"
|
||||
],
|
||||
"monsoon_months": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
],
|
||||
"ffill_limit_h": 3,
|
||||
"basin_anchor": "P.1",
|
||||
"forward_rain_h": 24,
|
||||
"horizons": [
|
||||
6,
|
||||
12,
|
||||
24
|
||||
],
|
||||
"stale_after_h": 6.0,
|
||||
"heuristic_sigma": 0.3,
|
||||
"heuristic_version": "heuristic-v1",
|
||||
"latest_window_h": 336,
|
||||
"hii_fill_stations": [
|
||||
"P.1",
|
||||
"P.103",
|
||||
"P.20",
|
||||
"P.4A",
|
||||
"P.67",
|
||||
"P.75",
|
||||
"P.82",
|
||||
"P.84",
|
||||
"P.92",
|
||||
"P.81"
|
||||
],
|
||||
"hii_exact_mirrors": [
|
||||
"P.1",
|
||||
"P.103",
|
||||
"P.20",
|
||||
"P.4A",
|
||||
"P.67",
|
||||
"P.75",
|
||||
"P.82",
|
||||
"P.84",
|
||||
"P.92"
|
||||
],
|
||||
"hii_min_overlap_hours": 168,
|
||||
"dam": {
|
||||
"dam_id": "200103",
|
||||
"report_hour": 7,
|
||||
"ffill_limit_h": 48,
|
||||
"serving_days": 21
|
||||
},
|
||||
"notify": {
|
||||
"clear_margin_m": 0.1,
|
||||
"capacity_guard_min_pct": 60.0,
|
||||
"capacity_guard_exempt": [
|
||||
"P.1"
|
||||
],
|
||||
"outlook_on": 0.5,
|
||||
"outlook_off": 0.25,
|
||||
"outlook_horizon": 24,
|
||||
"feed_stale_after_h": 3.0,
|
||||
"station_names": {
|
||||
"P.1": "Nawarat Bridge, Chiang Mai city",
|
||||
"P.103": "Ring Road Bridge 3, Chiang Mai",
|
||||
"P.67": "Ban Tae (Mae Taeng)",
|
||||
"P.21": "Ban Rim Tai (Mae Rim)",
|
||||
"P.75": "Ban Chai Lat",
|
||||
"P.92": "Ban Muang Aut",
|
||||
"P.20": "Ban Chiang Dao",
|
||||
"P.4A": "Ban Mae Taeng",
|
||||
"P.5": "Tha Nang Bridge (downstream)",
|
||||
"P.81": "Ban Pong (downstream)",
|
||||
"P.82": "Ban Sob Win",
|
||||
"P.84": "Ban Panton",
|
||||
"P.87": "Ban Pa Sang",
|
||||
"P.77": "Ban Sop Mae Sapuat",
|
||||
"P.85": "Ban Lai Kaew",
|
||||
"P.76": "Ban Mae I Hai"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user