Skip to content
Snippets Groups Projects
simulate_sfg_window.py 5.75 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    """
    B-ASIC window to simulate an SFG.
    """
    
    from typing import TYPE_CHECKING, Dict
    
    from qtpy.QtCore import Qt, Signal
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from qtpy.QtWidgets import (
        QCheckBox,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        QDialog,
        QFormLayout,
        QFrame,
        QGridLayout,
        QLabel,
    
        QLayout,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        QPushButton,
        QSpinBox,
        QVBoxLayout,
    )
    
    from b_asic.GUI.signal_generator_input import _GENERATOR_MAPPING
    
    if TYPE_CHECKING:
        from b_asic.signal_flow_graph import SFG
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """Simulation 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.setCheckState(Qt.CheckState.Checked)
    
            options_layout.addRow("Plot results: ", check_box_plot)
    
            check_box_all.setCheckState(Qt.CheckState.Checked)
    
            options_layout.addRow("Get all results: ", check_box_all)
    
            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
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                    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")
    
                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)
    
                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()
    
                        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
    
    
        @property
        def properties(self) -> Dict:
    
            """Return the simulation properties."""
    
            return self._properties