Download core/flood_core/baselines.py from bpHigh/FloodGate: direct link, hf CLI and curl.
- Browser
- Download file 3.36 kB
-
https://huggingface.co/spaces/bpHigh/FloodGate/resolve/main/core/flood_core/baselines.py
- Command line
-
hf download hf://spaces/bpHigh/FloodGate/core/flood_core/baselines.py
-
curl -L -o baselines.py https://huggingface.co/spaces/bpHigh/FloodGate/resolve/main/core/flood_core/baselines.py
3.36 kB
| """Lazy policies and the Corps' own releases, for the references and the board. | |
| hold keep every dam at the release of the step before the window | |
| pass release what comes in (no storage used), as fast as the ramp allows, within the release limits | |
| corps the Nashville District's real releases in the window (tier `real` only; other tiers change the water) | |
| """ | |
| from __future__ import annotations | |
| def hold(task: dict) -> dict[str, list[float]]: | |
| return {d["id"]: [min(max(d["release_prev_cfs"], d["min_release_cfs"]), d["max_release_cfs"])] * task["steps"] | |
| for d in task["dams"]} | |
| def pass_inflow(task: dict) -> dict[str, list[float]]: | |
| out = {} | |
| for d in task["dams"]: | |
| cur, rs = d["release_prev_cfs"], [] | |
| for v in d["inflow_cfs"]: | |
| tgt = min(max(v, d["min_release_cfs"]), d["max_release_cfs"]) | |
| cur = cur + max(-d["ramp_cfs_per_step"], min(d["ramp_cfs_per_step"], tgt - cur)) | |
| rs.append(cur) | |
| out[d["id"]] = rs | |
| return out | |
| def corps(task: dict) -> dict[str, list[float]] | None: | |
| if task["tier"] != "real": | |
| return None | |
| return {d["id"]: list(d["record_release_cfs"]) for d in task["dams"]} | |
| POLICIES = {"hold": hold, "pass": pass_inflow} | |
| def rule(task: dict) -> dict[str, list[float]]: | |
| """A standard flood-control rule, step by step: release as much as each lake can (to empty its flood pool), but | |
| never push a downstream gauge above its action flow when the water arrives (or above where it already is, when | |
| local runoff alone exceeds it); spill protection first: release more if the lake would overtop.""" | |
| from .basin import AF_PER_CFS_STEP, routing_weights | |
| H, T = task["steps"], task["tail_steps"] | |
| q = {p["id"]: list(p["base_cfs"]) for p in task["points"]} | |
| thr = {p["id"]: p["thresholds"]["action"] for p in task["points"]} | |
| rel = {d["id"]: [] for d in task["dams"]} | |
| stor = {d["id"]: d["storage0_af"] for d in task["dams"]} | |
| order = sorted(task["dams"], key=lambda d: -max(task["lags_h"][d["id"]].values())) | |
| for t in range(H): | |
| for d in order: | |
| k = d["id"] | |
| prev = rel[k][-1] if rel[k] else d["release_prev_cfs"] | |
| lo = max(d["min_release_cfs"], prev - d["ramp_cfs_per_step"]) | |
| hi = min(d["max_release_cfs"], prev + d["ramp_cfs_per_step"]) | |
| # lake target: down to the bottom of the flood pool | |
| want = d["inflow_cfs"][t] + max(0.0, stor[k] - d["bottom_of_flood_af"]) / AF_PER_CFS_STEP | |
| room = hi | |
| for c, lag in task["lags_h"][k].items(): | |
| for i, wi in enumerate(routing_weights(lag)): | |
| if t + i < H + T and wi > 0: | |
| cap = max(thr[c], q[c][t + i]) - q[c][t + i] | |
| room = min(room, cap / wi) | |
| r = max(lo, min(hi, want, room)) | |
| # never overtop | |
| must = d["inflow_cfs"][t] - (d["top_of_flood_af"] - stor[k]) / AF_PER_CFS_STEP | |
| r = max(r, min(hi, must)) | |
| rel[k].append(r) | |
| stor[k] += (d["inflow_cfs"][t] - r) * AF_PER_CFS_STEP | |
| for c, lag in task["lags_h"][k].items(): | |
| for i, wi in enumerate(routing_weights(lag)): | |
| if t + i < H + T: | |
| q[c][t + i] += wi * r | |
| return rel | |
| POLICIES["rule"] = rule | |