Example #1
0
    def _save_dict(self):
        """
        Save the coefficient register `self.ba` to the filter dict `fb.fil[0]['ba']`.
        """

        logger.debug("_save_dict called")

        fb.fil[0]['N'] = max(len(self.ba[0]), len(self.ba[1])) - 1

        self.ui2qdict()

        if fb.fil[0]['ft'] == 'IIR':
            fb.fil[0]['fc'] = 'Manual_IIR'
        else:
            fb.fil[0]['fc'] = 'Manual_FIR'

        # save, check and convert coeffs, check filter type
        fil_save(fb.fil[0], self.ba, 'ba', __name__)

        if __name__ == '__main__':
            self.load_dict()  # only needed for stand-alone test

        self.sig_tx.emit({'sender': __name__, 'data_changed': 'input_coeffs'})
        # -> input_tab_widgets

        qstyle_widget(self.ui.butSave, 'normal')
Example #2
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
            if fb.fil[0]['freq_specs_unit'] in {"f_S", "f_Ny"}:
                self.qlabels[i].setText(to_html(new_labels[i], frmt='bi'))
            else:  # convert 'F' to 'f' for frequencies in Hz
                self.qlabels[i].setText(
                    to_html(new_labels[i][0].lower() + new_labels[i][1:],
                            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
Example #3
0
    def _copy_to_table(self):
        """
        Read data from clipboard / file and copy it to `self.ba` as float / cmplx
        # TODO: More checks for swapped row <-> col, single values, wrong data type ...
        """
        data_str = qtext2table(
            self, 'ba',
            title="Import Filter Coefficients")  # returns ndarray of str
        if data_str is None:  # file operation has been aborted or some other error
            return

        logger.debug(
            "importing data: dim - shape = {0} - {1} - {2}\n{3}".format(
                type(data_str), np.ndim(data_str), np.shape(data_str),
                data_str))

        conv = self.myQ.frmt2float  # frmt2float_vec?
        frmt = self.myQ.frmt

        if np.ndim(data_str) > 1:
            num_cols, num_rows = np.shape(data_str)
            orientation_horiz = num_cols > num_rows  # need to transpose data
        elif np.ndim(data_str) == 1:
            num_rows = len(data_str)
            num_cols = 1
            orientation_horiz = False
        else:
            logger.error("Imported data is a single value or None.")
            return None
        logger.info("_copy_to_table: c x r = {0} x {1}".format(
            num_cols, num_rows))
        if orientation_horiz:
            self.ba = [[], []]
            for c in range(num_cols):
                self.ba[0].append(conv(data_str[c][0], frmt))
                if num_rows > 1:
                    self.ba[1].append(conv(data_str[c][1], frmt))
            if num_rows > 1:
                self._filter_type(ftype='IIR')
            else:
                self._filter_type(ftype='FIR')
        else:
            self.ba[0] = [conv(s, frmt) for s in data_str[0]]
            if num_cols > 1:
                self.ba[1] = [conv(s, frmt) for s in data_str[1]]
                self._filter_type(ftype='IIR')
            else:
                self.ba[1] = [1]
                self._filter_type(ftype='FIR')

        self.ba[0] = np.asarray(self.ba[0])
        self.ba[1] = np.asarray(self.ba[1])

        self._equalize_ba_length()
        qstyle_widget(self.ui.butSave, 'changed')
        self._refresh_table()
Example #4
0
 def _store_gain(self, source):
     """
     When the textfield of `source` has been edited (flag `self.spec_edited` =  True),
     store it in the shadow dict. This is triggered by `QEvent.focusOut` or
     RETURN key.
     """
     if self.spec_edited:
         self.zpk[2] = safe_eval(source.text(), alt_expr=str(self.zpk[2]))
         qstyle_widget(self.ui.butSave, 'changed')
         self.spec_edited = False  # reset flag
Example #5
0
    def load_dict(self):
        """
        Load all entries from filter dict fb.fil[0]['zpk'] into the Zero/Pole/Gain list
        self.zpk and update the display via `self._refresh_table()`.
        The explicit np.array( ... ) statement enforces a deep copy of fb.fil[0],
        otherwise the filter dict would be modified inadvertedly. `dtype=object`
        needs to be specified to create a numpy array from the nested lists with
        differing lengths without creating the deprecation warning

        "Creating an ndarray from ragged nested sequences (which is a list-or-tuple of
        lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated."

        The filter dict fb.fil[0]['zpk'] is a list of numpy float ndarrays for z / p / k values
        `self.zpk` is an array of float ndarrays with different lengths of z / p / k subarrays 
        to allow adding / deleting items.
        """
        self.zpk = np.array(fb.fil[0]['zpk'],
                            dtype=object)  # this enforces a deep copy
        qstyle_widget(self.ui.butSave, 'normal')
        self._refresh_table()