Saving sim results
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import Signal
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtWidgets import QFileDialog, QMainWindow, QMessageBox
|
||||
|
||||
from bedit.core.simulation.openmodelica import SimulationMessage, SimulationProgress
|
||||
from bedit.core.simulation.results import (
|
||||
SimulationExecutionResult,
|
||||
SimulationResults,
|
||||
load_simulation_results,
|
||||
save_simulation_results,
|
||||
@@ -31,6 +32,10 @@ class SimulationWindow(QMainWindow):
|
||||
self.results = SimulationResults()
|
||||
self._connect_actions()
|
||||
self._populate_view_menu()
|
||||
self.splitDockWidget(
|
||||
self.ui.statusDock, self.ui.logDock, Qt.Orientation.Vertical
|
||||
)
|
||||
self.ui.statusDock.setFixedHeight(self.ui.statusDock.sizeHint().height())
|
||||
self.progressReceived.connect(self._show_progress)
|
||||
self.messageReceived.connect(self._show_message)
|
||||
self.simulationFinished.connect(self._show_finished)
|
||||
@@ -39,15 +44,18 @@ class SimulationWindow(QMainWindow):
|
||||
def _connect_actions(self) -> None:
|
||||
self.ui.actionOpen.triggered.connect(self.open_results)
|
||||
self.ui.actionSave.triggered.connect(self.save_results)
|
||||
self.ui.actionSaveAs.triggered.connect(self.save_results_as)
|
||||
self.ui.actionClear.triggered.connect(self.clear)
|
||||
self.ui.actionExit.triggered.connect(self.close)
|
||||
self.ui.actionAbout.triggered.connect(self.show_about)
|
||||
self.ui.actionAboutQt.triggered.connect(
|
||||
lambda: QMessageBox.aboutQt(self, "About Qt Framework")
|
||||
)
|
||||
self.ui.actionToggleResults.toggled.connect(self.ui.centralWidget.setVisible)
|
||||
|
||||
def _populate_view_menu(self) -> None:
|
||||
for panel in (self.ui.statusDock, self.ui.logDock, self.ui.resultsDock):
|
||||
self.ui.menuPanels.addAction(self.ui.actionToggleResults)
|
||||
for panel in (self.ui.statusDock, self.ui.logDock):
|
||||
self.ui.menuPanels.addAction(panel.toggleViewAction())
|
||||
self.ui.menuToolbars.addAction(self.ui.fileToolbar.toggleViewAction())
|
||||
|
||||
@@ -97,15 +105,18 @@ class SimulationWindow(QMainWindow):
|
||||
)
|
||||
|
||||
def load_result_views(self) -> None:
|
||||
"""Populate custom plots from ``self.results.traces``.
|
||||
"""Populate custom plots from ``self.results.data`` and traces.
|
||||
|
||||
This is the intended integration point for a future plotting widget.
|
||||
"""
|
||||
|
||||
data_count = len(self.results.data)
|
||||
trace_count = len(self.results.traces)
|
||||
if trace_count:
|
||||
if data_count or trace_count:
|
||||
sample_count = len(next(iter(self.results.data.values()), []))
|
||||
self.ui.resultsPlaceholder.setText(
|
||||
f"{trace_count} trace(s) loaded; add graph rendering here."
|
||||
f"{data_count} data column(s), {sample_count} sample(s), and "
|
||||
f"{trace_count} configured trace(s) loaded; add graph rendering here."
|
||||
)
|
||||
|
||||
def open_results(self) -> None:
|
||||
@@ -113,7 +124,7 @@ class SimulationWindow(QMainWindow):
|
||||
self,
|
||||
"Open Simulation Results",
|
||||
"",
|
||||
"BEdit Simulation Results (*.json);;JSON Files (*.json)",
|
||||
"BEdit Binary Simulation Results (*.ber);;JSON Simulation Results (*.json)",
|
||||
)
|
||||
if not file_name:
|
||||
return
|
||||
@@ -131,18 +142,27 @@ class SimulationWindow(QMainWindow):
|
||||
def save_results(self) -> None:
|
||||
file_path = self._file_path
|
||||
if file_path is None:
|
||||
default_name = f"{_safe_file_stem(self.results.model_name)}-results.json"
|
||||
file_name, _selected_filter = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
"Save Simulation Results",
|
||||
default_name,
|
||||
"BEdit Simulation Results (*.json);;JSON Files (*.json)",
|
||||
)
|
||||
if not file_name:
|
||||
return
|
||||
file_path = Path(file_name)
|
||||
if file_path.suffix.lower() != ".json":
|
||||
file_path = file_path.with_suffix(".json")
|
||||
self.save_results_as()
|
||||
return
|
||||
self._save_results_to(file_path)
|
||||
|
||||
def save_results_as(self) -> None:
|
||||
default_name = f"{_safe_file_stem(self.results.model_name)}-results.ber"
|
||||
file_name, selected_filter = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
"Save Simulation Results As",
|
||||
default_name,
|
||||
"BEdit Binary Simulation Results (*.ber);;JSON Simulation Results (*.json)",
|
||||
)
|
||||
if not file_name:
|
||||
return
|
||||
file_path = Path(file_name)
|
||||
if file_path.suffix.lower() not in {".ber", ".json"}:
|
||||
suffix = ".json" if selected_filter.startswith("JSON") else ".ber"
|
||||
file_path = file_path.with_suffix(suffix)
|
||||
self._save_results_to(file_path)
|
||||
|
||||
def _save_results_to(self, file_path: Path) -> None:
|
||||
try:
|
||||
save_simulation_results(file_path, self.results)
|
||||
except OSError as error:
|
||||
@@ -209,7 +229,12 @@ class SimulationWindow(QMainWindow):
|
||||
def _show_finished(self, result) -> None:
|
||||
self._running = False
|
||||
self.results.status.update(phase="Simulation finished", progress=10000)
|
||||
self.results.metadata["processResult"] = result
|
||||
if isinstance(result, SimulationExecutionResult):
|
||||
self.results.data = result.data
|
||||
self.results.metadata["processReturnCode"] = result.return_code
|
||||
self.results.metadata["sourceResultFile"] = Path(result.result_file).name
|
||||
else:
|
||||
self.results.metadata["processResult"] = result
|
||||
self.ui.progressBar.setValue(10000)
|
||||
self.ui.statusLabel.setText("Simulation finished")
|
||||
self.load_result_views()
|
||||
|
||||
Reference in New Issue
Block a user