def draw_impz(self): """ (Re-)draw the figure without recalculation """ if not hasattr(self, 'cmplx'): # has response been calculated yet? logger.error("self.y {0}".format(self.y)) self.calc_stimulus() self.calc_response() f_unit = fb.fil[0]['freq_specs_unit'] if f_unit in {"f_S", "f_Ny"}: unit_frmt = "i" # italic else: unit_frmt = None self.ui.lblFreqUnit1.setText(to_html(f_unit, frmt=unit_frmt)) self.ui.lblFreqUnit2.setText(to_html(f_unit, frmt=unit_frmt)) self.load_fs() #self.init_axes() self.fmt_plot_resp = {'color':'red', 'linewidth':2, 'alpha':0.5} self.fmt_mkr_resp = {'color':'red', 'alpha':0.5} self.fmt_plot_stim = {'color':'blue', 'linewidth':2, 'alpha':0.5} self.fmt_mkr_stim = {'color':'blue', 'alpha':0.5} self.fmt_stem_stim = params['mpl_stimuli'] idx = self.tabWidget.currentIndex() if idx == 0: self.draw_impz_time() elif idx == 1: self.draw_impz_freq() else: logger.error("Index {0} out of range!".format(idx))
def draw_impz(self): """ (Re-)draw the figure without recalculation """ if not hasattr( self, 'cmplx' ): # has response been calculated yet? logger.error("self.y {0}".format(self.y)) self.calc_stimulus() self.calc_response() f_unit = fb.fil[0]['freq_specs_unit'] if f_unit in {"f_S", "f_Ny"}: unit_frmt = "i" # italic else: unit_frmt = None self.ui.lblFreqUnit1.setText(to_html(f_unit, frmt=unit_frmt)) self.ui.lblFreqUnit2.setText(to_html(f_unit, frmt=unit_frmt)) self.load_fs() #self.init_axes() self.fmt_plot_resp = {'color': 'red', 'linewidth': 2, 'alpha': 0.5} self.fmt_mkr_resp = {'color': 'red', 'alpha': 0.5} self.fmt_plot_stim = {'color': 'blue', 'linewidth': 2, 'alpha': 0.5} self.fmt_mkr_stim = {'color': 'blue', 'alpha': 0.5} self.fmt_stem_stim = params['mpl_stimuli'] idx = self.tabWidget.currentIndex() if idx == 0: self.draw_impz_time() elif idx == 1: self.draw_impz_freq() else: logger.error("Index {0} out of range!".format(idx))
def _update_noi(self): """ Update type + value + label for self.noi for noise""" self.noise = qget_cmb_box(self.cmbNoise, data=False).lower() self.lblNoi.setVisible(self.noise != 'none') self.ledNoi.setVisible(self.noise != 'none') if self.noise != 'none': self.noi = safe_eval(self.ledNoi.text(), 0, return_type='float', sign='pos') self.ledNoi.setText(str(self.noi)) if self.noise == 'gauss': self.lblNoi.setText(to_html("σ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Standard deviation of statistical process," "noise power is <i>P</i> = σ<sup>2</sup></span>") elif self.noise == 'uniform': self.lblNoi.setText(to_html("Δ =", frmt='bi')) self.ledNoi.setToolTip( "<span>Interval size for uniformly distributed process " "(e.g. quantization step size for quantization noise), " "centered around 0. Noise power is " "<i>P</i> = Δ<sup>2</sup>/12.</span>") elif self.noise == 'prbs': self.lblNoi.setText(to_html("A =", frmt='bi')) self.ledNoi.setToolTip( "<span>Amplitude of bipolar Pseudorandom Binary Sequence. " "Noise power is <i>P</i> = A<sup>2</sup>.</span>") self.sig_tx.emit({'sender': __name__, 'data_changed': 'noi'})
def update_UI(self, new_labels=()): """ Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] unit = fb.fil[0]['freq_specs_unit'] if unit in {"f_S", "f_Ny"}: unit_frmt = 'bi' else: unit_frmt = 'b' self.lblUnit.setText(" in " + to_html(unit, frmt=unit_frmt)) num_new_labels = len(new_labels) # hide / show labels / create new subwidgets if neccessary: self._show_entries(num_new_labels) # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel #---------------------------- logging ----------------------------- logger.debug("update_UI: {0}-{1}-{2}".format(fb.fil[0]['rt'], fb.fil[0]['fc'], fb.fil[0]['fo'])) f_range = " (0 < <i>f</i> < <i>f<sub>S </sub></i>/2)" for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID qstyle_widget(self.qlineedit[i], state) if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) stop band" + f_range + ".</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) pass band" + f_range + ".</span>") else: self.qlineedit[i].setToolTip( "<span>Corner frequency for (this) band" + f_range + ".</span>") self.n_cur_labels = num_new_labels # update number of currently visible labels self.sort_dict_freqs( ) # sort frequency entries in dictionary and update display
def _show_entries(self, num_new_labels): """ - check whether enough subwidgets (QLabel und QLineEdit) exist for the the required number of `num_new_labels`: - create new ones if required - initialize them with dummy information - install eventFilter for new QLineEdit widgets so that the filter dict is updated automatically when a QLineEdit field has been edited. - if enough subwidgets exist already, make enough of them visible to show all spec fields """ num_tot_labels = len(self.qlabels) # number of existing labels / qlineedit fields if num_tot_labels < num_new_labels: # new widgets need to be generated for i in range(num_tot_labels, num_new_labels): self.qlabels.append(QLabel(self)) self.qlabels[i].setText(to_html("dummy", frmt='bi')) self.qlineedit.append(QLineEdit("")) self.qlineedit[i].setObjectName("dummy") self.qlineedit[i].installEventFilter(self) # filter events # first entry is title and reset button self.layGSpecs.addWidget(self.qlabels[i],i+1,0) self.layGSpecs.addWidget(self.qlineedit[i],i+1,1) else: # make the right number of widgets visible for i in range(self.n_cur_labels, num_new_labels): self.qlabels[i].show() self.qlineedit[i].show()
def update_UI(self, new_labels = []): """ Called from filter_specs.update_UI() Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] num_new_labels = len(new_labels) if num_new_labels < self.n_cur_labels: # less new labels/qlineedit fields than before self._hide_entries(num_new_labels) elif num_new_labels > self.n_cur_labels: # more new labels, create / show new ones self._show_entries(num_new_labels) for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID self.qlineedit[i].setToolTip("<span>Relative weight (importance) for approximating this band.</span>") qstyle_widget(self.qlineedit[i], state) self.n_cur_labels = num_new_labels # update number of currently visible labels self.load_dict() # display rounded filter dict entries
def _show_entries(self, num_new_labels): """ - check whether enough subwidgets (QLabel und QLineEdit) exist for the the required number of `num_new_labels`: - create new ones if required - initialize them with dummy information - install eventFilter for new QLineEdit widgets so that the filter dict is updated automatically when a QLineEdit field has been edited. - if enough subwidgets exist already, make enough of them visible to show all spec fields """ num_tot_labels = len( self.qlabels) # number of existing labels (vis. + invis.) if num_tot_labels < num_new_labels: # new widgets need to be generated for i in range(num_tot_labels, num_new_labels): self.qlabels.append(QLabel(self)) self.qlabels[i].setText(to_html("dummy", frmt='b')) self.qlineedit.append(QLineEdit("")) self.qlineedit[i].setObjectName("dummy") self.qlineedit[i].installEventFilter(self) # filter events # first entry is title self.layGSpecs.addWidget(self.qlabels[i], i + 1, 0) self.layGSpecs.addWidget(self.qlineedit[i], i + 1, 1) else: # make the right number of widgets visible for i in range(self.n_cur_labels, num_new_labels): self.qlabels[i].show() self.qlineedit[i].show()
def _construct_UI(self, **kwargs): """ Construct widget """ dict_ui = {'label':'WI.WF', 'max_led_width':30, 'WI':0, 'WI_len':2, 'tip_WI':'Number of integer bits', 'WF':15,'WF_len':2, 'tip_WF':'Number of fractional bits', 'enabled':True, 'visible':True } for key, val in kwargs.items(): dict_ui.update({key:val}) # dict_ui.update(map(kwargs)) # same as above? self.WI = dict_ui['WI'] self.WF = dict_ui['WF'] lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) self.ledWI = QLineEdit(self) self.ledWI.setToolTip(dict_ui['tip_WI']) self.ledWI.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWI.setFixedWidth(dict_ui['max_led_width']) # width of lineedit in points(?) lblDot = QLabel(".", self) self.ledWF = QLineEdit(self) self.ledWF.setToolTip(dict_ui['tip_WF']) self.ledWF.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWF.setFixedWidth(dict_ui['max_led_width']) # width of lineedit in points(?) layH = QHBoxLayout() layH.addWidget(lblW) layH.addStretch() layH.addWidget(self.ledWI) layH.addWidget(lblDot) layH.addWidget(self.ledWF) layH.setContentsMargins(0,0,0,0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0,5,0,0)#*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # INITIAL SETTINGS #---------------------------------------------------------------------- self.ledWI.setText(qstr(dict_ui['WI'])) self.ledWF.setText(qstr(dict_ui['WF'])) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.ledWI.editingFinished.connect(self.save_ui) self.ledWF.editingFinished.connect(self.save_ui)
def _update_param1(): self.ledWinPar1.setToolTip(tooltip) self.lblWinPar1.setText(to_html(txt_par1, frmt='bi')) self.param1 = safe_eval(self.ledWinPar1.text(), self.param1, return_type='float', sign='pos') self.ledWinPar1.setText(str(self.param1))
def _update_noi(self): """ Update type + value + label for self.noi for noise""" self.noise = qget_cmb_box(self.cmbNoise, data=False).lower() self.lblNoi.setVisible(self.noise!='none') self.ledNoi.setVisible(self.noise!='none') if self.noise!='none': self.noi = safe_eval(self.ledNoi.text(), 0, return_type='float', sign='pos') self.ledNoi.setText(str(self.noi)) if self.noise == 'gauss': self.lblNoi.setText(to_html("σ =", frmt='bi')) self.ledNoi.setToolTip("<span>Standard deviation of statistical process," "noise power is <i>P</i> = σ<sup>2</sup></span>") elif self.noise == 'uniform': self.lblNoi.setText(to_html("Δ =", frmt='bi')) self.ledNoi.setToolTip("<span>Interval size for uniformly distributed process " "(e.g. quantization step size for quantization noise), " "centered around 0. Noise power is " "<i>P</i> = Δ<sup>2</sup>/12.</span>") self.sig_tx.emit({'sender':__name__, 'data_changed':'noi'})
def update_f_unit(self): """ Set label for frequency unit according to selected unit. """ unit = fb.fil[0]['freq_specs_unit'] if unit in {"f_S", "f_Ny"}: unit_frmt = 'bi' else: unit_frmt = 'b' self.lblUnit.setText(" in " + to_html(unit, frmt=unit_frmt))
def update_UI(self, new_labels=()): """ Called from filter_specs.update_UI() and target_specs.update_UI(). Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel num_new_labels = len(new_labels) if num_new_labels < self.n_cur_labels: # less new labels/qlineedit fields than before self._hide_entries(num_new_labels) elif num_new_labels > self.n_cur_labels: # more new labels, create / show new ones self._show_entries(num_new_labels) tool_tipp_sb = "Min. attenuation resp. maximum level in (this) stop band" for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>" + tool_tipp_sb + " (> 0).</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip( "<span>Maximum ripple (> 0) in (this) pass band.<span/>" ) qstyle_widget(self.qlineedit[i], state) self.n_cur_labels = num_new_labels # update number of currently visible labels self.load_dict( ) # display rounded filter dict entries in selected unit
def update_UI(self, new_labels = ()): """ Called from filter_specs.update_UI() and target_specs.update_UI() Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ self.update_f_unit() state = new_labels[0] new_labels = new_labels[1:] num_new_labels = len(new_labels) # hide / show labels / create new subwidgets if neccessary: self._show_entries(num_new_labels) # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel #---------------------------- logging ----------------------------- logger.debug("update_UI: {0}-{1}-{2}".format( fb.fil[0]['rt'],fb.fil[0]['fc'],fb.fil[0]['fo'])) f_range = " (0 < <i>f</i> < <i>f<sub>S </sub></i>/2)" for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID qstyle_widget(self.qlineedit[i], state) if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>Corner frequency for (this) stop band" + f_range + ".</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>Corner frequency for (this) pass band" + f_range + ".</span>") else: self.qlineedit[i].setToolTip("<span>Corner frequency for (this) band" + f_range + ".</span>") self.n_cur_labels = num_new_labels # update number of currently visible labels self.sort_dict_freqs() # sort frequency entries in dictionary and update display
def update_UI(self, new_labels = ()): """ Called from filter_specs.update_UI() and target_specs.update_UI(). Set labels and get corresponding values from filter dictionary. When number of entries has changed, the layout of subwidget is rebuilt, using - `self.qlabels`, a list with references to existing QLabel widgets, - `new_labels`, a list of strings from the filter_dict for the current filter design - 'num_new_labels`, their number - `self.n_cur_labels`, the number of currently visible labels / qlineedit fields """ state = new_labels[0] new_labels = new_labels[1:] # W_lbl = max([self.qfm.width(l) for l in new_labels]) # max. label width in pixel num_new_labels = len(new_labels) if num_new_labels < self.n_cur_labels: # less new labels/qlineedit fields than before self._hide_entries(num_new_labels) elif num_new_labels > self.n_cur_labels: # more new labels, create / show new ones self._show_entries(num_new_labels) tool_tipp_sb = "Min. attenuation resp. maximum level in (this) stop band" for i in range(num_new_labels): # Update ALL labels and corresponding values self.qlabels[i].setText(to_html(new_labels[i], frmt='bi')) self.qlineedit[i].setText(str(fb.fil[0][new_labels[i]])) self.qlineedit[i].setObjectName(new_labels[i]) # update ID if "sb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>" + tool_tipp_sb + " (> 0).</span>") elif "pb" in new_labels[i].lower(): self.qlineedit[i].setToolTip("<span>Maximum ripple (> 0) in (this) pass band.<span/>") qstyle_widget(self.qlineedit[i], state) self.n_cur_labels = num_new_labels # update number of currently visible labels self.load_dict() # display rounded filter dict entries in selected unit
def _construct_UI(self): """ Construct the User Interface """ bfont = QFont() bfont.setBold(True) lblTitle = QLabel(str(self.title), self) # field for widget title lblTitle.setFont(bfont) lblTitle.setWordWrap(True) self.lblUnit = QLabel(self) self.lblUnit.setText("in " + to_html(fb.fil[0]['freq_specs_unit'], frmt='bi')) layHTitle = QHBoxLayout() layHTitle.addWidget(lblTitle) layHTitle.addWidget(self.lblUnit) layHTitle.addStretch(1) # Create a gridLayout consisting of QLabel and QLineEdit fields # for the frequency specs: self.layGSpecs = QGridLayout() # sublayout for spec fields # set the title as the first (fixed) entry in grid layout. The other # fields are added and hidden dynamically in _show_entries and _hide_entries() self.layGSpecs.addLayout(layHTitle, 0, 0, 1, 2) self.layGSpecs.setAlignment(Qt.AlignLeft) self.frmMain = QFrame(self) self.frmMain.setLayout(self.layGSpecs) self.layVMain = QVBoxLayout() # Widget main layout self.layVMain.addWidget(self.frmMain) #, Qt.AlignLeft) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) self.n_cur_labels = 0 # number of currently visible labels / qlineedits #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx)
def _construct_UI(self): """ Construct the User Interface """ bfont = QFont() bfont.setBold(True) lblTitle = QLabel(str(self.title), self) # field for widget title lblTitle.setFont(bfont) lblTitle.setWordWrap(True) self.lblUnit = QLabel(self) self.lblUnit.setText("in " + to_html(fb.fil[0]['freq_specs_unit'], frmt='bi')) layHTitle = QHBoxLayout() layHTitle.addWidget(lblTitle) layHTitle.addWidget(self.lblUnit) layHTitle.addStretch(1) # Create a gridLayout consisting of QLabel and QLineEdit fields # for the frequency specs: self.layGSpecs = QGridLayout() # sublayout for spec fields # set the title as the first (fixed) entry in grid layout. The other # fields are added and hidden dynamically in _show_entries and _hide_entries() self.layGSpecs.addLayout(layHTitle, 0, 0, 1, 2) self.layGSpecs.setAlignment(Qt.AlignLeft) self.frmMain = QFrame(self) self.frmMain.setLayout(self.layGSpecs) self.layVMain = QVBoxLayout() # Widget main layout self.layVMain.addWidget(self.frmMain)#, Qt.AlignLeft) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) self.n_cur_labels = 0 # number of currently visible labels / qlineedits #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx)
def _show_entries(self, num_new_labels): """ - check whether subwidgets need to be shown or hidden - check whether enough subwidgets (QLabel und QLineEdit) exist for the the required number of `num_new_labels`: - create new ones if required - initialize them with dummy information - install eventFilter for new QLineEdit widgets so that the filter dict is updated automatically when a QLineEdit field has been edited. - if enough subwidgets exist already, make enough of them visible to show all spec fields """ num_tot_labels = len(self.qlabels) # number of existing labels (vis. + invis.) # less new subwidgets than currently displayed -> _hide some if num_new_labels < self.n_cur_labels: # less new labels/qlineedit fields than before for i in range (num_new_labels, num_tot_labels): self.qlabels[i].hide() self.qlineedit[i].hide() # enough hidden subwidgets but need to make more labels visible elif num_tot_labels >= num_new_labels: for i in range(self.n_cur_labels, num_new_labels): self.qlabels[i].show() self.qlineedit[i].show() else: # new subwidgets need to be generated for i in range(num_tot_labels, num_new_labels): self.qlabels.append(QLabel(self)) self.qlabels[i].setText(to_html("dummy", frmt='bi')) self.qlineedit.append(QLineEdit("")) self.qlineedit[i].setObjectName("dummy") self.qlineedit[i].installEventFilter(self) # filter events # first entry is the title self.layGSpecs.addWidget(self.qlabels[i],i+1,0) self.layGSpecs.addWidget(self.qlineedit[i],i+1,1)
def write(self, msg): if not self.signalsBlocked(): msg = to_html(msg,frmt='log') self.messageWritten.emit(msg)
def __init__(self, parent): """ Pass instance `parent` of parent class (FilterCoeffs) """ super(Input_PZ_UI, self).__init__(parent) # self.parent = parent # instance of the parent (not the base) class self.eps = 1.e-4 # # tolerance value for e.g. setting P/Z to zero """ Intitialize the widget, consisting of: - top chkbox row - coefficient table - two bottom rows with action buttons """ self.bfont = QFont() self.bfont.setBold(True) self.bifont = QFont() self.bifont.setBold(True) self.bifont.setItalic(True) # q_icon_size = QSize(20, 20) # optional, size is derived from butEnable # --------------------------------------------- # UI Elements for controlling the display # --------------------------------------------- self.butEnable = QPushButton(self) self.butEnable.setIcon(QIcon(':/circle-x.svg')) q_icon_size = self.butEnable.iconSize() # <- set this for manual icon sizing self.butEnable.setIconSize(q_icon_size) self.butEnable.setCheckable(True) self.butEnable.setChecked(True) self.butEnable.setToolTip("<span>Show / hide poles and zeros in an editable table." " For high order systems, the table display might be slow.</span>") self.cmbPZFrmt = QComboBox(self) pz_formats = [('Cartesian', 'cartesian'), ('Polar (rad)', 'polar_rad'), ('Polar (pi)', 'polar_pi'), ('Polar (°)', 'polar_deg')] # display text, data # π: u'3C0, °: u'B0, ∠: u'2220 for pz in pz_formats: self.cmbPZFrmt.addItem(*pz) self.cmbPZFrmt.setSizeAdjustPolicy(QComboBox.AdjustToContents) # self.cmbPZFrmt.setEnabled(False) self.cmbPZFrmt.setToolTip("<span>Set display format for poles and zeros to" " either cartesian (x + jy) or polar (r * ∠ Ω)." " Type 'o' for '°', '<' for '∠' and 'pi' for 'π'.</span>") self.spnDigits = QSpinBox(self) self.spnDigits.setRange(0,16) self.spnDigits.setToolTip("Number of digits to display.") self.lblDigits = QLabel("Digits", self) self.lblDigits.setFont(self.bifont) self.cmbCausal = QComboBox(self) causal_types = ['Causal', 'Acausal', 'Anticausal'] for cs in causal_types: self.cmbCausal.addItem(cs) qset_cmb_box(self.cmbCausal, 'Causal') self.cmbCausal.setToolTip('<span>Set the system type. Not implemented yet.</span>') self.cmbCausal.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbCausal.setEnabled(False) layHDisplay = QHBoxLayout() layHDisplay.setAlignment(Qt.AlignLeft) layHDisplay.addWidget(self.butEnable) layHDisplay.addWidget(self.cmbPZFrmt) layHDisplay.addWidget(self.spnDigits) layHDisplay.addWidget(self.lblDigits) layHDisplay.addWidget(self.cmbCausal) layHDisplay.addStretch() # --------------------------------------------- # UI Elements for setting the gain # --------------------------------------------- self.lblNorm = QLabel(to_html("Normalize:", frmt='bi'), self) self.cmbNorm = QComboBox(self) self.cmbNorm.addItems(["None", "1", "Max"]) self.cmbNorm.setToolTip("<span>Set the gain <i>k</i> so that H(f)<sub>max</sub> is " "either 1 or the max. of the previous system.</span>") self.lblGain = QLabel(to_html("k =", frmt='bi'), self) self.ledGain = QLineEdit(self) self.ledGain.setToolTip("<span>Specify gain factor <i>k</i>" " (only possible for Normalize = 'None').</span>") self.ledGain.setText(str(1.)) self.ledGain.setObjectName("ledGain") layHGain = QHBoxLayout() layHGain.addWidget(self.lblNorm) layHGain.addWidget(self.cmbNorm) layHGain.addWidget(self.lblGain) layHGain.addWidget(self.ledGain) layHGain.addStretch() # --------------------------------------------- # UI Elements for loading / storing / manipulating cells and rows # --------------------------------------------- # self.cmbFilterType = QComboBox(self) # self.cmbFilterType.setObjectName("comboFilterType") # self.cmbFilterType.setToolTip("Select between IIR and FIR filte for manual entry.") # self.cmbFilterType.addItems(["FIR","IIR"]) # self.cmbFilterType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butAddCells = QPushButton(self) self.butAddCells.setIcon(QIcon(':/row_insert_above.svg')) self.butAddCells.setIconSize(q_icon_size) self.butAddCells.setToolTip("<SPAN>Select cells to insert a new cell above each selected cell. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, add a row at the end.</SPAN>") self.butDelCells = QPushButton(self) self.butDelCells.setIcon(QIcon(':/row_delete.svg')) self.butDelCells.setIconSize(q_icon_size) self.butDelCells.setToolTip("<SPAN>Delete selected cell(s) from the table. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, delete the last row.</SPAN>") self.butSave = QPushButton(self) self.butSave.setIcon(QIcon(':/upload.svg')) self.butSave.setIconSize(q_icon_size) self.butSave.setToolTip("<span>Copy P/Z table to filter dict and update all plots and widgets.</span>") self.butLoad = QPushButton(self) self.butLoad.setIcon(QIcon(':/download.svg')) self.butLoad.setIconSize(q_icon_size) self.butLoad.setToolTip("Reload P/Z table from filter dict.") self.butClear = QPushButton(self) self.butClear.setIcon(QIcon(':/trash.svg')) self.butClear.setIconSize(q_icon_size) self.butClear.setToolTip("Clear all table entries.") self.butFromTable = QPushButton(self) self.butFromTable.setIconSize(q_icon_size) self.butToTable = QPushButton(self) self.butToTable.setIconSize(q_icon_size) self._set_load_save_icons() butSettingsClipboard = QPushButton(self) butSettingsClipboard.setIcon(QIcon(':/settings.svg')) butSettingsClipboard.setIconSize(q_icon_size) butSettingsClipboard.setToolTip("<span>Select CSV format and whether " "to copy to/from clipboard or file.</span>") layHButtonsCoeffs1 = QHBoxLayout() # layHButtonsCoeffs1.addWidget(self.cmbFilterType) layHButtonsCoeffs1.addWidget(self.butAddCells) layHButtonsCoeffs1.addWidget(self.butDelCells) layHButtonsCoeffs1.addWidget(self.butClear) layHButtonsCoeffs1.addWidget(self.butSave) layHButtonsCoeffs1.addWidget(self.butLoad) layHButtonsCoeffs1.addWidget(self.butFromTable) layHButtonsCoeffs1.addWidget(self.butToTable) layHButtonsCoeffs1.addWidget(butSettingsClipboard) layHButtonsCoeffs1.addStretch() #------------------------------------------------------------------- # Eps / set zero settings # --------------------------------------------------------------------- self.butSetZero = QPushButton("= 0", self) self.butSetZero.setToolTip("<span>Set selected poles / zeros = 0 with a magnitude < ε. " "When nothing is selected, test the whole table.</span>") self.butSetZero.setIconSize(q_icon_size) lblEps = QLabel(self) lblEps.setText("<b><i>for ε</i> <</b>") self.ledEps = QLineEdit(self) self.ledEps.setToolTip("Specify tolerance value.") layHButtonsCoeffs2 = QHBoxLayout() layHButtonsCoeffs2.addWidget(self.butSetZero) layHButtonsCoeffs2.addWidget(lblEps) layHButtonsCoeffs2.addWidget(self.ledEps) layHButtonsCoeffs2.addStretch() # ######################## Main UI Layout ############################ # layout for frame (UI widget) layVMainF = QVBoxLayout() layVMainF.addLayout(layHDisplay) layVMainF.addLayout(layHGain) layVMainF.addLayout(layHButtonsCoeffs1) layVMainF.addLayout(layHButtonsCoeffs2) # This frame encompasses all UI elements frmMain = QFrame(self) frmMain.setLayout(layVMainF) layVMain = QVBoxLayout() layVMain.setAlignment(Qt.AlignTop) # this affects only the first widget (intended here) layVMain.addWidget(frmMain) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #--- set initial values from dict ------------ self.spnDigits.setValue(params['FMT_pz']) self.ledEps.setText(str(self.eps)) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- butSettingsClipboard.clicked.connect(self._copy_options) self.sig_rx.connect(self._set_load_save_icons)
def _construct_UI(self): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- self.chk_auto_run = QCheckBox("Auto", self) self.chk_auto_run.setObjectName("chk_auto_run") self.chk_auto_run.setToolTip( "<span>Update response automatically when " "parameters have been changed.</span>") self.chk_auto_run.setChecked(True) self.but_run = QPushButton(self) self.but_run.setText("RUN") self.but_run.setToolTip("Run simulation") self.but_run.setEnabled(not self.chk_auto_run.isChecked()) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float", "Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip( "<span>Simulate floating-point or fixpoint response." "</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N)) self.led_N_points.setToolTip( "<span>Number of displayed data points. " "<i>N</i> = 0 tries to choose for you.</span>") self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.chk_fx_scale = QCheckBox("Int. scale", self) self.chk_fx_scale.setObjectName("chk_fx_scale") self.chk_fx_scale.setToolTip( "<span>Display data with integer (fixpoint) scale.</span>") self.chk_fx_scale.setChecked(False) self.chk_stim_options = QCheckBox("Stim. Options", self) self.chk_stim_options.setObjectName("chk_stim_options") self.chk_stim_options.setToolTip("<span>Show stimulus options.</span>") self.chk_stim_options.setChecked(True) self.but_fft_win = QPushButton(self) self.but_fft_win.setText("WIN FFT") self.but_fft_win.setToolTip( "Show time and frequency response of FFT Window") self.but_fft_win.setCheckable(True) self.but_fft_win.setChecked(False) layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.but_run) #layH_ctrl_run.addWidget(self.lbl_sim_select) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addWidget(self.chk_auto_run) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_fx_scale) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_stim_options) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.but_fft_win) layH_ctrl_run.addStretch(10) #layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- plot_styles_list = [ "None", "Dots", "Line", "Line*", "Stem", "Stem*", "Step", "Step*" ] lbl_plt_time_title = QLabel("<b>View:</b>", self) lbl_plt_time_resp = QLabel("Response", self) self.cmb_plt_time_resp = QComboBox(self) self.cmb_plt_time_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_resp, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip( "<span>Plot style for response.</span>") self.lbl_plt_time_stim = QLabel("Stimulus", self) self.cmb_plt_time_stim = QComboBox(self) self.cmb_plt_time_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stim, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_time_stmq = QLabel("Stim.<q>", self) self.cmb_plt_time_stmq = QComboBox(self) self.cmb_plt_time_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_time_stmq, self.plt_time_stmq) self.cmb_plt_time_stmq.setToolTip( "<span>Plot style for <em>quantized</em> stimulus.</span>") self.chk_log_time = QCheckBox("dB", self) self.chk_log_time.setObjectName("chk_log_time") self.chk_log_time.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_time.setChecked(False) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setToolTip( "<span>Minimum display value for log. scale.</span>") self.chk_win_time = QCheckBox("FFT Window", self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip( "<span>Show FFT windowing function.</span>") self.chk_win_time.setChecked(False) self.chk_fx_limits = QCheckBox("Min/max.", self) self.chk_fx_limits.setObjectName("chk_fx_limits") self.chk_fx_limits.setToolTip( "<span>Display limits of fixpoint range.</span>") self.chk_fx_limits.setChecked(False) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(lbl_plt_time_title) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(lbl_plt_time_resp) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stmq) layH_ctrl_time.addWidget(self.cmb_plt_time_stmq) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_log_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_fx_limits) layH_ctrl_time.addStretch(10) #layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- lbl_plt_freq_title = QLabel("<b>View:</b>", self) lbl_plt_freq_resp = QLabel("Response", self) self.cmb_plt_freq_resp = QComboBox(self) self.cmb_plt_freq_resp.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_resp, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip( "<span>Plot style for response.</span>") self.lbl_plt_freq_stim = QLabel("Stimulus", self) self.cmb_plt_freq_stim = QComboBox(self) self.cmb_plt_freq_stim.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stim, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip( "<span>Plot style for stimulus.</span>") self.lbl_plt_freq_stmq = QLabel("Stim.<q>", self) self.cmb_plt_freq_stmq = QComboBox(self) self.cmb_plt_freq_stmq.addItems(plot_styles_list) qset_cmb_box(self.cmb_plt_freq_stmq, self.plt_freq_stmq) self.cmb_plt_freq_stmq.setToolTip( "<span>Plot style for <em>quantized</em> stimulus.</span>") self.chk_log_freq = QCheckBox("dB : Min.", self) self.chk_log_freq.setObjectName("chk_log_freq") self.chk_log_freq.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_freq.setChecked(True) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_win_fft = QLabel("Window: ", self) self.cmb_win_fft = QComboBox(self) self.cmb_win_fft.addItems(get_window_names()) #self.cmb_win_fft.addItems(["Rect","Triangular","Hann","Hamming","Kaiser", "Flattop", "Chebwin"]) self.cmb_win_fft.setToolTip("FFT window type.") qset_cmb_box(self.cmb_win_fft, self.window) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") self.lblWinPar2 = QLabel("Param2") self.ledWinPar2 = QLineEdit(self) self.ledWinPar2.setText("2") self.ledWinPar2.setObjectName("ledWinPar2") layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(lbl_plt_freq_title) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stmq) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stmq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.chk_log_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.lbl_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft) layH_ctrl_freq.addWidget(self.lblWinPar1) layH_ctrl_freq.addWidget(self.ledWinPar1) layH_ctrl_freq.addWidget(self.lblWinPar2) layH_ctrl_freq.addWidget(self.ledWinPar2) layH_ctrl_freq.addStretch(10) #layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # --------------------------------------------------------------- # Controls for stimuli # --------------------------------------------------------------- lbl_title_stim = QLabel("<b>Stimulus:</b>", self) self.lblStimulus = QLabel("Signal: ", self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems([ "None", "Pulse", "Step", "StepErr", "Cos", "Sine", "Triang", "Saw", "Rect", "Comb" ]) self.cmbStimulus.setToolTip("Stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.chk_stim_bl = QCheckBox("BL", self) self.chk_stim_bl.setToolTip( "<span>The signal is bandlimited to the Nyquist frequency " "to avoid aliasing. However, it is much slower to generate " "than the regular version.</span>") self.chk_stim_bl.setChecked(True) self.chk_stim_bl.setObjectName("stim_bl") self.lblNoise = QLabel("Noise: ", self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None", "Gauss", "Uniform", "PRBS"]) self.cmbNoise.setToolTip("Type of additive noise.") qset_cmb_box(self.cmbNoise, self.noise) layVlblCmb = QVBoxLayout() layVlblCmb.addWidget(self.lblStimulus) layVlblCmb.addWidget(self.lblNoise) layVCmb = QVBoxLayout() layHCmbStim = QHBoxLayout() layHCmbStim.addWidget(self.cmbStimulus) layHCmbStim.addWidget(self.chk_stim_bl) #layVCmb.addWidget(self.cmbStimulus) layVCmb.addLayout(layHCmbStim) layVCmb.addWidget(self.cmbNoise) #---------------------------------------------- self.lblAmp1 = QLabel(to_html("A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html("A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2") self.ledAmp2.setObjectName("stimAmp2") layVlblAmp = QVBoxLayout() layVlblAmp.addWidget(self.lblAmp1) layVlblAmp.addWidget(self.lblAmp2) layVledAmp = QVBoxLayout() layVledAmp.addWidget(self.ledAmp1) layVledAmp.addWidget(self.ledAmp2) #---------------------------------------------- self.lblPhi1 = QLabel(to_html("φ_1", frmt='bi') + " =", self) self.ledPhi1 = QLineEdit(self) self.ledPhi1.setText(str(self.phi1)) self.ledPhi1.setToolTip("Stimulus phase") self.ledPhi1.setObjectName("stimPhi1") self.lblPhU1 = QLabel(to_html("°", frmt='b'), self) self.lblPhi2 = QLabel(to_html("φ_2", frmt='bi') + " =", self) self.ledPhi2 = QLineEdit(self) self.ledPhi2.setText(str(self.phi2)) self.ledPhi2.setToolTip("Stimulus phase 2") self.ledPhi2.setObjectName("stimPhi2") self.lblPhU2 = QLabel(to_html("°", frmt='b'), self) layVlblPhi = QVBoxLayout() layVlblPhi.addWidget(self.lblPhi1) layVlblPhi.addWidget(self.lblPhi2) layVledPhi = QVBoxLayout() layVledPhi.addWidget(self.ledPhi1) layVledPhi.addWidget(self.ledPhi2) layVlblPhU = QVBoxLayout() layVlblPhU.addWidget(self.lblPhU1) layVlblPhU.addWidget(self.lblPhU2) #---------------------------------------------- self.lblFreq1 = QLabel(to_html("f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html("f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) layVlblfreq = QVBoxLayout() layVlblfreq.addWidget(self.lblFreq1) layVlblfreq.addWidget(self.lblFreq2) layVledfreq = QVBoxLayout() layVledfreq.addWidget(self.ledFreq1) layVledfreq.addWidget(self.ledFreq2) layVlblfreqU = QVBoxLayout() layVlblfreqU.addWidget(self.lblFreqUnit1) layVlblfreqU.addWidget(self.lblFreqUnit2) #---------------------------------------------- self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layVlblNoiDC = QVBoxLayout() layVlblNoiDC.addWidget(self.lblNoi) layVlblNoiDC.addWidget(self.lblDC) layVledNoiDC = QVBoxLayout() layVledNoiDC.addWidget(self.ledNoi) layVledNoiDC.addWidget(self.ledDC) #---------------------------------------------- layH_ctrl_stim = QHBoxLayout() layH_ctrl_stim.addWidget(lbl_title_stim) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblCmb) layH_ctrl_stim.addLayout(layVCmb) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblAmp) layH_ctrl_stim.addLayout(layVledAmp) layH_ctrl_stim.addLayout(layVlblPhi) layH_ctrl_stim.addLayout(layVledPhi) layH_ctrl_stim.addLayout(layVlblPhU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblfreq) layH_ctrl_stim.addLayout(layVledfreq) layH_ctrl_stim.addLayout(layVlblfreqU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblNoiDC) layH_ctrl_stim.addLayout(layVledNoiDC) layH_ctrl_stim.addStretch(10) self.wdg_ctrl_stim = QWidget(self) self.wdg_ctrl_stim.setLayout(layH_ctrl_stim) # --------- end stimuli --------------------------------- # frequency widgets require special handling as they are scaled with f_s self.ledFreq1.installEventFilter(self) self.ledFreq2.installEventFilter(self) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) # --- frequency control --- # careful! currentIndexChanged passes the current index to _update_win_fft self.cmb_win_fft.currentIndexChanged.connect(self._update_win_fft) self.ledWinPar1.editingFinished.connect(self._update_param1) self.ledWinPar2.editingFinished.connect(self._update_param2) # --- stimulus control --- self.chk_stim_options.clicked.connect(self._show_stim_options) self.chk_stim_bl.clicked.connect(self._enable_stim_widgets) self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledPhi1.editingFinished.connect(self._update_phi1) self.ledPhi2.editingFinished.connect(self._update_phi2) self.ledDC.editingFinished.connect(self._update_DC)
def draw_impz(self): """ (Re-)calculate h[n] and draw the figure """ log = self.chkLog.isChecked() stim = str(self.cmbStimulus.currentText()) periodic_sig = stim in {"Cos", "Sine","Rect", "Saw"} self.lblLogBottom.setVisible(log) self.ledLogBottom.setVisible(log) self.lbldB.setVisible(log) self.lblFreq.setVisible(periodic_sig) self.ledFreq.setVisible(periodic_sig) self.lblFreqUnit.setVisible(periodic_sig) self.lblFreqUnit.setText(to_html(fb.fil[0]['freq_specs_unit'])) self.load_dict() self.bb = np.asarray(fb.fil[0]['ba'][0]) self.aa = np.asarray(fb.fil[0]['ba'][1]) if min(len(self.aa), len(self.bb)) < 2: logger.error('No proper filter coefficients: len(a), len(b) < 2 !') return sos = np.asarray(fb.fil[0]['sos']) antiCausal = 'zpkA' in fb.fil[0] causal = not (antiCausal) self.f_S = fb.fil[0]['f_S'] N_entry = safe_eval(self.ledNPoints.text(), 0, return_type='int', sign='pos') N = self.calc_n_points(N_entry) if N_entry != 0: # automatic calculation self.ledNPoints.setText(str(N)) self.A = safe_eval(self.ledAmp.text(), self.A, return_type='float') self.ledAmp.setText(str(self.A)) t = np.linspace(0, N/self.f_S, N, endpoint=False) title_str = r'Impulse Response' # default H_str = r'$h[n]$' # default # calculate h[n] if stim == "Pulse": x = np.zeros(N) x[0] = self.A # create dirac impulse as input signal elif stim == "Step": x = self.A * np.ones(N) # create step function title_str = r'Step Response' H_str = r'$h_{\epsilon}[n]$' elif stim == "StepErr": x = self.A * np.ones(N) # create step function title_str = r'Settling Error' H_str = r'$h_{\epsilon, \infty} - h_{\epsilon}[n]$' elif stim in {"Cos"}: x = self.A * np.cos(2 * np.pi * t * float(self.ledFreq.text())) if stim == "Cos": title_str = r'Transient Response to Cosine Signal' H_str = r'$y_{\cos}[n]$' elif stim in {"Sine", "Rect"}: x = self.A * np.sin(2 * np.pi * t * float(self.ledFreq.text())) if stim == "Sine": title_str = r'Transient Response to Sine Signal' H_str = r'$y_{\sin}[n]$' else: x = self.A * np.sign(x) title_str = r'Transient Response to Rect. Signal' H_str = r'$y_{rect}[n]$' elif stim == "Saw": x = self.A * sig.sawtooth(t * (float(self.ledFreq.text())* 2*np.pi)) title_str = r'Transient Response to Sawtooth Signal' H_str = r'$y_{saw}[n]$' elif stim == "RandN": x = self.A * np.random.randn(N) title_str = r'Transient Response to Gaussian Noise' H_str = r'$y_{gauss}[n]$' elif stim == "RandU": x = self.A * (np.random.rand(N)-0.5) title_str = r'Transient Response to Uniform Noise' H_str = r'$y_{uni}[n]$' else: logger.error('Unknown stimulus "{0}"'.format(stim)) return if len(sos) > 0 and (causal): # has second order sections and is causal h = sig.sosfilt(sos, x) elif (antiCausal): h = sig.filtfilt(self.bb, self.aa, x, -1, None) else: # no second order sections or antiCausals for current filter h = sig.lfilter(self.bb, self.aa, x) dc = sig.freqz(self.bb, self.aa, [0]) if stim == "StepErr": h = h - abs(dc[1]) # subtract DC value from response h = np.real_if_close(h, tol = 1e3) # tol specified in multiples of machine eps self.cmplx = np.any(np.iscomplex(h)) if self.cmplx: h_i = h.imag h = h.real H_i_str = r'$\Im\{$' + H_str + '$\}$' H_str = r'$\Re\{$' + H_str + '$\}$' if log: self.bottom = safe_eval(self.ledLogBottom.text(), self.bottom, return_type='float') self.ledLogBottom.setText(str(self.bottom)) H_str = r'$|$ ' + H_str + '$|$ in dB' h = np.maximum(20 * np.log10(abs(h)), self.bottom) if self.cmplx: h_i = np.maximum(20 * np.log10(abs(h_i)), self.bottom) H_i_str = r'$\log$ ' + H_i_str + ' in dB' else: self.bottom = 0 self.init_axes() #================ Main Plotting Routine ========================= [ml, sl, bl] = self.ax_r.stem(t, h, bottom=self.bottom, markerfmt='o', label = '$h[n]$') stem_fmt = params['mpl_stimuli'] if self.chkPltStim.isChecked(): [ms, ss, bs] = self.ax_r.stem(t, x, bottom=self.bottom, label = 'Stim.', **stem_fmt) ms.set_mfc(stem_fmt['mfc']) ms.set_mec(stem_fmt['mec']) ms.set_ms(stem_fmt['ms']) ms.set_alpha(stem_fmt['alpha']) for stem in ss: stem.set_linewidth(stem_fmt['lw']) stem.set_color(stem_fmt['mec']) stem.set_alpha(stem_fmt['alpha']) bs.set_visible(False) # invisible bottomline expand_lim(self.ax_r, 0.02) self.ax_r.set_title(title_str) if self.cmplx: [ml_i, sl_i, bl_i] = self.ax_i.stem(t, h_i, bottom=self.bottom, markerfmt='d', label = '$h_i[n]$') self.ax_i.set_xlabel(fb.fil[0]['plt_tLabel']) # self.ax_r.get_xaxis().set_ticklabels([]) # removes both xticklabels # plt.setp(ax_r.get_xticklabels(), visible=False) # is shorter but imports matplotlib, set property directly instead: [label.set_visible(False) for label in self.ax_r.get_xticklabels()] self.ax_r.set_ylabel(H_str + r'$\rightarrow $') self.ax_i.set_ylabel(H_i_str + r'$\rightarrow $') else: self.ax_r.set_xlabel(fb.fil[0]['plt_tLabel']) self.ax_r.set_ylabel(H_str + r'$\rightarrow $') if self.ACTIVE_3D: # not implemented / tested yet # plotting the stems for i in range(len(t)): self.ax3d.plot([t[i], t[i]], [h[i], h[i]], [0, h_i[i]], '-', linewidth=2, alpha=.5) # plotting a circle on the top of each stem self.ax3d.plot(t, h, h_i, 'o', markersize=8, markerfacecolor='none', label='$h[n]$') self.ax3d.set_xlabel('x') self.ax3d.set_ylabel('y') self.ax3d.set_zlabel('z') self.redraw()
def _construct_UI(self): self.lblN_points = QLabel(to_html("N", frmt='bi') + " =", self) self.ledN_points = QLineEdit(self) self.ledN_points.setText(str(self.N_points)) self.ledN_points.setToolTip( "<span>Number of points to calculate and display. " "N = 0 tries to choose for you.</span>") self.lblN_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.ledN_start = QLineEdit(self) self.ledN_start.setText(str(self.N_start)) self.ledN_start.setToolTip("<span>First point to plot.</span>") layVlblN = QVBoxLayout() layVlblN.addWidget(self.lblN_start) layVlblN.addWidget(self.lblN_points) layVledN = QVBoxLayout() layVledN.addWidget(self.ledN_start) layVledN.addWidget(self.ledN_points) self.chkLog = QCheckBox("Log. y-axis", self) self.chkLog.setObjectName("chkLog") self.chkLog.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chkLog.setChecked(False) self.chkMarker = QCheckBox("Markers", self) self.chkMarker.setObjectName("chkMarker") self.chkMarker.setToolTip("<span>Show plot markers.</span>") self.chkMarker.setChecked(True) layVchkLogMark = QVBoxLayout() layVchkLogMark.addWidget(self.chkLog) layVchkLogMark.addWidget(self.chkMarker) self.lblLogBottom = QLabel("Bottom = ", self) self.ledLogBottom = QLineEdit(self) self.ledLogBottom.setText(str(self.bottom)) self.ledLogBottom.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbldB = QLabel("dB", self) self.lblPltTime = QLabel("Time: ", self) self.cmbPltTime = QComboBox(self) self.cmbPltTime.addItems(["None", "Stimulus", "Response", "Both"]) qset_cmb_box(self.cmbPltTime, self.plt_time) self.cmbPltTime.setToolTip( "<span>Choose which signals to show in the time domain: " "The stimulus, the filter response or both.</span>") self.lblPltFreq = QLabel("Freq.: ", self) self.cmbPltFreq = QComboBox(self) self.cmbPltFreq.addItems(["None", "Stimulus", "Response", "Both"]) qset_cmb_box(self.cmbPltFreq, self.plt_freq) self.cmbPltFreq.setToolTip( "<span>Choose which signals to show in the frequency domain: " "The stimulus, the filter response or both.</span>") layVlblPlt = QVBoxLayout() layVlblPlt.addWidget(self.lblPltTime) layVlblPlt.addWidget(self.lblPltFreq) layVcmbPlt = QVBoxLayout() layVcmbPlt.addWidget(self.cmbPltTime) layVcmbPlt.addWidget(self.cmbPltFreq) self.lblStimulus = QLabel("Stimulus: ", self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems( ["Pulse", "Step", "StepErr", "Cos", "Sine", "Rect", "Saw"]) self.cmbStimulus.setToolTip("Select stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.lblNoise = QLabel("Noise: ", self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None", "Gauss", "Uniform"]) self.cmbNoise.setToolTip("Select added noise type.") qset_cmb_box(self.cmbNoise, self.noise) layVlblCmb = QVBoxLayout() layVlblCmb.addWidget(self.lblStimulus) layVlblCmb.addWidget(self.lblNoise) layVCmb = QVBoxLayout() layVCmb.addWidget(self.cmbStimulus) layVCmb.addWidget(self.cmbNoise) self.lblAmp1 = QLabel(to_html("A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude.") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html("A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2.") self.ledAmp2.setObjectName("stimAmp2") layVlblAmp = QVBoxLayout() layVlblAmp.addWidget(self.lblAmp1) layVlblAmp.addWidget(self.lblAmp2) layVledAmp = QVBoxLayout() layVledAmp.addWidget(self.ledAmp1) layVledAmp.addWidget(self.ledAmp2) self.lblFreq1 = QLabel(to_html("f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1.") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html("f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2.") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) layVlblfreq = QVBoxLayout() layVlblfreq.addWidget(self.lblFreq1) layVlblfreq.addWidget(self.lblFreq2) layVledfreq = QVBoxLayout() layVledfreq.addWidget(self.ledFreq1) layVledfreq.addWidget(self.ledFreq2) layVlblfreqU = QVBoxLayout() layVlblfreqU.addWidget(self.lblFreqUnit1) layVlblfreqU.addWidget(self.lblFreqUnit2) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layVlblNoiDC = QVBoxLayout() layVlblNoiDC.addWidget(self.lblNoi) layVlblNoiDC.addWidget(self.lblDC) layVledNoiDC = QVBoxLayout() layVledNoiDC.addWidget(self.ledNoi) layVledNoiDC.addWidget(self.ledDC) layHControls = QHBoxLayout() layHControls.addLayout(layVlblN) layHControls.addLayout(layVledN) layHControls.addStretch(2) layHControls.addLayout(layVchkLogMark) layHControls.addStretch(1) layHControls.addWidget(self.lblLogBottom) layHControls.addWidget(self.ledLogBottom) layHControls.addWidget(self.lbldB) layHControls.addStretch(2) layHControls.addLayout(layVlblPlt) layHControls.addLayout(layVcmbPlt) layHControls.addStretch(1) layHControls.addLayout(layVlblCmb) layHControls.addLayout(layVCmb) layHControls.addStretch(1) layHControls.addLayout(layVlblAmp) layHControls.addLayout(layVledAmp) layHControls.addLayout(layVlblfreq) layHControls.addLayout(layVledfreq) layHControls.addLayout(layVlblfreqU) layHControls.addStretch(1) layHControls.addLayout(layVlblNoiDC) layHControls.addLayout(layVledNoiDC) layHControls.addStretch(10) layHControlsF = QHBoxLayout() self.chkLogF = QCheckBox("Log. scale", self) self.chkLogF.setObjectName("chkLogF") self.chkLogF.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chkLogF.setChecked(True) self.lblLogBottomF = QLabel("Bottom = ", self) self.ledLogBottomF = QLineEdit(self) self.ledLogBottomF.setText(str(self.bottom_f)) self.ledLogBottomF.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbldBF = QLabel("dB", self) self.lblWindow = QLabel("Window: ", self) self.cmbWindow = QComboBox(self) self.cmbWindow.addItems([ "Rect", "Triangular", "Hann", "Hamming", "Kaiser", "Flattop", "Chebwin" ]) self.cmbWindow.setToolTip("Select window type.") qset_cmb_box(self.cmbWindow, self.window) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") layHControlsF.addWidget(self.chkLogF) layHControlsF.addWidget(self.lblLogBottomF) layHControlsF.addWidget(self.ledLogBottomF) layHControlsF.addWidget(self.lbldBF) layHControls.addStretch(2) layHControlsF.addWidget(self.lblWindow) layHControlsF.addWidget(self.cmbWindow) layHControlsF.addWidget(self.lblWinPar1) layHControlsF.addWidget(self.ledWinPar1) layHControlsF.addStretch(10) self.wdgHControlsF = QWidget(self) self.wdgHControlsF.setLayout(layHControlsF) #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_signals) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.ledN_start.editingFinished.connect(self.update_N) self.ledN_points.editingFinished.connect(self.update_N) self.chkLog.clicked.connect(self._log_mode) self.ledLogBottom.editingFinished.connect(self._log_mode) self.cmbPltTime.currentIndexChanged.connect(self._update_time_freq) self.cmbPltFreq.currentIndexChanged.connect(self._update_time_freq) self.chkMarker.clicked.connect(self._update_chk_boxes) self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledDC.editingFinished.connect(self._update_DC) self.chkLogF.clicked.connect(self._log_mode) self.ledLogBottomF.editingFinished.connect(self._log_mode) # careful! currentIndexChanged passes the current index to _update_window self.cmbWindow.currentIndexChanged.connect(self._update_window) self.ledWinPar1.editingFinished.connect(self._update_window) # ######################## Main UI Layout ############################ # layout for frame (UI widget) layVMainF = QVBoxLayout() layVMainF.addLayout(layHControls) layVMainF.addWidget(self.wdgHControlsF) # This frame encompasses all UI elements self.frmControls = QFrame(self) self.frmControls.setLayout(layVMainF) layVMain = QVBoxLayout() layVMain.addWidget(self.frmControls) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain)
def _construct_UI(self): """ Intitialize the widget, consisting of: - Matplotlib widget with NavigationToolbar - Frame with control elements """ self.chk_auto_N = QCheckBox(self) self.chk_auto_N.setChecked(False) self.chk_auto_N.setToolTip( "Use number of points from calling routine.") self.lbl_auto_N = QLabel("Auto " + to_html("N", frmt='i')) self.led_N = QLineEdit(self) self.led_N.setText(str(self.N)) self.led_N.setMaximumWidth(70) self.led_N.setToolTip("<span>Number of window data points.</span>") self.chk_log_t = QCheckBox("Log", self) self.chk_log_t.setChecked(False) self.chk_log_t.setToolTip("Display in dB") self.led_log_bottom_t = QLineEdit(self) self.led_log_bottom_t.setText(str(self.bottom_t)) self.led_log_bottom_t.setMaximumWidth(50) self.led_log_bottom_t.setEnabled(self.chk_log_t.isChecked()) self.led_log_bottom_t.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_log_bottom_t = QLabel("dB", self) self.lbl_log_bottom_t.setEnabled(self.chk_log_t.isChecked()) self.chk_norm_f = QCheckBox("Norm", self) self.chk_norm_f.setChecked(True) self.chk_norm_f.setToolTip( "Normalize window spectrum for a maximum of 1.") self.chk_half_f = QCheckBox("Half", self) self.chk_half_f.setChecked(True) self.chk_half_f.setToolTip( "Display window spectrum in the range 0 ... 0.5 f_S.") self.chk_log_f = QCheckBox("Log", self) self.chk_log_f.setChecked(True) self.chk_log_f.setToolTip("Display in dB") self.led_log_bottom_f = QLineEdit(self) self.led_log_bottom_f.setText(str(self.bottom_f)) self.led_log_bottom_f.setMaximumWidth(50) self.led_log_bottom_f.setEnabled(self.chk_log_f.isChecked()) self.led_log_bottom_f.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_log_bottom_f = QLabel("dB", self) self.lbl_log_bottom_f.setEnabled(self.chk_log_f.isChecked()) layHControls = QHBoxLayout() layHControls.addWidget(self.chk_auto_N) layHControls.addWidget(self.lbl_auto_N) layHControls.addWidget(self.led_N) layHControls.addStretch(1) layHControls.addWidget(self.chk_log_t) layHControls.addWidget(self.led_log_bottom_t) layHControls.addWidget(self.lbl_log_bottom_t) layHControls.addStretch(10) layHControls.addWidget(self.chk_norm_f) layHControls.addStretch(1) layHControls.addWidget(self.chk_half_f) layHControls.addStretch(1) layHControls.addWidget(self.chk_log_f) layHControls.addWidget(self.led_log_bottom_f) layHControls.addWidget(self.lbl_log_bottom_f) # self.tblFiltPerf = QTableWidget(self) # self.tblFiltPerf.setAlternatingRowColors(True) # # self.tblFiltPerf.verticalHeader().setVisible(False) # self.tblFiltPerf.horizontalHeader().setHighlightSections(False) # self.tblFiltPerf.horizontalHeader().setFont(bfont) # self.tblFiltPerf.verticalHeader().setHighlightSections(False) # self.tblFiltPerf.verticalHeader().setFont(bfont) self.txtInfoBox = QTextBrowser(self) #---------------------------------------------------------------------- # ### frmControls ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- self.frmControls = QFrame(self) self.frmControls.setObjectName("frmControls") self.frmControls.setLayout(layHControls) #---------------------------------------------------------------------- # ### mplwidget ### # # main widget: Layout layVMainMpl (VBox) is defined with MplWidget, # additional widgets can be added (like self.frmControls) # The widget encompasses all other widgets. #---------------------------------------------------------------------- self.mplwidget = MplWidget(self) self.mplwidget.layVMainMpl.addWidget(self.frmControls) self.mplwidget.layVMainMpl.setContentsMargins(*params['wdg_margins']) #---------------------------------------------------------------------- # ### splitter ### # # This widget encompasses all control subwidgets #---------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.mplwidget) splitter.addWidget(self.txtInfoBox) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 1000]) self.setCentralWidget(splitter) #self.setCentralWidget(self.mplwidget) #---------------------------------------------------------------------- # Set subplots # self.ax = self.mplwidget.fig.subplots(nrows=1, ncols=2) self.ax_t = self.ax[0] self.ax_f = self.ax[1] self.draw() # initial drawing #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.chk_log_f.clicked.connect(self.update_view) self.chk_log_t.clicked.connect(self.update_view) self.led_log_bottom_t.editingFinished.connect(self.update_bottom) self.led_log_bottom_f.editingFinished.connect(self.update_bottom) self.chk_auto_N.clicked.connect(self.draw) self.led_N.editingFinished.connect(self.draw) self.chk_norm_f.clicked.connect(self.draw) self.chk_half_f.clicked.connect(self.update_view) self.mplwidget.mplToolbar.sig_tx.connect(self.process_sig_rx)
def _construct_UI(self): """ Construct the User Interface """ self.layVMain = QVBoxLayout() # Widget main layout f_units = ['f_S', 'f_Ny', 'Hz', 'kHz', 'MHz', 'GHz'] self.t_units = ['', '', 's', 'ms', r'$\mu$s', 'ns'] bfont = QFont() bfont.setBold(True) self.lblUnits=QLabel(self) self.lblUnits.setText("Freq. Unit:") self.lblUnits.setFont(bfont) self.fs_old = fb.fil[0]['f_S'] # store current sampling frequency self.ledF_S = QLineEdit() self.ledF_S.setText(str(fb.fil[0]["f_S"])) self.ledF_S.setObjectName("f_S") self.ledF_S.installEventFilter(self) # filter events self.lblF_S = QLabel(self) self.lblF_S.setText(to_html("f_S", frmt='bi')) self.cmbUnits = QComboBox(self) self.cmbUnits.setObjectName("cmbUnits") self.cmbUnits.addItems(f_units) self.cmbUnits.setToolTip( "Select whether frequencies are specified with respect to \n" "the sampling frequency f_S, to the Nyquist frequency \n" "f_Ny = f_S/2 or as absolute values.") self.cmbUnits.setCurrentIndex(0) # self.cmbUnits.setItemData(0, (0,QColor("#FF333D"),Qt.BackgroundColorRole))# # self.cmbUnits.setItemData(0, (QFont('Verdana', bold=True), Qt.FontRole) fRanges = [("0...½", "half"), ("0...1","whole"), ("-½...½", "sym")] self.cmbFRange = QComboBox(self) self.cmbFRange.setObjectName("cmbFRange") for f in fRanges: self.cmbFRange.addItem(f[0],f[1]) self.cmbFRange.setToolTip("Select frequency range (whole or half).") self.cmbFRange.setCurrentIndex(0) # Combobox resizes with longest entry self.cmbUnits.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbFRange.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butSort = QToolButton(self) self.butSort.setText("Sort") self.butSort.setCheckable(True) self.butSort.setChecked(True) self.butSort.setToolTip("Sort frequencies in ascending order when pushed.") self.butSort.setStyleSheet("QToolButton:checked {font-weight:bold}") self.layHUnits = QHBoxLayout() self.layHUnits.addWidget(self.cmbUnits) self.layHUnits.addWidget(self.cmbFRange) self.layHUnits.addWidget(self.butSort) # Create a gridLayout consisting of QLabel and QLineEdit fields # for setting f_S, the units and the actual frequency specs: self.layGSpecWdg = QGridLayout() # sublayout for spec fields self.layGSpecWdg.addWidget(self.lblF_S,1,0) self.layGSpecWdg.addWidget(self.ledF_S,1,1) self.layGSpecWdg.addWidget(self.lblUnits,0,0) self.layGSpecWdg.addLayout(self.layHUnits,0,1) frmMain = QFrame(self) frmMain.setLayout(self.layGSpecWdg) self.layVMain.addWidget(frmMain) self.layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(self.layVMain) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.cmbUnits.currentIndexChanged.connect(self.update_UI) self.cmbFRange.currentIndexChanged.connect(self._freq_range) self.butSort.clicked.connect(self._store_sort_flag) #---------------------------------------------------------------------- self.update_UI() # first-time initialization
def _construct_UI(self): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- self.lbl_sim_select = QLabel("<b>Simulate</b>", self) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float", "Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip( "<span>Simulate floating-point or fixpoint response." "</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N_points)) self.led_N_points.setToolTip( "<span>Number of points to calculate and display. " "N = 0 tries to choose for you.</span>") self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.but_run = QPushButton("RUN", self) self.but_run.setToolTip("Run fixpoint simulation") self.chk_fx_scale = QCheckBox("Integer scale", self) self.chk_fx_scale.setObjectName("chk_fx_scale") self.chk_fx_scale.setToolTip( "<span>Display data with integer (fixpoint) scale.</span>") self.chk_fx_scale.setChecked(False) self.chk_stim_options = QCheckBox("Stimulus Options", self) self.chk_stim_options.setObjectName("chk_stim_options") self.chk_stim_options.setToolTip( "<span>Show options for stimulus signal.</span>") self.chk_stim_options.setChecked(True) layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.lbl_sim_select) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.but_run) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_fx_scale) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_stim_options) layH_ctrl_run.addStretch(10) #layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- lbl_plt_time_title = QLabel("<b>Time: Show</b>", self) self.lbl_plt_time_resp = QLabel("Response", self) self.cmb_plt_time_resp = QComboBox(self) self.cmb_plt_time_resp.addItems( ["None", "Dots", "Line", "Stem", "Step"]) qset_cmb_box(self.cmb_plt_time_resp, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip( "<span>Choose response plot style.</span>") self.chk_mrk_time_resp = QCheckBox("*", self) self.chk_mrk_time_resp.setChecked(False) self.chk_mrk_time_resp.setToolTip("Use plot markers") self.lbl_plt_time_stim = QLabel("Stimulus", self) self.cmb_plt_time_stim = QComboBox(self) self.cmb_plt_time_stim.addItems( ["None", "Dots", "Line", "Stem", "Step"]) qset_cmb_box(self.cmb_plt_time_stim, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip( "<span>Choose stimulus plot style.</span>") self.chk_mrk_time_stim = QCheckBox("*", self) self.chk_mrk_time_stim.setChecked(False) self.chk_mrk_time_stim.setToolTip("Use plot markers") self.chk_log_time = QCheckBox("dB", self) self.chk_log_time.setObjectName("chk_log_time") self.chk_log_time.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_time.setChecked(False) self.lbl_log_bottom_time = QLabel("Bottom = ", self) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_dB_time = QLabel("dB", self) self.chk_win_time = QCheckBox("FFT Window", self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip( "<span>Show FFT windowing function.</span>") self.chk_win_time.setChecked(False) self.chk_fx_range = QCheckBox("Min/max.", self) self.chk_fx_range.setObjectName("chk_fx_range") self.chk_fx_range.setToolTip( "<span>Display limits of fixpoint range.</span>") self.chk_fx_range.setChecked(False) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(lbl_plt_time_title) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_resp) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) layH_ctrl_time.addWidget(self.chk_mrk_time_resp) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) layH_ctrl_time.addWidget(self.chk_mrk_time_stim) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_log_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_log_bottom_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) layH_ctrl_time.addWidget(self.lbl_dB_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_fx_range) layH_ctrl_time.addStretch(10) #layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- lbl_plt_freq_title = QLabel("<b>Freq: Show</b>", self) self.lbl_plt_freq_stim = QLabel("Stimulus", self) self.cmb_plt_freq_stim = QComboBox(self) self.cmb_plt_freq_stim.addItems( ["None", "Dots", "Line", "Stem", "Step"]) qset_cmb_box(self.cmb_plt_freq_stim, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip( "<span>Choose stimulus plot style.</span>") self.chk_mrk_freq_stim = QCheckBox("*", self) self.chk_mrk_freq_stim.setChecked(False) self.chk_mrk_freq_stim.setToolTip("Use plot markers") self.lbl_plt_freq_resp = QLabel("Response", self) self.cmb_plt_freq_resp = QComboBox(self) self.cmb_plt_freq_resp.addItems( ["None", "Dots", "Line", "Stem", "Step"]) qset_cmb_box(self.cmb_plt_freq_resp, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip( "<span>Choose response plot style.</span>") self.chk_mrk_freq_resp = QCheckBox("*", self) self.chk_mrk_freq_resp.setChecked(False) self.chk_mrk_freq_resp.setToolTip("Use plot markers") self.chk_log_freq = QCheckBox("dB", self) self.chk_log_freq.setObjectName("chk_log_freq") self.chk_log_freq.setToolTip( "<span>Logarithmic scale for y-axis.</span>") self.chk_log_freq.setChecked(True) self.lbl_log_bottom_freq = QLabel("Bottom = ", self) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setToolTip( "<span>Minimum display value for log. scale.</span>") self.lbl_dB_freq = QLabel("dB", self) self.lbl_win_fft = QLabel("Window: ", self) self.cmb_win_fft = QComboBox(self) self.cmb_win_fft.addItems([ "Rect", "Triangular", "Hann", "Hamming", "Kaiser", "Flattop", "Chebwin" ]) self.cmb_win_fft.setToolTip("Select window type.") qset_cmb_box(self.cmb_win_fft, self.window) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") self.chk_win_freq = QCheckBox("Show", self) self.chk_win_freq.setObjectName("chk_win_freq") self.chk_win_freq.setToolTip( "<span>Show FFT windowing function.</span>") self.chk_win_freq.setChecked(False) layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(lbl_plt_freq_title) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) layH_ctrl_freq.addWidget(self.chk_mrk_freq_resp) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) layH_ctrl_freq.addWidget(self.chk_mrk_freq_stim) layH_ctrl_freq.addWidget(self.chk_log_freq) layH_ctrl_freq.addWidget(self.lbl_log_bottom_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addWidget(self.lbl_dB_freq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.lbl_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft) layH_ctrl_freq.addWidget(self.lblWinPar1) layH_ctrl_freq.addWidget(self.ledWinPar1) layH_ctrl_freq.addWidget(self.chk_win_freq) layH_ctrl_freq.addStretch(10) #layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # --------------------------------------------------------------- # Controls for stimuli # --------------------------------------------------------------- lbl_title_stim = QLabel("<b>Stimulus:</b>", self) self.lblStimulus = QLabel("Signal: ", self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems( ["None", "Pulse", "Step", "StepErr", "Cos", "Sine", "Rect", "Saw"]) self.cmbStimulus.setToolTip("Select stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.lblNoise = QLabel("Noise: ", self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None", "Gauss", "Uniform"]) self.cmbNoise.setToolTip("Select added noise type.") qset_cmb_box(self.cmbNoise, self.noise) layVlblCmb = QVBoxLayout() layVlblCmb.addWidget(self.lblStimulus) layVlblCmb.addWidget(self.lblNoise) layVCmb = QVBoxLayout() layVCmb.addWidget(self.cmbStimulus) layVCmb.addWidget(self.cmbNoise) self.lblAmp1 = QLabel(to_html("A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude.") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html("A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2.") self.ledAmp2.setObjectName("stimAmp2") layVlblAmp = QVBoxLayout() layVlblAmp.addWidget(self.lblAmp1) layVlblAmp.addWidget(self.lblAmp2) layVledAmp = QVBoxLayout() layVledAmp.addWidget(self.ledAmp1) layVledAmp.addWidget(self.ledAmp2) self.lblFreq1 = QLabel(to_html("f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1.") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html("f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2.") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) layVlblfreq = QVBoxLayout() layVlblfreq.addWidget(self.lblFreq1) layVlblfreq.addWidget(self.lblFreq2) layVledfreq = QVBoxLayout() layVledfreq.addWidget(self.ledFreq1) layVledfreq.addWidget(self.ledFreq2) layVlblfreqU = QVBoxLayout() layVlblfreqU.addWidget(self.lblFreqUnit1) layVlblfreqU.addWidget(self.lblFreqUnit2) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layVlblNoiDC = QVBoxLayout() layVlblNoiDC.addWidget(self.lblNoi) layVlblNoiDC.addWidget(self.lblDC) layVledNoiDC = QVBoxLayout() layVledNoiDC.addWidget(self.ledNoi) layVledNoiDC.addWidget(self.ledDC) layH_ctrl_stim = QHBoxLayout() layH_ctrl_stim.addWidget(lbl_title_stim) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblCmb) layH_ctrl_stim.addLayout(layVCmb) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblAmp) layH_ctrl_stim.addLayout(layVledAmp) layH_ctrl_stim.addLayout(layVlblfreq) layH_ctrl_stim.addLayout(layVledfreq) layH_ctrl_stim.addLayout(layVlblfreqU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblNoiDC) layH_ctrl_stim.addLayout(layVledNoiDC) layH_ctrl_stim.addStretch(10) self.wdg_ctrl_stim = QWidget(self) self.wdg_ctrl_stim.setLayout(layH_ctrl_stim) # --------- end stimuli --------------------------------- #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) # --- frequency control --- #self.chkLogF.clicked.connect(self._log_mode_freq) #self.ledLogBottomF.editingFinished.connect(self._log_mode_freq) # careful! currentIndexChanged passes the current index to _update_win_fft self.cmb_win_fft.currentIndexChanged.connect(self._update_win_fft) self.ledWinPar1.editingFinished.connect(self._update_win_fft) # --- stimulus control --- self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledDC.editingFinished.connect(self._update_DC)
def _construct_UI(self, **kwargs): """ Construct widget """ dict_ui = { 'label': '', 'label_q': 'Quant.', 'tip_q': 'Select the kind of quantization.', 'cmb_q': ['round', 'fix', 'floor'], 'cur_q': 'round', 'label_ov': 'Ovfl.', 'tip_ov': 'Select overflow behaviour.', 'cmb_ov': ['wrap', 'sat'], 'cur_ov': 'wrap', 'enabled': True, 'visible': True } #: default widget settings if 'quant' in self.q_dict and self.q_dict['quant'] in dict_ui['cmb_q']: dict_ui['cur_q'] = self.q_dict['quant'] if 'ovfl' in self.q_dict and self.q_dict['ovfl'] in dict_ui['cmb_ov']: dict_ui['cur_ov'] = self.q_dict['ovfl'] for key, val in kwargs.items(): dict_ui.update({key: val}) # dict_ui.update(map(kwargs)) # same as above? lblQuant = QLabel(dict_ui['label_q'], self) self.cmbQuant = QComboBox(self) self.cmbQuant.addItems(dict_ui['cmb_q']) qset_cmb_box(self.cmbQuant, dict_ui['cur_q']) self.cmbQuant.setToolTip(dict_ui['tip_q']) self.cmbQuant.setObjectName('quant') lblOvfl = QLabel(dict_ui['label_ov'], self) self.cmbOvfl = QComboBox(self) self.cmbOvfl.addItems(dict_ui['cmb_ov']) qset_cmb_box(self.cmbOvfl, dict_ui['cur_ov']) self.cmbOvfl.setToolTip(dict_ui['tip_ov']) self.cmbOvfl.setObjectName('ovfl') # ComboBox size is adjusted automatically to fit the longest element self.cmbQuant.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbOvfl.setSizeAdjustPolicy(QComboBox.AdjustToContents) layH = QHBoxLayout() if dict_ui['label'] != "": lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) layH.addWidget(lblW) layH.addStretch() layH.addWidget(lblOvfl) layH.addWidget(self.cmbOvfl) #layH.addStretch(1) layH.addWidget(lblQuant) layH.addWidget(self.cmbQuant) layH.setContentsMargins(0, 0, 0, 0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0, 0, 0, 0) #*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # INITIAL SETTINGS #---------------------------------------------------------------------- self.ovfl = qget_cmb_box(self.cmbOvfl, data=False) self.quant = qget_cmb_box(self.cmbQuant, data=False) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.cmbOvfl.currentIndexChanged.connect(self.ui2dict) self.cmbQuant.currentIndexChanged.connect(self.ui2dict)
def _construct_UI(self, **kwargs): """ Construct widget from quantization dict, individual settings and the default dict below """ # default settings dict_ui = { 'label': 'WI.WF', 'lbl_sep': '.', 'max_led_width': 30, 'WI': 0, 'WI_len': 2, 'tip_WI': 'Number of integer bits', 'WF': 15, 'WF_len': 2, 'tip_WF': 'Number of fractional bits', 'enabled': True, 'visible': True, 'fractional': True, 'combo_visible': False, 'combo_items': ['auto', 'full', 'man'], 'tip_combo': 'Calculate Acc. width.', 'lock_visible': False, 'tip_lock': 'Lock input/output quantization.' } #: default values if self.q_dict: dict_ui.update(self.q_dict) for k, v in kwargs.items(): if k not in dict_ui: logger.warning("Unknown key {0}".format(k)) else: dict_ui.update({k: v}) if not dict_ui['fractional']: dict_ui['WF'] = 0 self.WI = dict_ui['WI'] self.WF = dict_ui['WF'] self.W = int(self.WI + self.WF + 1) if self.q_dict: self.q_dict.update({'WI': self.WI, 'WF': self.WF, 'W': self.W}) else: self.q_dict = {'WI': self.WI, 'WF': self.WF, 'W': self.W} lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) self.cmbW = QComboBox(self) self.cmbW.addItems(dict_ui['combo_items']) self.cmbW.setVisible(dict_ui['combo_visible']) self.cmbW.setToolTip(dict_ui['tip_combo']) self.cmbW.setObjectName("cmbW") self.butLock = QPushButton(self) self.butLock.setCheckable(True) self.butLock.setChecked(False) self.butLock.setVisible(dict_ui['lock_visible']) self.butLock.setToolTip(dict_ui['tip_lock']) self.ledWI = QLineEdit(self) self.ledWI.setToolTip(dict_ui['tip_WI']) self.ledWI.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWI.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points(?) self.ledWI.setObjectName("WI") lblDot = QLabel(dict_ui['lbl_sep'], self) lblDot.setVisible(dict_ui['fractional']) self.ledWF = QLineEdit(self) self.ledWF.setToolTip(dict_ui['tip_WF']) self.ledWF.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWF.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points(?) self.ledWF.setVisible(dict_ui['fractional']) self.ledWF.setObjectName("WF") layH = QHBoxLayout() layH.addWidget(lblW) layH.addStretch() layH.addWidget(self.cmbW) layH.addWidget(self.butLock) layH.addWidget(self.ledWI) layH.addWidget(lblDot) layH.addWidget(self.ledWF) layH.setContentsMargins(0, 0, 0, 0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0, 5, 0, 0) #*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # INITIAL SETTINGS #---------------------------------------------------------------------- self.ledWI.setText(qstr(dict_ui['WI'])) self.ledWF.setText(qstr(dict_ui['WF'])) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.ledWI.editingFinished.connect(self.ui2dict) self.ledWF.editingFinished.connect(self.ui2dict) self.butLock.clicked.connect(self.but_clicked) self.cmbW.currentIndexChanged.connect(self.ui2dict) # initialize button icon self.but_clicked(self.butLock.isChecked())
def _construct_UI(self): # ----------- --------------------------------------------------- # Run control widgets # --------------------------------------------------------------- self.lbl_sim_select = QLabel("<b>Simulate</b>", self) self.cmb_sim_select = QComboBox(self) self.cmb_sim_select.addItems(["Float","Fixpoint"]) qset_cmb_box(self.cmb_sim_select, "Float") self.cmb_sim_select.setToolTip("<span>Simulate floating-point or fixpoint response." "</span>") self.lbl_N_points = QLabel(to_html("N", frmt='bi') + " =", self) self.led_N_points = QLineEdit(self) self.led_N_points.setText(str(self.N_points)) self.led_N_points.setToolTip("<span>Number of points to calculate and display. " "N = 0 tries to choose for you.</span>") self.lbl_N_start = QLabel(to_html("N_0", frmt='bi') + " =", self) self.led_N_start = QLineEdit(self) self.led_N_start.setText(str(self.N_start)) self.led_N_start.setToolTip("<span>First point to plot.</span>") self.but_run = QPushButton("RUN", self) self.but_run.setToolTip("Run fixpoint simulation") self.chk_fx_scale = QCheckBox("Integer scale", self) self.chk_fx_scale.setObjectName("chk_fx_scale") self.chk_fx_scale.setToolTip("<span>Display data with integer (fixpoint) scale.</span>") self.chk_fx_scale.setChecked(False) self.chk_stim_options = QCheckBox("Stimulus Options", self) self.chk_stim_options.setObjectName("chk_stim_options") self.chk_stim_options.setToolTip("<span>Show options for stimulus signal.</span>") self.chk_stim_options.setChecked(True) layH_ctrl_run = QHBoxLayout() layH_ctrl_run.addWidget(self.lbl_sim_select) layH_ctrl_run.addWidget(self.cmb_sim_select) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_start) layH_ctrl_run.addWidget(self.led_N_start) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.lbl_N_points) layH_ctrl_run.addWidget(self.led_N_points) layH_ctrl_run.addStretch(1) layH_ctrl_run.addWidget(self.but_run) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_fx_scale) layH_ctrl_run.addStretch(2) layH_ctrl_run.addWidget(self.chk_stim_options) layH_ctrl_run.addStretch(10) #layH_ctrl_run.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_run = QWidget(self) self.wdg_ctrl_run.setLayout(layH_ctrl_run) # --- end of run control ---------------------------------------- # ----------- --------------------------------------------------- # Controls for time domain # --------------------------------------------------------------- lbl_plt_time_title = QLabel("<b>Time: Show</b>", self) self.lbl_plt_time_stim = QLabel("Stimulus", self) self.cmb_plt_time_stim = QComboBox(self) self.cmb_plt_time_stim.addItems(["None","Dots","Line","Stem", "Step"]) qset_cmb_box(self.cmb_plt_time_stim, self.plt_time_stim) self.cmb_plt_time_stim.setToolTip("<span>Choose stimulus plot style.</span>") self.chk_mrk_time_stim = QCheckBox("*", self) self.chk_mrk_time_stim.setChecked(False) self.chk_mrk_time_stim.setToolTip("Use plot markers") self.lbl_plt_time_resp = QLabel("Response", self) self.cmb_plt_time_resp = QComboBox(self) self.cmb_plt_time_resp.addItems(["None","Dots","Line","Stem", "Step"]) qset_cmb_box(self.cmb_plt_time_resp, self.plt_time_resp) self.cmb_plt_time_resp.setToolTip("<span>Choose response plot style.</span>") self.chk_mrk_time_resp = QCheckBox("*", self) self.chk_mrk_time_resp.setChecked(False) self.chk_mrk_time_resp.setToolTip("Use plot markers") self.chk_log_time = QCheckBox("dB", self) self.chk_log_time.setObjectName("chk_log_time") self.chk_log_time.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chk_log_time.setChecked(False) self.lbl_log_bottom_time = QLabel("Bottom = ", self) self.led_log_bottom_time = QLineEdit(self) self.led_log_bottom_time.setText(str(self.bottom_t)) self.led_log_bottom_time.setToolTip("<span>Minimum display value for log. scale.</span>") self.lbl_dB_time = QLabel("dB", self) self.chk_win_time = QCheckBox("FFT Window", self) self.chk_win_time.setObjectName("chk_win_time") self.chk_win_time.setToolTip("<span>Show FFT windowing function.</span>") self.chk_win_time.setChecked(False) self.chk_fx_range = QCheckBox("Min/max.", self) self.chk_fx_range.setObjectName("chk_fx_range") self.chk_fx_range.setToolTip("<span>Display limits of fixpoint range.</span>") self.chk_fx_range.setChecked(False) layH_ctrl_time = QHBoxLayout() layH_ctrl_time.addWidget(lbl_plt_time_title) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.cmb_plt_time_resp) layH_ctrl_time.addWidget(self.chk_mrk_time_resp) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_plt_time_stim) layH_ctrl_time.addWidget(self.cmb_plt_time_stim) layH_ctrl_time.addWidget(self.chk_mrk_time_stim) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_log_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.lbl_log_bottom_time) layH_ctrl_time.addWidget(self.led_log_bottom_time) layH_ctrl_time.addWidget(self.lbl_dB_time) layH_ctrl_time.addStretch(1) layH_ctrl_time.addWidget(self.chk_win_time) layH_ctrl_time.addStretch(2) layH_ctrl_time.addWidget(self.chk_fx_range) layH_ctrl_time.addStretch(10) #layH_ctrl_time.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_time = QWidget(self) self.wdg_ctrl_time.setLayout(layH_ctrl_time) # ---- end time domain ------------------ # --------------------------------------------------------------- # Controls for frequency domain # --------------------------------------------------------------- lbl_plt_freq_title = QLabel("<b>Freq: Show</b>", self) self.lbl_plt_freq_stim = QLabel("Stimulus", self) self.cmb_plt_freq_stim = QComboBox(self) self.cmb_plt_freq_stim.addItems(["None","Dots","Line","Stem", "Step"]) qset_cmb_box(self.cmb_plt_freq_stim, self.plt_freq_stim) self.cmb_plt_freq_stim.setToolTip("<span>Choose stimulus plot style.</span>") self.chk_mrk_freq_stim = QCheckBox("*", self) self.chk_mrk_freq_stim.setChecked(False) self.chk_mrk_freq_stim.setToolTip("Use plot markers") self.lbl_plt_freq_resp = QLabel("Response", self) self.cmb_plt_freq_resp = QComboBox(self) self.cmb_plt_freq_resp.addItems(["None","Dots","Line","Stem", "Step"]) qset_cmb_box(self.cmb_plt_freq_resp, self.plt_freq_resp) self.cmb_plt_freq_resp.setToolTip("<span>Choose response plot style.</span>") self.chk_mrk_freq_resp = QCheckBox("*", self) self.chk_mrk_freq_resp.setChecked(False) self.chk_mrk_freq_resp.setToolTip("Use plot markers") self.chk_log_freq = QCheckBox("dB", self) self.chk_log_freq.setObjectName("chk_log_freq") self.chk_log_freq.setToolTip("<span>Logarithmic scale for y-axis.</span>") self.chk_log_freq.setChecked(True) self.lbl_log_bottom_freq = QLabel("Bottom = ", self) self.led_log_bottom_freq = QLineEdit(self) self.led_log_bottom_freq.setText(str(self.bottom_f)) self.led_log_bottom_freq.setToolTip("<span>Minimum display value for log. scale.</span>") self.lbl_dB_freq = QLabel("dB", self) self.lbl_win_fft = QLabel("Window: ", self) self.cmb_win_fft = QComboBox(self) self.cmb_win_fft.addItems(["Rect","Triangular","Hann","Hamming","Kaiser", "Flattop", "Chebwin"]) self.cmb_win_fft.setToolTip("Select window type.") qset_cmb_box(self.cmb_win_fft, self.window) self.lblWinPar1 = QLabel("Param1") self.ledWinPar1 = QLineEdit(self) self.ledWinPar1.setText("1") self.ledWinPar1.setObjectName("ledWinPar1") self.chk_win_freq = QCheckBox("Show", self) self.chk_win_freq.setObjectName("chk_win_freq") self.chk_win_freq.setToolTip("<span>Show FFT windowing function.</span>") self.chk_win_freq.setChecked(False) layH_ctrl_freq = QHBoxLayout() layH_ctrl_freq.addWidget(lbl_plt_freq_title) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_resp) layH_ctrl_freq.addWidget(self.cmb_plt_freq_resp) layH_ctrl_freq.addWidget(self.chk_mrk_freq_resp) layH_ctrl_freq.addStretch(1) layH_ctrl_freq.addWidget(self.lbl_plt_freq_stim) layH_ctrl_freq.addWidget(self.cmb_plt_freq_stim) layH_ctrl_freq.addWidget(self.chk_mrk_freq_stim) layH_ctrl_freq.addWidget(self.chk_log_freq) layH_ctrl_freq.addWidget(self.led_log_bottom_freq) layH_ctrl_freq.addWidget(self.lbl_dB_freq) layH_ctrl_freq.addStretch(2) layH_ctrl_freq.addWidget(self.lbl_win_fft) layH_ctrl_freq.addWidget(self.cmb_win_fft) layH_ctrl_freq.addWidget(self.lblWinPar1) layH_ctrl_freq.addWidget(self.ledWinPar1) layH_ctrl_freq.addWidget(self.chk_win_freq) layH_ctrl_freq.addStretch(10) #layH_ctrl_freq.setContentsMargins(*params['wdg_margins']) self.wdg_ctrl_freq = QWidget(self) self.wdg_ctrl_freq.setLayout(layH_ctrl_freq) # ---- end Frequency Domain ------------------ # --------------------------------------------------------------- # Controls for stimuli # --------------------------------------------------------------- lbl_title_stim = QLabel("<b>Stimulus:</b>", self) self.lblStimulus = QLabel("Signal: ", self) self.cmbStimulus = QComboBox(self) self.cmbStimulus.addItems(["None","Pulse","Step","StepErr","Cos","Sine","Rect","Saw"]) self.cmbStimulus.setToolTip("Select stimulus type.") qset_cmb_box(self.cmbStimulus, self.stim) self.lblNoise = QLabel("Noise: ", self) self.cmbNoise = QComboBox(self) self.cmbNoise.addItems(["None","Gauss","Uniform"]) self.cmbNoise.setToolTip("Select added noise type.") qset_cmb_box(self.cmbNoise, self.noise) layVlblCmb = QVBoxLayout() layVlblCmb.addWidget(self.lblStimulus) layVlblCmb.addWidget(self.lblNoise) layVCmb = QVBoxLayout() layVCmb.addWidget(self.cmbStimulus) layVCmb.addWidget(self.cmbNoise) self.lblAmp1 = QLabel(to_html("A_1", frmt='bi') + " =", self) self.ledAmp1 = QLineEdit(self) self.ledAmp1.setText(str(self.A1)) self.ledAmp1.setToolTip("Stimulus amplitude.") self.ledAmp1.setObjectName("stimAmp1") self.lblAmp2 = QLabel(to_html("A_2", frmt='bi') + " =", self) self.ledAmp2 = QLineEdit(self) self.ledAmp2.setText(str(self.A2)) self.ledAmp2.setToolTip("Stimulus amplitude 2.") self.ledAmp2.setObjectName("stimAmp2") layVlblAmp = QVBoxLayout() layVlblAmp.addWidget(self.lblAmp1) layVlblAmp.addWidget(self.lblAmp2) layVledAmp = QVBoxLayout() layVledAmp.addWidget(self.ledAmp1) layVledAmp.addWidget(self.ledAmp2) self.lblFreq1 = QLabel(to_html("f_1", frmt='bi') + " =", self) self.ledFreq1 = QLineEdit(self) self.ledFreq1.setText(str(self.f1)) self.ledFreq1.setToolTip("Stimulus frequency 1.") self.ledFreq1.setObjectName("stimFreq1") self.lblFreqUnit1 = QLabel("f_S", self) self.lblFreq2 = QLabel(to_html("f_2", frmt='bi') + " =", self) self.ledFreq2 = QLineEdit(self) self.ledFreq2.setText(str(self.f2)) self.ledFreq2.setToolTip("Stimulus frequency 2.") self.ledFreq2.setObjectName("stimFreq2") self.lblFreqUnit2 = QLabel("f_S", self) layVlblfreq = QVBoxLayout() layVlblfreq.addWidget(self.lblFreq1) layVlblfreq.addWidget(self.lblFreq2) layVledfreq = QVBoxLayout() layVledfreq.addWidget(self.ledFreq1) layVledfreq.addWidget(self.ledFreq2) layVlblfreqU = QVBoxLayout() layVlblfreqU.addWidget(self.lblFreqUnit1) layVlblfreqU.addWidget(self.lblFreqUnit2) self.lblNoi = QLabel("not initialized", self) self.ledNoi = QLineEdit(self) self.ledNoi.setText(str(self.noi)) self.ledNoi.setToolTip("not initialized") self.ledNoi.setObjectName("stimNoi") self.lblDC = QLabel(to_html("DC =", frmt='bi'), self) self.ledDC = QLineEdit(self) self.ledDC.setText(str(self.DC)) self.ledDC.setToolTip("DC Level") self.ledDC.setObjectName("stimDC") layVlblNoiDC = QVBoxLayout() layVlblNoiDC.addWidget(self.lblNoi) layVlblNoiDC.addWidget(self.lblDC) layVledNoiDC = QVBoxLayout() layVledNoiDC.addWidget(self.ledNoi) layVledNoiDC.addWidget(self.ledDC) layH_ctrl_stim = QHBoxLayout() layH_ctrl_stim.addWidget(lbl_title_stim) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblCmb) layH_ctrl_stim.addLayout(layVCmb) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblAmp) layH_ctrl_stim.addLayout(layVledAmp) layH_ctrl_stim.addLayout(layVlblfreq) layH_ctrl_stim.addLayout(layVledfreq) layH_ctrl_stim.addLayout(layVlblfreqU) layH_ctrl_stim.addStretch(1) layH_ctrl_stim.addLayout(layVlblNoiDC) layH_ctrl_stim.addLayout(layVledNoiDC) layH_ctrl_stim.addStretch(10) self.wdg_ctrl_stim = QWidget(self) self.wdg_ctrl_stim.setLayout(layH_ctrl_stim) # --------- end stimuli --------------------------------- #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- # --- run control --- self.led_N_start.editingFinished.connect(self.update_N) self.led_N_points.editingFinished.connect(self.update_N) # --- frequency control --- #self.chkLogF.clicked.connect(self._log_mode_freq) #self.ledLogBottomF.editingFinished.connect(self._log_mode_freq) # careful! currentIndexChanged passes the current index to _update_win_fft self.cmb_win_fft.currentIndexChanged.connect(self._update_win_fft) self.ledWinPar1.editingFinished.connect(self._update_win_fft) # --- stimulus control --- self.cmbStimulus.currentIndexChanged.connect(self._enable_stim_widgets) self.cmbNoise.currentIndexChanged.connect(self._update_noi) self.ledNoi.editingFinished.connect(self._update_noi) self.ledAmp1.editingFinished.connect(self._update_amp1) self.ledAmp2.editingFinished.connect(self._update_amp2) self.ledDC.editingFinished.connect(self._update_DC)
def _update_param2(): self.lblWinPar2.setText( to_html(self.win_dict['par'][0][1] + " =", frmt='bi')) self.ledWinPar2.setText(str(self.win_dict['par'][2][1])) self.ledWinPar2.setToolTip(self.win_dict['par'][4][1])
def _construct_UI(self, **kwargs): """ Construct widget from default settings, """ # default settings dict_ui = { 'label': 'WI.WF', 'lbl_sep': '.', 'max_led_width': 30, 'WI': 0, 'WI_len': 2, 'tip_WI': 'Number of integer bits', 'WF': 15, 'WF_len': 2, 'tip_WF': 'Number of fractional bits', 'enabled': True, 'visible': True, 'fractional': True } #: default values for k, v in kwargs.items(): if k not in dict_ui: logger.warning("Unknown key {0}".format(k)) else: dict_ui.update({k: v}) # dict_ui.update(map(kwargs)) # same as above? if not dict_ui['fractional']: dict_ui['WF'] = 0 self.WI = dict_ui['WI'] self.WF = dict_ui['WF'] lblW = QLabel(to_html(dict_ui['label'], frmt='bi'), self) self.ledWI = QLineEdit(self) self.ledWI.setToolTip(dict_ui['tip_WI']) self.ledWI.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWI.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points(?) lblDot = QLabel(dict_ui['lbl_sep'], self) lblDot.setVisible(dict_ui['fractional']) self.ledWF = QLineEdit(self) self.ledWF.setToolTip(dict_ui['tip_WF']) self.ledWF.setMaxLength(dict_ui['WI_len']) # maximum of 2 digits self.ledWF.setFixedWidth( dict_ui['max_led_width']) # width of lineedit in points(?) self.ledWF.setVisible(dict_ui['fractional']) layH = QHBoxLayout() layH.addWidget(lblW) layH.addStretch() layH.addWidget(self.ledWI) layH.addWidget(lblDot) layH.addWidget(self.ledWF) layH.setContentsMargins(0, 0, 0, 0) frmMain = QFrame(self) frmMain.setLayout(layH) layVMain = QVBoxLayout() # Widget main layout layVMain.addWidget(frmMain) layVMain.setContentsMargins(0, 5, 0, 0) #*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # INITIAL SETTINGS #---------------------------------------------------------------------- self.ledWI.setText(qstr(dict_ui['WI'])) self.ledWF.setText(qstr(dict_ui['WF'])) frmMain.setEnabled(dict_ui['enabled']) frmMain.setVisible(dict_ui['visible']) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.ledWI.editingFinished.connect(self.ui2dict) self.ledWF.editingFinished.connect(self.ui2dict)
def draw_impz(self): """ (Re-)draw the figure """ f_unit = fb.fil[0]['freq_specs_unit'] if f_unit in {"f_S", "f_Ny"}: unit_frmt = "i" # italic else: unit_frmt = None self.ui.lblFreqUnit1.setText(to_html(f_unit, frmt=unit_frmt)) self.ui.lblFreqUnit2.setText(to_html(f_unit, frmt=unit_frmt)) N_start = self.ui.N_start self.load_fs() self.init_axes() #================ Main Plotting Routine ========================= if self.ui.chkMarker.isChecked(): mkfmt_r = 'o' mkfmt_i = 'd' else: mkfmt_r = mkfmt_i = ' ' if self.cmplx: H_i_str = r'$\Im\{$' + self.H_str + '$\}$ in V' H_str = r'$\Re\{$' + self.H_str + '$\}$ in V' else: H_str = self.H_str + 'in V' if self.ui.chkLog.isChecked(): H_str = r'$|$ ' + H_str + '$|$ in dBV' y = np.maximum(20 * np.log10(abs(self.y)), self.ui.bottom) if self.cmplx: y_i = np.maximum(20 * np.log10(abs(self.y_i)), self.ui.bottom) H_i_str = r'$\log$ ' + H_i_str + ' in dBV' else: self.ui.bottom = 0 y = self.y y_i = self.y_i if self.ui.plt_time in {"Response", "Both"}: [ml, sl, bl] = self.ax_r.stem(self.t[N_start:], y[N_start:], bottom=self.ui.bottom, markerfmt=mkfmt_r, label = '$y[n]$') if self.ui.plt_time in {"Stimulus", "Both"}: stem_fmt = params['mpl_stimuli'] [ms, ss, bs] = self.ax_r.stem(self.t[N_start:], self.x[N_start:], bottom=self.ui.bottom, label = 'Stim.', **stem_fmt) ms.set_mfc(stem_fmt['mfc']) ms.set_mec(stem_fmt['mec']) ms.set_ms(stem_fmt['ms']) ms.set_alpha(stem_fmt['alpha']) for stem in ss: stem.set_linewidth(stem_fmt['lw']) stem.set_color(stem_fmt['mec']) stem.set_alpha(stem_fmt['alpha']) bs.set_visible(False) # invisible bottomline if self.cmplx and self.ui.plt_time in {"Response", "Both"}: [ml_i, sl_i, bl_i] = self.ax_i.stem(self.t[N_start:], y_i[N_start:], bottom=self.ui.bottom, markerfmt=mkfmt_i, label = '$y_i[n]$') self.ax_i.set_xlabel(fb.fil[0]['plt_tLabel']) # self.ax_r.get_xaxis().set_ticklabels([]) # removes both xticklabels # plt.setp(ax_r.get_xticklabels(), visible=False) # is shorter but imports matplotlib, set property directly instead: [label.set_visible(False) for label in self.ax_r.get_xticklabels()] self.ax_r.set_ylabel(H_str + r'$\rightarrow $') self.ax_i.set_ylabel(H_i_str + r'$\rightarrow $') else: self.ax_r.set_xlabel(fb.fil[0]['plt_tLabel']) self.ax_r.set_ylabel(H_str + r'$\rightarrow $') self.ax_r.set_title(self.title_str) self.ax_r.set_xlim([self.t[N_start],self.t[self.ui.N_end-1]]) expand_lim(self.ax_r, 0.02) # plot frequency domain ========================================= if self.ui.plt_freq != "None": plt_response = self.ui.plt_freq in {"Response","Both"} plt_stimulus = self.ui.plt_freq in {"Stimulus","Both"} if plt_response and not plt_stimulus: XY_str = r'$|Y(\mathrm{e}^{\mathrm{j} \Omega})|$' elif not plt_response and plt_stimulus: XY_str = r'$|X(\mathrm{e}^{\mathrm{j} \Omega})|$' else: XY_str = r'$|X,Y(\mathrm{e}^{\mathrm{j} \Omega})|$' F = np.fft.fftfreq(self.ui.N, d = 1. / fb.fil[0]['f_S']) if plt_stimulus: X = self.X.copy()/np.sqrt(2) # enforce deep copy and convert to RMS self.Px = np.sum(np.square(self.X)) if fb.fil[0]['freqSpecsRangeType'] == 'half': X[1:] = 2 * X[1:] # correct for single-sided spectrum (except DC) if plt_response: Y = self.Y.copy()/np.sqrt(2) # enforce deep copy and convert to RMS self.Py = np.sum(np.square(self.Y)) if fb.fil[0]['freqSpecsRangeType'] == 'half': Y[1:] = 2 * Y[1:] # correct for single-sided spectrum (except DC) if self.ui.chkLogF.isChecked(): unit = unit_P = "dBW" unit_nenbw = "dB" nenbw = 10 * np.log10(self.ui.nenbw) if plt_stimulus: X = np.maximum(20 * np.log10(X), self.ui.bottom_f) self.Px = 10*np.log10(self.Px) if plt_response: Y = np.maximum(20 * np.log10(Y), self.ui.bottom_f) self.Py = 10*np.log10(self.Py) else: unit = "Vrms" unit_P = "W" unit_nenbw = "bins" nenbw = self.ui.nenbw XY_str = XY_str + ' in ' + unit if fb.fil[0]['freqSpecsRangeType'] == 'sym': # shift X, Y and F by f_S/2 if plt_response: Y = np.fft.fftshift(Y) if plt_stimulus: X = np.fft.fftshift(X) F = np.fft.fftshift(F) elif fb.fil[0]['freqSpecsRangeType'] == 'half': # only use the first half of X, Y and F if plt_response: Y = Y[0:self.ui.N//2] if plt_stimulus: X = X[0:self.ui.N//2] F = F[0:self.ui.N//2] else: # fb.fil[0]['freqSpecsRangeType'] == 'whole' # plot for F = 0 ... 1 F = np.fft.fftshift(F) + fb.fil[0]['f_S']/2. handles = [] labels = [] if plt_stimulus: h, = self.ax_fft.plot(F, X, color =(0.5,0.5,0.5,0.5), lw=2) handles.append(h) labels.append("$P_X$ = {0:.3g} {1}".format(self.Px, unit_P)) if plt_response: h, = self.ax_fft.plot(F, Y) handles.append(h) labels.append("$P_Y$ = {0:.3g} {1}".format(self.Py, unit_P)) labels.append("$NENBW$ = {0:.4g} {1}".format(nenbw, unit_nenbw)) labels.append("$CGAIN$ = {0:.4g}".format(self.ui.scale)) handles.append(mpl_patches.Rectangle((0, 0), 1, 1, fc="white",ec="white", lw=0)) handles.append(mpl_patches.Rectangle((0, 0), 1, 1, fc="white",ec="white", lw=0)) self.ax_fft.legend(handles, labels, loc='best', fontsize = 'small', fancybox=True, framealpha=0.5) self.ax_fft.set_xlabel(fb.fil[0]['plt_fLabel']) self.ax_fft.set_ylabel(XY_str) self.ax_fft.set_xlim(fb.fil[0]['freqSpecsRange']) if self.ui.plt_time == "None": self.ax_fft.set_title(self.title_str) # no time window, print title here if self.ui.chkLogF.isChecked(): # create second axis scaled for noise power scale self.ax_fft_noise = self.ax_fft.twinx() self.ax_fft_noise.is_twin = True corr = 10*np.log10(self.ui.N / self.ui.nenbw) mn, mx = self.ax_fft.get_ylim() self.ax_fft_noise.set_ylim(mn+corr, mx+corr) self.ax_fft_noise.set_ylabel(r'$P_N$ in dBW') if self.ACTIVE_3D: # not implemented / tested yet # plotting the stems for i in range(N_start, self.ui.N_end): self.ax3d.plot([self.t[i], self.t[i]], [y[i], y[i]], [0, y_i[i]], '-', linewidth=2, alpha=.5) # plotting a circle on the top of each stem self.ax3d.plot(self.t[N_start:], y[N_start:], y_i[N_start:], 'o', markersize=8, markerfacecolor='none', label='$y[n]$') self.ax3d.set_xlabel('x') self.ax3d.set_ylabel('y') self.ax3d.set_zlabel('z') self.redraw()
def __init__(self, parent): """ Pass instance `parent` of parent class (FilterCoeffs) """ super(Input_PZ_UI, self).__init__(parent) # self.parent = parent # instance of the parent (not the base) class self.eps = 1.e-4 # # tolerance value for e.g. setting P/Z to zero """ Intitialize the widget, consisting of: - top chkbox row - coefficient table - two bottom rows with action buttons """ self.bfont = QFont() self.bfont.setBold(True) self.bifont = QFont() self.bifont.setBold(True) self.bifont.setItalic(True) # q_icon_size = QSize(20, 20) # optional, size is derived from butEnable # --------------------------------------------- # UI Elements for controlling the display # --------------------------------------------- self.butEnable = QPushButton(self) self.butEnable.setIcon(QIcon(':/circle-x.svg')) q_icon_size = self.butEnable.iconSize( ) # <- set this for manual icon sizing self.butEnable.setIconSize(q_icon_size) self.butEnable.setCheckable(True) self.butEnable.setChecked(True) self.butEnable.setToolTip( "<span>Show / hide poles and zeros in an editable table." " For high order systems, the table display might be slow.</span>") self.cmbPZFrmt = QComboBox(self) pz_formats = [('Cartesian', 'cartesian'), ('Polar (rad)', 'polar_rad'), ('Polar (pi)', 'polar_pi'), ('Polar (°)', 'polar_deg')] # display text, data # π: u'3C0, °: u'B0, ∠: u'2220 for pz in pz_formats: self.cmbPZFrmt.addItem(*pz) self.cmbPZFrmt.setSizeAdjustPolicy(QComboBox.AdjustToContents) # self.cmbPZFrmt.setEnabled(False) self.cmbPZFrmt.setToolTip( "<span>Set display format for poles and zeros to" " either cartesian (x + jy) or polar (r * ∠ Ω)." " Type 'o' for '°', '<' for '∠' and 'pi' for 'π'.</span>" ) self.spnDigits = QSpinBox(self) self.spnDigits.setRange(0, 16) self.spnDigits.setToolTip("Number of digits to display.") self.lblDigits = QLabel("Digits", self) self.lblDigits.setFont(self.bifont) self.cmbCausal = QComboBox(self) causal_types = ['Causal', 'Acausal', 'Anticausal'] for cs in causal_types: self.cmbCausal.addItem(cs) qset_cmb_box(self.cmbCausal, 'Causal') self.cmbCausal.setToolTip( '<span>Set the system type. Not implemented yet.</span>') self.cmbCausal.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.cmbCausal.setEnabled(False) layHDisplay = QHBoxLayout() layHDisplay.setAlignment(Qt.AlignLeft) layHDisplay.addWidget(self.butEnable) layHDisplay.addWidget(self.cmbPZFrmt) layHDisplay.addWidget(self.spnDigits) layHDisplay.addWidget(self.lblDigits) layHDisplay.addWidget(self.cmbCausal) layHDisplay.addStretch() # --------------------------------------------- # UI Elements for setting the gain # --------------------------------------------- self.lblNorm = QLabel(to_html("Normalize:", frmt='bi'), self) self.cmbNorm = QComboBox(self) self.cmbNorm.addItems(["None", "1", "Max"]) self.cmbNorm.setToolTip( "<span>Set the gain <i>k</i> so that H(f)<sub>max</sub> is " "either 1 or the max. of the previous system.</span>") self.lblGain = QLabel(to_html("k =", frmt='bi'), self) self.ledGain = QLineEdit(self) self.ledGain.setToolTip( "<span>Specify gain factor <i>k</i>" " (only possible for Normalize = 'None').</span>") self.ledGain.setText(str(1.)) self.ledGain.setObjectName("ledGain") layHGain = QHBoxLayout() layHGain.addWidget(self.lblNorm) layHGain.addWidget(self.cmbNorm) layHGain.addWidget(self.lblGain) layHGain.addWidget(self.ledGain) layHGain.addStretch() # --------------------------------------------- # UI Elements for loading / storing / manipulating cells and rows # --------------------------------------------- # self.cmbFilterType = QComboBox(self) # self.cmbFilterType.setObjectName("comboFilterType") # self.cmbFilterType.setToolTip("Select between IIR and FIR filte for manual entry.") # self.cmbFilterType.addItems(["FIR","IIR"]) # self.cmbFilterType.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.butAddCells = QPushButton(self) self.butAddCells.setIcon(QIcon(':/row_insert_above.svg')) self.butAddCells.setIconSize(q_icon_size) self.butAddCells.setToolTip( "<SPAN>Select cells to insert a new cell above each selected cell. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, add a row at the end.</SPAN>") self.butDelCells = QPushButton(self) self.butDelCells.setIcon(QIcon(':/row_delete.svg')) self.butDelCells.setIconSize(q_icon_size) self.butDelCells.setToolTip( "<SPAN>Delete selected cell(s) from the table. " "Use <SHIFT> or <CTRL> to select multiple cells. " "When nothing is selected, delete the last row.</SPAN>") self.butSave = QPushButton(self) self.butSave.setIcon(QIcon(':/upload.svg')) self.butSave.setIconSize(q_icon_size) self.butSave.setToolTip( "<span>Copy P/Z table to filter dict and update all plots and widgets.</span>" ) self.butLoad = QPushButton(self) self.butLoad.setIcon(QIcon(':/download.svg')) self.butLoad.setIconSize(q_icon_size) self.butLoad.setToolTip("Reload P/Z table from filter dict.") self.butClear = QPushButton(self) self.butClear.setIcon(QIcon(':/trash.svg')) self.butClear.setIconSize(q_icon_size) self.butClear.setToolTip("Clear all table entries.") self.butFromTable = QPushButton(self) self.butFromTable.setIconSize(q_icon_size) self.butToTable = QPushButton(self) self.butToTable.setIconSize(q_icon_size) self._set_load_save_icons() butSettingsClipboard = QPushButton(self) butSettingsClipboard.setIcon(QIcon(':/settings.svg')) butSettingsClipboard.setIconSize(q_icon_size) butSettingsClipboard.setToolTip( "<span>Select CSV format and whether " "to copy to/from clipboard or file.</span>") layHButtonsCoeffs1 = QHBoxLayout() # layHButtonsCoeffs1.addWidget(self.cmbFilterType) layHButtonsCoeffs1.addWidget(self.butAddCells) layHButtonsCoeffs1.addWidget(self.butDelCells) layHButtonsCoeffs1.addWidget(self.butClear) layHButtonsCoeffs1.addWidget(self.butSave) layHButtonsCoeffs1.addWidget(self.butLoad) layHButtonsCoeffs1.addWidget(self.butFromTable) layHButtonsCoeffs1.addWidget(self.butToTable) layHButtonsCoeffs1.addWidget(butSettingsClipboard) layHButtonsCoeffs1.addStretch() #------------------------------------------------------------------- # Eps / set zero settings # --------------------------------------------------------------------- self.butSetZero = QPushButton("= 0", self) self.butSetZero.setToolTip( "<span>Set selected poles / zeros = 0 with a magnitude < ε. " "When nothing is selected, test the whole table.</span>") self.butSetZero.setIconSize(q_icon_size) lblEps = QLabel(self) lblEps.setText("<b><i>for ε</i> <</b>") self.ledEps = QLineEdit(self) self.ledEps.setToolTip("Specify tolerance value.") layHButtonsCoeffs2 = QHBoxLayout() layHButtonsCoeffs2.addWidget(self.butSetZero) layHButtonsCoeffs2.addWidget(lblEps) layHButtonsCoeffs2.addWidget(self.ledEps) layHButtonsCoeffs2.addStretch() # ######################## Main UI Layout ############################ # layout for frame (UI widget) layVMainF = QVBoxLayout() layVMainF.addLayout(layHDisplay) layVMainF.addLayout(layHGain) layVMainF.addLayout(layHButtonsCoeffs1) layVMainF.addLayout(layHButtonsCoeffs2) # This frame encompasses all UI elements frmMain = QFrame(self) frmMain.setLayout(layVMainF) layVMain = QVBoxLayout() layVMain.setAlignment( Qt.AlignTop) # this affects only the first widget (intended here) layVMain.addWidget(frmMain) layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #--- set initial values from dict ------------ self.spnDigits.setValue(params['FMT_pz']) self.ledEps.setText(str(self.eps)) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs #---------------------------------------------------------------------- butSettingsClipboard.clicked.connect(self._copy_options) self.sig_rx.connect(self._set_load_save_icons)