Exemple #1
0
    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))
Exemple #2
0
    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))
Exemple #3
0
    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> = &sigma;<sup>2</sup></span>")
            elif self.noise == 'uniform':
                self.lblNoi.setText(to_html("&Delta; =", 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> = &Delta;<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'})
Exemple #4
0
    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 &lt; <i>f</i> &lt; <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
Exemple #5
0
    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()
Exemple #6
0
    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
Exemple #7
0
    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)
Exemple #9
0
        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))
Exemple #10
0
 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("&sigma; =", frmt='bi'))
             self.ledNoi.setToolTip("<span>Standard deviation of statistical process,"
                                    "noise power is <i>P</i> = &sigma;<sup>2</sup></span>")
         elif self.noise == 'uniform':
             self.lblNoi.setText(to_html("&Delta; =", 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> = &Delta;<sup>2</sup>/12.</span>")
     self.sig_tx.emit({'sender':__name__, 'data_changed':'noi'})
Exemple #11
0
 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))
Exemple #12
0
 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))
Exemple #13
0
    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 +
                                             " (&gt; 0).</span>")
            elif "pb" in new_labels[i].lower():
                self.qlineedit[i].setToolTip(
                    "<span>Maximum ripple (&gt; 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
Exemple #14
0
    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 &lt; <i>f</i> &lt; <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
Exemple #15
0
    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 + " (&gt; 0).</span>")
            elif "pb" in new_labels[i].lower():
                self.qlineedit[i].setToolTip("<span>Maximum ripple (&gt; 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
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
    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)
Exemple #19
0
    def write(self, msg):
        if not self.signalsBlocked():
            msg = to_html(msg,frmt='log')

            self.messageWritten.emit(msg)
Exemple #20
0
    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 * &ang; &Omega;)."
                                  " Type 'o' for '&deg;', '&lt;' for '&ang;' and 'pi' for '&pi;'.</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 &lt;SHIFT&gt; or &lt;CTRL&gt; 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 &lt;SHIFT&gt; or &lt;CTRL&gt; 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 &lt; &epsilon;. "
        "When nothing is selected, test the whole table.</span>")
        self.butSetZero.setIconSize(q_icon_size)

        lblEps = QLabel(self)
        lblEps.setText("<b><i>for &epsilon;</i> &lt;</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)
Exemple #21
0
    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("&phi;_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("&deg;", frmt='b'), self)

        self.lblPhi2 = QLabel(to_html("&phi;_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("&deg;", 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)
Exemple #22
0
    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()
Exemple #23
0
    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)
Exemple #24
0
    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)
Exemple #25
0
    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
Exemple #26
0
        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))
Exemple #27
0
    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())
Exemple #30
0
    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)
Exemple #31
0
 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])
Exemple #32
0
    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)
Exemple #33
0
    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()
Exemple #34
0
    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 * &ang; &Omega;)."
            " Type 'o' for '&deg;', '&lt;' for '&ang;' and 'pi' for '&pi;'.</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 &lt;SHIFT&gt; or &lt;CTRL&gt; 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 &lt;SHIFT&gt; or &lt;CTRL&gt; 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 &lt; &epsilon;. "
            "When nothing is selected, test the whole table.</span>")
        self.butSetZero.setIconSize(q_icon_size)

        lblEps = QLabel(self)
        lblEps.setText("<b><i>for &epsilon;</i> &lt;</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)