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._store_q_settings() 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')
def _save_entries(self): """ Save the values from self.ba to the filter ba dict. """ logger.debug("_save_entries called") fb.fil[0]['N'] = max(len(self.ba[0]), len(self.ba[1])) - 1 fb.fil[0]["q_coeff"] = { 'WI': int(self.ledWI.text()), 'WF': int(self.ledWF.text()), 'quant': self.cmbQQuant.currentText(), 'ovfl': self.cmbQOvfl.currentText(), 'frmt': self.cmbFormat.currentText(), 'point': self.chkRadixPoint.isChecked() } # save, check and convert coeffs, check filter type fil_save(fb.fil[0], self.ba, 'ba', __name__) if fb.fil[0]['ft'] == 'IIR': fb.fil[0]['fc'] = 'Manual_IIR' else: fb.fil[0]['fc'] = 'Manual_FIR' if __name__ == '__main__': self.load_dict() # only needed for stand-alone test self.sigFilterDesigned.emit() # -> filter_specs # -> input_tab_widgets -> pyfdax -> plt_tab_widgets.updateAll() qstyle_widget(self.butSave, 'normal')
def _save_entries(self): """ Save the values from self.zpk to the filter PZ dict, the QLineEdit for setting the gain has to be treated separately. """ logger.debug("_save_entries called") fb.fil[0]['N'] = len(self.zpk[0]) if np.any(self.zpk[1]): # any non-zero poles? fb.fil[0]['fc'] = 'Manual_IIR' else: fb.fil[0]['fc'] = 'Manual_FIR' fil_save(fb.fil[0], self.zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_dict() # only needed for stand-alone test self.sigFilterDesigned.emit() # -> filter_specs # -> input_tab_widgets -> pyfdax -> plt_tab_widgets.updateAll() logger.debug("b,a = %s\n\n" "zpk = %s\n" % (pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk'])))
def _save_entries(self): """ Read table entries and save the values to the filter PZ dict """ logger.debug("=====================\nInputPZ._save_entries called") zpk = [] num_rows = self.tblPZ.rowCount() logger.debug("nrows = %d" % num_rows) #iterate over both columns for col in range(2): rows = [] for row in range(num_rows): item = self.tblPZ.item(row, col) if item: if item.text() != "": rows.append(simple_eval(item.text())) else: rows.append(0.) zpk.append(rows) zpk.append(simple_eval(self.ledGain.text())) # append k factor to zpk fb.fil[0]['N'] = num_rows if np.any(zpk[1]): fb.fil[0]['ft'] = 'IIR' fb.fil[0]['fc'] = 'Manual_IIR' self.cmbFilterType.setCurrentIndex(1) # set to "IIR" else: fb.fil[0]['ft'] = 'FIR' fb.fil[0]['fc'] = 'Manual_FIR' self.cmbFilterType.setCurrentIndex(0) # set to "FIR" fil_save(fb.fil[0], zpk, 'zpk', __name__) # save & convert to 'ba' if self.chkNorm.isChecked(): # set gain factor k (zpk[2]) in such a way that the max. filter # gain remains unchanged # TODO: Comparison against Hmax is not robust, need to find another anchor [w, H] = freqz(fb.fil[0]['ba'][0], fb.fil[0]['ba'][1]) # (bb, aa) Hmax = max(abs(H)) if not np.isfinite(Hmax) or Hmax > 1e4: Hmax = 1. zpk[2] = zpk[2] * self.Hmax_last / max(abs(H)) fil_save(fb.fil[0], zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_entries() # only needed for stand-alone test self.sigFilterDesigned.emit() logger.debug("_save_entries - coeffients / zpk updated:\n" "b,a = %s\n\n" "zpk = %s\n" % (pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk'])))
def _save_dict(self): """ Save the coefficient register `self.ba` to the filter dict `fb.fil[0]['ba']`. """ logger.debug("_save_entries called") fb.fil[0]['N'] = max(len(self.ba[0]), len(self.ba[1])) - 1 self._store_q_settings() 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.sigFilterDesigned.emit() # -> filter_specs # -> input_tab_widgets -> pyfdax -> plt_tab_widgets.updateAll() qstyle_widget(self.ui.butSave, 'normal')
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._store_q_settings() 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')
def _save_entries(self): """ Save the values from self.zpk to the filter PZ dict, the QLineEdit for setting the gain has to be treated separately. """ logger.debug("_save_entries called") fb.fil[0]['N'] = len(self.zpk[0]) if np.any(self.zpk[1]): # any non-zero poles? fb.fil[0]['fc'] = 'Manual_IIR' else: fb.fil[0]['fc'] = 'Manual_FIR' fil_save(fb.fil[0], self.zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_dict() # only needed for stand-alone test self.sigFilterDesigned.emit() # -> filter_specs # -> input_tab_widgets -> pyfdax -> plt_tab_widgets.updateAll() logger.debug("b,a = %s\n\n" "zpk = %s\n" %(pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk']) ))
def _save_entries(self): """ Save the values from self.zpk to the filter PZ dict, the QLineEdit for setting the gain has to be treated separately. """ logger.debug("_save_entries called") fb.fil[0]['N'] = len(self.zpk[0]) if np.any(self.zpk[1]): # any non-zero poles? fb.fil[0]['fc'] = 'Manual_IIR' else: fb.fil[0]['fc'] = 'Manual_FIR' fil_save(fb.fil[0], self.zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_dict() # only needed for stand-alone test self.sig_tx.emit({'sender':__name__, 'data_changed':'input_pz'}) # -> input_tab_widgets qstyle_widget(self.ui.butSave, 'normal') logger.debug("b,a = {0}\n\n" "zpk = {1}\n" .format(pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk']) ))
def _save_entries(self): """ Save the values from self.zpk to the filter PZ dict, the QLineEdit for setting the gain has to be treated separately. """ logger.debug("_save_entries called") fb.fil[0]['N'] = len(self.zpk[0]) if np.any(self.zpk[1]): # any non-zero poles? fb.fil[0]['fc'] = 'Manual_IIR' else: fb.fil[0]['fc'] = 'Manual_FIR' fil_save(fb.fil[0], self.zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_dict() # only needed for stand-alone test self.sig_tx.emit({'sender': __name__, 'data_changed': 'input_pz'}) # -> input_tab_widgets qstyle_widget(self.ui.butSave, 'normal') logger.debug("b,a = {0}\n\n" "zpk = {1}\n".format(pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk'])))
def store_entries(self): """ Read out coefficients table and save the values to filter 'coeffs' and 'zpk' dicts. Is called when clicking the <Save> button, triggers a recalculation and replot of all plot widgets. """ coeffs = [] num_rows, num_cols = self.tblCoeff.rowCount( ), self.tblCoeff.columnCount() logger.debug("store_entries: \n%s rows x %s cols" % (num_rows, num_cols)) if self.cmbFilterType.currentText() == 'IIR': fb.fil[0]['ft'] = 'IIR' fb.fil[0]['fc'] = 'Manual_IIR' self.cmbFilterType.setCurrentIndex(1) # set to "IIR" else: fb.fil[0]['ft'] = 'FIR' fb.fil[0]['fc'] = 'Manual_FIR' self.cmbFilterType.setCurrentIndex(0) # set to "FIR" # if num_cols > 1: # IIR for col in range(num_cols): rows = [] for row in range(num_rows): item = self.tblCoeff.item(row, col) if item: if item.text() != "": rows.append(simple_eval(item.text())) else: rows.append(0.) # rows.append(float(item.text()) if item else 0.) if num_cols == 1: coeffs = rows else: coeffs.append(rows) # type: list num_cols x num_rows fb.fil[0]["N"] = num_rows - 1 fb.fil[0]["q_coeff"] = { 'QI': int(self.ledQuantI.text()), 'QF': int(self.ledQuantF.text()), 'quant': self.cmbQQuant.currentText(), 'ovfl': self.cmbQOvfl.currentText(), 'frmt': self.cmbQFormat.currentText() } fil_save(fb.fil[0], coeffs, 'ba', __name__) logger.debug("store_entries - coeffients / zpk updated:\n" "b,a = %s\n\n" "zpk = %s\n" % (pformat(fb.fil[0]['ba']), pformat(fb.fil[0]['zpk']))) self.sigFilterDesigned.emit( ) # -> input_widgets -> pyFDA -> pltWidgets.updateAll()
def _save(self, fil_dict, arg): """ Convert between poles / zeros / gain, filter coefficients (polynomes) and second-order sections and store all available formats in the passed dictionary 'fil_dict'. """ fil_save(fil_dict, arg, self.FRMT, __name__) if str(fil_dict['fo']) == 'min': fil_dict['N'] = self.N - 1 # yes, update filterbroker
def _save(self, fil_dict, arg): """ Convert between poles / zeros / gain, filter coefficients (polynomes) and second-order sections and store all available formats in the passed dictionary 'fil_dict'. """ fil_save(fil_dict, arg, self.FRMT, __name__) try: # has the order been calculated by a "min" filter design? fil_dict['N'] = self.N # yes, update filterbroker except AttributeError: pass
def _save(self, fil_dict): """ Convert between poles / zeros / gain, filter coefficients (polynomes) and second-order sections and store all available formats in the passed dictionary 'fil_dict'. """ if 'zpk' in FRMT: fil_save(fil_dict, self.zpk, 'zpk', __name__, convert=False) if 'ba' in FRMT: fil_save(fil_dict, self.b, 'ba', __name__, convert=False) fil_convert(fil_dict, FRMT) if str(fil_dict['fo']) == 'min': fil_dict['N'] = self.N # yes, update filterbroker
def _save_entries(self): """ Read table entries and save the values to the filter PZ dict """ logger.debug("=====================\nInputPZ._save_entries called") zpk = [] num_rows = self.tblPZ.rowCount() logger.debug("nrows = %d" % num_rows) #iterate over both columns for col in range(2): rows = [] for row in range(num_rows): item = self.tblPZ.item(row, col) if item: if item.text() != "": rows.append(simple_eval(item.text())) else: rows.append(0.) zpk.append(rows) zpk.append(simple_eval(self.ledGain.text())) # append k factor to zpk fb.fil[0]["N"] = num_rows fil_save(fb.fil[0], zpk, 'zpk', __name__) # save & convert to 'ba' if self.chkNorm.isChecked(): # set gain factor k (zpk[2]) in such a way that the max. filter # gain remains unchanged # TODO: Comparison against Hmax is not robust, need to find another anchor [w, H] = freqz(fb.fil[0]['ba'][0], fb.fil[0]['ba'][1]) # (bb, aa) Hmax = max(abs(H)) if not np.isfinite(Hmax) or Hmax > 1e4: Hmax = 1. zpk[2] = zpk[2] * self.Hmax_last / max(abs(H)) fil_save(fb.fil[0], zpk, 'zpk', __name__) # save with new gain if __name__ == '__main__': self.load_entries() # only needed for stand-alone test self.sigFilterDesigned.emit() if self.DEBUG: print("ZPK - coeffs:", fb.fil[0]['ba']) print("ZPK - zpk:", fb.fil[0]['zpk']) print("ZPK updated!")
def _save(self, fil_dict, arg): """ First design initial elliptic filter meeting sqRoot Amp specs; - Then create residue vector from poles/zeros; - Then square filter (k,p,z and dc,p,r) to get zero phase filter; - Then Convert results of filter design to all available formats (pz, pr, ba, sos) and store them in the global filter dictionary. Corner frequencies and order calculated for minimum filter order are also stored to allow for an easy subsequent manual filter optimization. """ fil_save(fil_dict, arg, self.FRMT, __name__) # For min. filter order algorithms, update filter dict with calculated # new values for filter order N and corner frequency(s) F_PBC fil_dict['N'] = self.N if str(fil_dict['fo']) == 'min': if str(fil_dict['rt']) == 'LP' or str(fil_dict['rt']) == 'HP': # HP or LP - single corner frequency fil_dict['F_PB'] = self.F_PBC / 2. else: # BP or BS - two corner frequencies fil_dict['F_PB'] = self.F_PBC[0] / 2. fil_dict['F_PB2'] = self.F_PBC[1] / 2. # Now generate poles/residues for custom file save of new parameters if (not self.manual): z = fil_dict['zpk'][0] p = fil_dict['zpk'][1] k = fil_dict['zpk'][2] n = len(z) gain, residues = self._partial(k, p, z, n) pA, zA, gn, pC, rC = self._sqCausal(k, p, z, gain, residues, n) fil_dict['rpk'] = [rC, pC, gn] # save antiCausal b,a (nonReciprocal) also [easier to compute h(n) try: fil_dict['baA'] = sig.zpk2tf(zA, pA, k) except Exception as e: logger.error(e) # 'rpk' is our signal that this is a non-Causal filter with zero phase # inserted into fil dictionary after fil_save and convert self.sigFiltChanged.emit()
def _save(self, fil_dict, arg): """ First design initial elliptic filter meeting sqRoot Amp specs; - Then create residue vector from poles/zeros; - Then square filter (k,p,z and dc,p,r) to get zero phase filter; - Then Convert results of filter design to all available formats (pz, pr, ba, sos) and store them in the global filter dictionary. Corner frequencies and order calculated for minimum filter order are also stored to allow for an easy subsequent manual filter optimization. """ fil_save(fil_dict, arg, self.FRMT, __name__) # For min. filter order algorithms, update filter dict with calculated # new values for filter order N and corner frequency(s) F_PBC fil_dict['N'] = self.N if str(fil_dict['fo']) == 'min': if str(fil_dict['rt']) == 'LP' or str(fil_dict['rt']) == 'HP': # HP or LP - single corner frequency fil_dict['F_PB'] = self.F_PBC / 2. else: # BP or BS - two corner frequencies fil_dict['F_PB'] = self.F_PBC[0] / 2. fil_dict['F_PB2'] = self.F_PBC[1] / 2. # Now generate poles/residues for custom file save of new parameters if (not self.manual): z = fil_dict['zpk'][0] p = fil_dict['zpk'][1] k = fil_dict['zpk'][2] n = len(z) gain, residues = self._partial (k, p, z, n) pA, zA, gn, pC, rC = self._sqCausal (k, p, z, gain, residues, n) fil_dict['rpk'] = [rC, pC, gn] # save antiCausal b,a (nonReciprocal) also [easier to compute h(n) try: fil_dict['baA'] = sig.zpk2tf(zA, pA, k) except Exception as e: logger.error(e) # 'rpk' is our signal that this is a non-Causal filter with zero phase # inserted into fil dictionary after fil_save and convert # sig_tx -> select_filter -> filter_specs self.sig_tx.emit({'sender':__name__, 'filt_changed':'ellip_zero'})
def _save(self, fil_dict, arg): """ Convert results of filter design to all available formats (pz, ba, sos) and store them in the global filter dictionary. Corner frequencies and order calculated for minimum filter order are also stored to allow for an easy subsequent manual filter optimization. """ fil_save(fil_dict, arg, self.FRMT, __name__) # For min. filter order algorithms, update filter dictionary with calculated # new values for filter order N and corner frequency(s) F_PBC fil_dict['N'] = self.N # always save, might have been limited by _test_N if str(fil_dict['fo']) == 'min': if str(fil_dict['rt']) == 'LP' or str(fil_dict['rt']) == 'HP': fil_dict['F_C'] = self.F_PBC / 2. # HP or LP - single corner frequency else: # BP or BS - two corner frequencies fil_dict['F_C'] = self.F_PBC[0] / 2. fil_dict['F_C2'] = self.F_PBC[1] / 2.
def _save(self, fil_dict): """ Save MA-filters both in 'zpk' and 'ba' format; no conversion has to be performed except maybe deleting an 'sos' entry from an earlier filter design. """ if 'zpk' in self.FRMT: fil_save(fil_dict, self.zpk, 'zpk', __name__, convert = False) if 'ba' in self.FRMT: fil_save(fil_dict, self.b, 'ba', __name__, convert = False) fil_convert(fil_dict, self.FRMT) # always update filter dict and LineEdit, in case the design algorithm # has changed the number of delays: fil_dict['N'] = self.delays * self.stages # updated filter order self.led_delays.setText(str(self.delays)) # updated number of delays self._store_entries()