sim window save/load
This commit is contained in:
78
BEdit/src/bedit/core/simulation/results.py
Normal file
78
BEdit/src/bedit/core/simulation/results.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import json
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
RESULTS_FORMAT = "bedit-simulation-results"
|
||||
RESULTS_VERSION = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class SimulationTrace:
|
||||
"""One plottable series; samples can be filled by a future result importer."""
|
||||
|
||||
name: str
|
||||
x_values: list[float] = field(default_factory=list)
|
||||
y_values: list[float] = field(default_factory=list)
|
||||
x_label: str = "time"
|
||||
y_label: str = ""
|
||||
unit: str = ""
|
||||
properties: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
class SimulationResults:
|
||||
"""Serializable state displayed by the standalone simulation window."""
|
||||
|
||||
model_name: str = ""
|
||||
status: dict[str, Any] = field(default_factory=dict)
|
||||
messages: list[dict[str, str]] = field(default_factory=list)
|
||||
traces: list[SimulationTrace] = field(default_factory=list)
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"format": RESULTS_FORMAT,
|
||||
"version": RESULTS_VERSION,
|
||||
"modelName": self.model_name,
|
||||
"status": dict(self.status),
|
||||
"messages": [dict(message) for message in self.messages],
|
||||
"traces": [asdict(trace) for trace in self.traces],
|
||||
"metadata": dict(self.metadata),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict[str, Any]) -> "SimulationResults":
|
||||
if data.get("format") != RESULTS_FORMAT:
|
||||
raise ValueError("Not a BEdit simulation-results file")
|
||||
if data.get("version") != RESULTS_VERSION:
|
||||
raise ValueError(f"Unsupported simulation-results version: {data.get('version')!r}")
|
||||
try:
|
||||
traces = [SimulationTrace(**trace) for trace in data.get("traces", [])]
|
||||
return cls(
|
||||
model_name=str(data.get("modelName", "")),
|
||||
status=dict(data.get("status", {})),
|
||||
messages=[dict(message) for message in data.get("messages", [])],
|
||||
traces=traces,
|
||||
metadata=dict(data.get("metadata", {})),
|
||||
)
|
||||
except (TypeError, ValueError) as error:
|
||||
raise ValueError("Malformed simulation-results data") from error
|
||||
|
||||
|
||||
def save_simulation_results(path: str | Path, results: SimulationResults) -> None:
|
||||
Path(path).write_text(
|
||||
json.dumps(results.to_dict(), indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def load_simulation_results(path: str | Path) -> SimulationResults:
|
||||
try:
|
||||
data = json.loads(Path(path).read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError) as error:
|
||||
raise ValueError(f"Could not read simulation results: {error}") from error
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError("Simulation-results root must be an object")
|
||||
return SimulationResults.from_dict(data)
|
||||
Reference in New Issue
Block a user