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.
349 lines
3.7 KiB
JSON
349 lines
3.7 KiB
JSON
{
|
|
"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"
|
|
}
|
|
}
|
|
}
|