新增爆管位置检测模块及相关API接口
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from app.algorithms.burst_location import run_burst_location
|
||||
from app.services.tjnetwork import dump_inp
|
||||
|
||||
SeriesInput = pd.Series | dict[str, Any] | list[dict[str, Any]]
|
||||
|
||||
|
||||
def _normalize_series(data: SeriesInput, field_name: str) -> pd.Series:
|
||||
if isinstance(data, pd.Series):
|
||||
series = data.copy()
|
||||
elif isinstance(data, dict):
|
||||
series = pd.Series(data, dtype=float)
|
||||
elif isinstance(data, list):
|
||||
if len(data) == 0:
|
||||
return pd.Series(dtype=float)
|
||||
frame = pd.DataFrame(data)
|
||||
if not {"id", "value"}.issubset(frame.columns):
|
||||
raise ValueError(f"{field_name} list item must include 'id' and 'value'.")
|
||||
series = pd.Series(
|
||||
frame["value"].values, index=frame["id"].astype(str).values, dtype=float
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unsupported data format for {field_name}.")
|
||||
|
||||
series.index = series.index.map(str)
|
||||
return pd.to_numeric(series, errors="raise")
|
||||
|
||||
|
||||
def run_burst_location_by_network(
|
||||
*,
|
||||
network: str,
|
||||
pressure_scada_ids: list[str],
|
||||
burst_pressure: SeriesInput,
|
||||
normal_pressure: SeriesInput,
|
||||
burst_leakage: float,
|
||||
flow_scada_ids: list[str] | None = None,
|
||||
burst_flow: SeriesInput | None = None,
|
||||
normal_flow: SeriesInput | None = None,
|
||||
min_dpressure: float = 2.0,
|
||||
basic_pressure: float = 10.0,
|
||||
) -> dict[str, Any]:
|
||||
if not network:
|
||||
raise ValueError("network is required.")
|
||||
|
||||
tmp_filename = f"burst_location_{network}_{uuid4().hex}.inp"
|
||||
inp_path = Path.cwd() / tmp_filename
|
||||
|
||||
try:
|
||||
dump_inp(network, tmp_filename)
|
||||
|
||||
burst_pressure_series = _normalize_series(burst_pressure, "burst_pressure")
|
||||
normal_pressure_series = _normalize_series(normal_pressure, "normal_pressure")
|
||||
burst_flow_series = (
|
||||
_normalize_series(burst_flow, "burst_flow") if burst_flow is not None else None
|
||||
)
|
||||
normal_flow_series = (
|
||||
_normalize_series(normal_flow, "normal_flow")
|
||||
if normal_flow is not None
|
||||
else None
|
||||
)
|
||||
|
||||
return run_burst_location(
|
||||
wn_inp_path=str(inp_path),
|
||||
pressure_scada_ids=pressure_scada_ids,
|
||||
burst_pressure=burst_pressure_series,
|
||||
normal_pressure=normal_pressure_series,
|
||||
burst_leakage=burst_leakage,
|
||||
flow_scada_ids=flow_scada_ids,
|
||||
burst_flow=burst_flow_series,
|
||||
normal_flow=normal_flow_series,
|
||||
min_dpressure=min_dpressure,
|
||||
basic_pressure=basic_pressure,
|
||||
)
|
||||
finally:
|
||||
if inp_path.exists():
|
||||
inp_path.unlink()
|
||||
Reference in New Issue
Block a user