-
Oscar Gustafsson authoredOscar Gustafsson authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
simulate_sfg_window.py 5.75 KiB
"""
B-ASIC window to simulate an SFG.
"""
from typing import TYPE_CHECKING, Dict
from qtpy.QtCore import Qt, Signal
from qtpy.QtWidgets import (
QCheckBox,
QComboBox,
QDialog,
QFormLayout,
QFrame,
QGridLayout,
QLabel,
QLayout,
QPushButton,
QSpinBox,
QVBoxLayout,
)
from b_asic.GUI.signal_generator_input import _GENERATOR_MAPPING
if TYPE_CHECKING:
from b_asic.signal_flow_graph import SFG
class SimulateSFGWindow(QDialog):
"""Simulation window."""
simulate = Signal()
def __init__(self, window):
super().__init__()
self._window = window
self._properties = {}
self._sfg_to_layout = {}
self._input_fields = {}
self.setWindowFlags(Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
self.setWindowTitle("Simulate SFG")
self._dialog_layout = QVBoxLayout()
self._dialog_layout.setSizeConstraint(QLayout.SetFixedSize)
self._simulate_btn = QPushButton("Simulate")
self._simulate_btn.clicked.connect(self.save_properties)
self._dialog_layout.addWidget(self._simulate_btn)
self.setLayout(self._dialog_layout)
self._input_grid = QGridLayout()
self._input_files = {}
def add_sfg_to_dialog(self, sfg: "SFG") -> None:
"""
Add a signal flow graph to the dialog.
Parameters
----------
sfg : SFG
The signal flow graph to add.
"""
sfg_layout = QVBoxLayout()
options_layout = QFormLayout()
name_label = QLabel(f"{sfg.name}")
sfg_layout.addWidget(name_label)
spin_box = QSpinBox()
spin_box.setRange(0, 2147483647)
spin_box.setValue(100)
options_layout.addRow("Iteration count: ", spin_box)
check_box_plot = QCheckBox()
check_box_plot.setCheckState(Qt.CheckState.Checked)
options_layout.addRow("Plot results: ", check_box_plot)
check_box_all = QCheckBox()
check_box_all.setCheckState(Qt.CheckState.Checked)
options_layout.addRow("Get all results: ", check_box_all)
sfg_layout.addLayout(options_layout)
self._input_fields[sfg] = {
"iteration_count": spin_box,
"show_plot": check_box_plot,
"all_results": check_box_all,
}
if sfg.input_count > 0:
input_label = QLabel("Input values:")
options_layout.addRow(input_label)
x, y = 0, 0
for i in range(sfg.input_count):
if i % 2 == 0 and i > 0:
x += 1
y = 0
input_label = QLabel(f"in{i}")
self._input_grid.addWidget(input_label, i, 0)
input_dropdown = QComboBox()
input_dropdown.insertItems(0, list(_GENERATOR_MAPPING.keys()))
input_dropdown.currentTextChanged.connect(
lambda text, i=i: self.change_input_format(i, text)
)
self._input_grid.addWidget(input_dropdown, i, 1, alignment=Qt.AlignLeft)
self.change_input_format(i, "Constant")
y += 1
sfg_layout.addLayout(self._input_grid)
frame = QFrame()
frame.setFrameShape(QFrame.HLine)
frame.setFrameShadow(QFrame.Sunken)
self._dialog_layout.addWidget(frame)
self._sfg_to_layout[sfg] = sfg_layout
self._dialog_layout.addLayout(sfg_layout)
def change_input_format(self, i: int, text: str) -> None:
"""
Change the input format selector.
Parameters
----------
i : int
Input number to change for.
text : str
Name of generator.
"""
grid = self._input_grid.itemAtPosition(i, 2)
if grid:
for j in reversed(range(grid.count())):
item = grid.itemAt(j)
widget = item.widget()
if widget:
widget.hide()
self._input_grid.removeItem(grid)
if text in _GENERATOR_MAPPING:
param_grid = _GENERATOR_MAPPING[text](self._window._logger)
else:
raise ValueError("Input selection is not implemented")
self._input_grid.addLayout(param_grid, i, 2)
def save_properties(self) -> None:
"""Save the simulation properties and emit a signal to start the simulation."""
for sfg, _properties in self._input_fields.items():
ic_value = self._input_fields[sfg]["iteration_count"].value()
if ic_value == 0:
self._window._logger.error("Iteration count is set to zero.")
input_values = []
for i in range(self._input_grid.rowCount()):
in_format = self._input_grid.itemAtPosition(i, 1).widget().currentText()
in_param = self._input_grid.itemAtPosition(i, 2)
if in_format in _GENERATOR_MAPPING:
tmp2 = in_param.get_generator()
else:
raise ValueError("Input selection is not implemented")
input_values.append(tmp2)
self._properties[sfg] = {
"iteration_count": ic_value,
"show_plot": self._input_fields[sfg]["show_plot"].isChecked(),
"all_results": self._input_fields[sfg]["all_results"].isChecked(),
"input_values": input_values,
}
# If we plot we should also print the entire data,
# since you cannot really interact with the graph.
if self._properties[sfg]["show_plot"]:
self._properties[sfg]["all_results"] = True
self.accept()
self.simulate.emit()
@property
def properties(self) -> Dict:
"""Return the simulation properties."""
return self._properties