From f619fd21fe39cbb0abee9d40e39242e657249ba2 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson <oscar.gustafsson@gmail.com> Date: Fri, 17 Feb 2023 09:35:06 +0100 Subject: [PATCH] Refactor signal generation GUI --- b_asic/GUI/signal_generator_input.py | 63 ++++++++++++++++++++++++++ b_asic/GUI/simulate_sfg_window.py | 66 ++++++++-------------------- docs_sphinx/GUI.rst | 12 +++++ 3 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 b_asic/GUI/signal_generator_input.py diff --git a/b_asic/GUI/signal_generator_input.py b/b_asic/GUI/signal_generator_input.py new file mode 100644 index 00000000..5779f53f --- /dev/null +++ b/b_asic/GUI/signal_generator_input.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +from qtpy.QtWidgets import ( + QCheckBox, + QComboBox, + QDialog, + QFileDialog, + QFormLayout, + QFrame, + QGridLayout, + QHBoxLayout, + QLabel, + QLineEdit, + QPushButton, + QShortcut, + QSizePolicy, + QSpinBox, + QVBoxLayout, +) + +from b_asic.signal_generator import Impulse, Step + + +class SignalGeneratorInput(QGridLayout): + """Abstract class for graphically configuring and generating signal generators. + """ + + def get_generator(self): + raise NotImplementedError + + +class DelayInput(SignalGeneratorInput): + """ + Abstract class for graphically configuring and generating signal generators that + have a single delay parameter. + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.delay_label = QLabel("Delay") + self.addWidget(self.delay_label, 0, 0) + self.delay_spin_box = QSpinBox() + self.delay_spin_box.setRange(0, 2147483647) + self.addWidget(self.delay_spin_box, 0, 1) + + +class ImpulseInput(DelayInput): + """ + Class for graphically configuring and generating a + :class:`~b_asic.signal_generators.Impulse` signal generator. + """ + + def get_generator(self): + return Impulse(self.delay_spin_box.value()) + + +class StepInput(DelayInput): + """ + Class for graphically configuring and generating a + :class:`~b_asic.signal_generators.Step` signal generator. + """ + + def get_generator(self): + return Step(self.delay_spin_box.value()) diff --git a/b_asic/GUI/simulate_sfg_window.py b/b_asic/GUI/simulate_sfg_window.py index 9a7429de..6961733a 100644 --- a/b_asic/GUI/simulate_sfg_window.py +++ b/b_asic/GUI/simulate_sfg_window.py @@ -26,8 +26,11 @@ from qtpy.QtWidgets import ( QVBoxLayout, ) +from b_asic.GUI.signal_generator_input import ImpulseInput, StepInput from b_asic.signal_generator import Impulse, Step, ZeroPad +_GENERATOR_MAPPING = {"Impulse": ImpulseInput, "Step": StepInput} + class SimulateSFGWindow(QDialog): simulate = Signal() @@ -58,12 +61,15 @@ class SimulateSFGWindow(QDialog): 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) @@ -124,18 +130,8 @@ class SimulateSFGWindow(QDialog): param_grid = QGridLayout() - if text == "Impulse": - delay_label = QLabel("Delay") - param_grid.addWidget(delay_label, 0, 0) - delay_spin_box = QSpinBox() - delay_spin_box.setRange(0, 2147483647) - param_grid.addWidget(delay_spin_box, 0, 1) - elif text == "Step": - delay_label = QLabel("Delay") - param_grid.addWidget(delay_label, 0, 0) - delay_spin_box = QSpinBox() - delay_spin_box.setRange(0, 2147483647) - param_grid.addWidget(delay_spin_box, 0, 1) + if text in ("Impulse", "Step"): + param_grid = _GENERATOR_MAPPING[text]() elif text == "Input": input_label = QLabel("Input") param_grid.addWidget(input_label, 0, 0) @@ -192,7 +188,7 @@ class SimulateSFGWindow(QDialog): if ic_value == 0: self._window.logger.error("Iteration count is set to zero.") - tmp = [] + input_values = [] for i in range(self.input_grid.rowCount()): in_format = ( @@ -200,33 +196,22 @@ class SimulateSFGWindow(QDialog): ) in_param = self.input_grid.itemAtPosition(i, 2) - tmp2 = [] - - if in_format == "Impulse": - g = Impulse(in_param.itemAtPosition(0, 1).widget().value()) - for j in range(ic_value): - tmp2.append(str(g(j))) - - elif in_format == "Step": - g = Step(in_param.itemAtPosition(0, 1).widget().value()) - for j in range(ic_value): - tmp2.append(str(g(j))) - + if in_format in ("Impulse", "Step"): + tmp2 = in_param.get_generator() elif in_format == "Input": widget = in_param.itemAtPosition(0, 1).widget() tmp3 = widget.text().split(",") if in_param.itemAtPosition(1, 1).widget().isChecked(): - g = ZeroPad(tmp3) - for j in range(ic_value): - tmp2.append(str(g(j))) + tmp2 = ZeroPad(tmp3) else: - tmp2 = tmp3 - + tmp2 = self.parse_input_values(tmp3) elif in_format == "File": widget = in_param.itemAtPosition(0, 1).widget() path = widget.text() try: - tmp2 = np.loadtxt(path, dtype=str).tolist() + tmp2 = self.parse_input_values( + np.loadtxt(path, dtype=str).tolist() + ) except FileNotFoundError: self._window.logger.error( f"Selected input file not found." @@ -235,24 +220,9 @@ class SimulateSFGWindow(QDialog): else: raise Exception("Input selection is not implemented") - tmp.append(tmp2) - - input_values = self.parse_input_values(tmp) - - max_len = max(len(list_) for list_ in input_values) - min_len = min(len(list_) for list_ in input_values) + input_values.append(tmp2) - if max_len != min_len: - self._window.logger.error( - "Minimum length of input lists are not equal to maximum " - f"length of input lists: {max_len} != {min_len}." - ) - elif ic_value > min_len: - self._window.logger.error( - "Minimum length of input lists are less than the " - f"iteration count: {ic_value} > {min_len}." - ) - else: + if True: self.properties[sfg] = { "iteration_count": ic_value, "show_plot": self.input_fields[sfg][ diff --git a/docs_sphinx/GUI.rst b/docs_sphinx/GUI.rst index bbe6459b..83b24cd9 100644 --- a/docs_sphinx/GUI.rst +++ b/docs_sphinx/GUI.rst @@ -76,6 +76,18 @@ GUI.show\_pc\_window module :undoc-members: :show-inheritance: +GUI.signal\_generator\_input module +----------------------------------- + +.. inheritance-diagram:: b_asic.GUI.signal_generator_input + :parts: 1 + :top-classes: b_asic.GUI.signal_generator_input.SignalGeneratorInput + +.. automodule:: b_asic.GUI.signal_generator_input + :members: + :undoc-members: + :show-inheritance: + GUI.simulate\_sfg\_window module -------------------------------- -- GitLab