From 8e39df793623ed62a1d4f23a05548a81914ad959 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 21 Nov 2010 19:41:59 -0500 Subject: Updating PSD function for some newer matplotlib interfacing. --- gr-utils/src/python/gr_plot_psd.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_plot_psd.py b/gr-utils/src/python/gr_plot_psd.py index 0e3dbecd9..f3535d321 100755 --- a/gr-utils/src/python/gr_plot_psd.py +++ b/gr-utils/src/python/gr_plot_psd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007,2008 Free Software Foundation, Inc. +# Copyright 2007,2008,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -35,6 +35,7 @@ except ImportError: from optparse import OptionParser from scipy import log10 +from gnuradio.eng_option import eng_option class gr_plot_psd: def __init__(self, datatype, filename, options): @@ -100,10 +101,10 @@ class gr_plot_psd: ''' Need to do this here and plot later so we can do the fftshift ''' overlap = self.psdfftsize/4 winfunc = scipy.blackman - psd,freq = self.sp_psd.psd(iq, self.psdfftsize, self.sample_rate, - window = lambda d: d*winfunc(self.psdfftsize), - noverlap = overlap, visible=False) - psd = 10.0*log10(abs(fftpack.fftshift(psd))) + psd,freq = mlab.psd(iq, self.psdfftsize, self.sample_rate, + window = lambda d: d*winfunc(self.psdfftsize), + noverlap = overlap) + psd = 10.0*log10(abs(psd)) return (psd, freq) def make_plots(self): @@ -159,6 +160,7 @@ class gr_plot_psd: def draw_psd(self): self.plot_psd[0].set_data([self.freq, self.iq_psd]) self.sp_psd.set_ylim([min(self.iq_psd)-10, max(self.iq_psd)+10]) + self.sp_psd.set_xlim([min(self.freq), max(self.freq)]) def draw_spec(self): overlap = self.specfftsize/4 @@ -236,14 +238,15 @@ def setup_options(): usage="%prog: [options] input_filename" description = "Takes a GNU Radio binary file (with specified data type using --data-type) and displays the I&Q data versus time as well as the power spectral density (PSD) plot. The y-axis values are plotted assuming volts as the amplitude of the I&Q streams and converted into dBm in the frequency domain (the 1/N power adjustment out of the FFT is performed internally). The script plots a certain block of data at a time, specified on the command line as -B or --block. The start position in the file can be set by specifying -s or --start and defaults to 0 (the start of the file). By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time and frequency axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples. Finally, the size of the FFT to use for the PSD and spectrogram plots can be set independently with --psd-size and --spec-size, respectively. The spectrogram plot does not display by default and is turned on with -S or --enable-spec." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) + parser = OptionParser(option_class=eng_option, conflict_handler="resolve", + usage=usage, description=description) parser.add_option("-d", "--data-type", type="string", default="complex64", help="Specify the data type (complex64, float32, (u)int32, (u)int16, (u)int8) [default=%default]") parser.add_option("-B", "--block", type="int", default=8192, help="Specify the block size [default=%default]") parser.add_option("-s", "--start", type="int", default=0, help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, + parser.add_option("-R", "--sample-rate", type="eng_float", default=1.0, help="Set the sampler rate of the data [default=%default]") parser.add_option("", "--psd-size", type="int", default=1024, help="Set the size of the PSD FFT [default=%default]") -- cgit From d692a41f98e7b888c745efbb9fcbbb0400f39025 Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Wed, 24 Nov 2010 17:29:11 -0800 Subject: Major Makefile.am housecleaning. Passes distcheck. Move all occurrences of swig_built_sources out of Makefile.am's. Move all SWIG related use of BUILT_SOURCES out of Makefile.am's. Clean up 'if PYTHON' conditionalization in gr-* Still left to do: fix Makefile.swig CLEANFILES and no_dist_files such that they remove exactly the generated files. --- gr-utils/src/python/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/Makefile.am b/gr-utils/src/python/Makefile.am index 9c4e222c8..450032266 100644 --- a/gr-utils/src/python/Makefile.am +++ b/gr-utils/src/python/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ $(bin_SCRIPTS) \ README.plot \ pyqt_plot.ui \ -- cgit From 91ca107edc1e4cad69f102d947471d2c0adfc354 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 30 Dec 2010 17:12:26 -0500 Subject: Fixes to psd plotting tool. Trying to keep up with the changing API; this should be backwards compatible. --- gr-utils/src/python/gr_plot_psd.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_plot_psd.py b/gr-utils/src/python/gr_plot_psd.py index f3535d321..e3ecabd6a 100755 --- a/gr-utils/src/python/gr_plot_psd.py +++ b/gr-utils/src/python/gr_plot_psd.py @@ -87,13 +87,13 @@ class gr_plot_psd: def get_data(self): self.position = self.hfile.tell()/self.sizeof_data self.text_file_pos.set_text("File Position: %d" % self.position) - self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length) - #print "Read in %d items" % len(self.iq) - if(len(self.iq) == 0): + try: + self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length) + except MemoryError: print "End of File" else: tstep = 1.0 / self.sample_rate - self.time = [tstep*(self.position + i) for i in xrange(len(self.iq))] + self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))]) self.iq_psd, self.freq = self.dopsd(self.iq) @@ -153,14 +153,14 @@ class gr_plot_psd: imags = self.iq.imag self.plot_iq[0].set_data([self.time, reals]) self.plot_iq[1].set_data([self.time, imags]) - self.sp_iq.set_xlim(min(self.time), max(self.time)) - self.sp_iq.set_ylim([1.5*min([min(reals), min(imags)]), - 1.5*max([max(reals), max(imags)])]) + self.sp_iq.set_xlim(self.time.min(), self.time.max()) + self.sp_iq.set_ylim([1.5*min([reals.min(), imags.min()]), + 1.5*max([reals.max(), imags.max()])]) def draw_psd(self): self.plot_psd[0].set_data([self.freq, self.iq_psd]) - self.sp_psd.set_ylim([min(self.iq_psd)-10, max(self.iq_psd)+10]) - self.sp_psd.set_xlim([min(self.freq), max(self.freq)]) + self.sp_psd.set_ylim([self.iq_psd.min()-10, self.iq_psd.max()+10]) + self.sp_psd.set_xlim([self.freq.min(), self.freq.max()]) def draw_spec(self): overlap = self.specfftsize/4 @@ -168,7 +168,7 @@ class gr_plot_psd: self.sp_spec.clear() self.sp_spec.specgram(self.iq, self.specfftsize, self.sample_rate, window = lambda d: d*winfunc(self.specfftsize), - noverlap = overlap, xextent=[min(self.time), max(self.time)]) + noverlap = overlap, xextent=[self.time.min(), self.time.max()]) def update_plots(self): self.draw_time() @@ -188,14 +188,14 @@ class gr_plot_psd: xmin = max(0, int(ceil(self.sample_rate*(self.xlim[0] - self.position)))) xmax = min(int(ceil(self.sample_rate*(self.xlim[1] - self.position))), len(self.iq)) - iq = self.iq[xmin : xmax] - time = self.time[xmin : xmax] + iq = scipy.array(self.iq[xmin : xmax]) + time = scipy.array(self.time[xmin : xmax]) iq_psd, freq = self.dopsd(iq) self.plot_psd[0].set_data(freq, iq_psd) - self.sp_psd.axis([min(freq), max(freq), - min(iq_psd)-10, max(iq_psd)+10]) + self.sp_psd.axis([freq.min(), freq.max(), + iq_psd.min()-10, iq_psd.max()+10]) draw() -- cgit From 04a2f7d44984ebce10c27ae5271d5fe9782cb6f0 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 9 Mar 2011 23:08:42 -0500 Subject: Fixing gr_filter_design program to import from gnuradio Python package. --- gr-utils/src/python/gr_filter_design.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index bf83cf69f..56ca84d78 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -24,7 +24,7 @@ except ImportError: raise SystemExit, 1 try: - from pyqt_filter import Ui_MainWindow + from gnuradio.pyqt_filter import Ui_MainWindow except ImportError: print "Could not import from pyqt_filter. Please build with \"pyuic4 pyqt_filter.ui -o pyqt_filter.py\"" raise SystemExit, 1 -- cgit From cc4cd11bb3443f79771b6b18aaf40105a2f9f088 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 17 Mar 2011 11:11:56 -0700 Subject: gr-utils: Adding save and open actions to filter designer. --- gr-utils/src/python/gr_filter_design.py | 105 ++++++- gr-utils/src/python/pyqt_filter.py | 61 ++-- gr-utils/src/python/pyqt_filter.ui | 505 ++++++++++++++++---------------- 3 files changed, 385 insertions(+), 286 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index 56ca84d78..265bb3a03 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys, os +import sys, os, csv from optparse import OptionParser from gnuradio import gr, blks2, eng_notation @@ -24,7 +24,7 @@ except ImportError: raise SystemExit, 1 try: - from gnuradio.pyqt_filter import Ui_MainWindow + from pyqt_filter import Ui_MainWindow except ImportError: print "Could not import from pyqt_filter. Please build with \"pyuic4 pyqt_filter.ui -o pyqt_filter.py\"" raise SystemExit, 1 @@ -36,6 +36,14 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui = Ui_MainWindow() self.gui.setupUi(self) + self.connect(self.gui.action_save, + Qt.SIGNAL("activated()"), + self.action_save_dialog) + self.connect(self.gui.action_open, + Qt.SIGNAL("activated()"), + self.action_open_dialog) + + self.connect(self.gui.filterTypeComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"), self.changed_filter_type) @@ -306,17 +314,10 @@ class gr_plot_filter(QtGui.QMainWindow): "Root Raised Cosine" : self.design_win_rrc, "Gaussian" : self.design_win_gaus} wintype = self.filterWindows[winstr] - taps,r = designer[ftype](fs, gain, wintype) + taps,design,r = designer[ftype](fs, gain, wintype) if(r): - self.taps = scipy.array(taps) - self.get_fft(fs, self.taps, self.nfftpts) - self.update_time_curves() - self.update_freq_curves() - self.update_phase_curves() - self.update_group_curves() - - self.gui.nTapsEdit.setText(Qt.QString("%1").arg(self.taps.size)) + self.draw_plots(taps, design) # Filter design functions using a window @@ -334,9 +335,12 @@ class gr_plot_filter(QtGui.QMainWindow): taps = gr.firdes.low_pass_2(gain, fs, pb, tb, atten, wintype) - return (taps, ret) + design = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "lpf", "passband": pb, "stopband": sb, + "atten": atten} + return (taps, design, ret) else: - return ([], ret) + return ([], [], ret) def design_win_bpf(self, fs, gain, wintype): ret = True @@ -651,6 +655,81 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.groupPlot.replot() + def action_save_dialog(self): + filename = QtGui.QFileDialog.getSaveFileName(self, "Save CSV Filter File", ".", "") + handle = open(filename, "wb") + csvhandle = csv.writer(handle, delimiter=",") + for k in self.design.keys(): + csvhandle.writerow([k, self.design[k]]) + csvhandle.writerow(["taps",] + self.taps.tolist()) + handle.close() + + def action_open_dialog(self): + filename = QtGui.QFileDialog.getOpenFileName(self, "Open CSV Filter File", ".", "") + handle = open(filename, "rb") + csvhandle = csv.reader(handle, delimiter=",") + taps = [] + design = {} + for row in csvhandle: + if(row[0] != "taps"): + try: # if it's not a float, its a string + design[row[0]] = float(row[1]) + except ValueError: + design[row[0]] = row[1] + else: + taps = [float(r) for r in row[1:]] + handle.close() + self.draw_plots(taps, design) + + self.gui.sampleRateEdit.setText(Qt.QString("%1").arg(design["fs"])) + self.gui.filterGainEdit.setText(Qt.QString("%1").arg(design["gain"])) + + #FIXME: work on setting filter type and window type dropdown boxes + #FIXME: enable this and design for all other filt types + if(design["filttype"] == "lpf"): + self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(design["passband"])) + self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(design["stopband"])) + self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(design["atten"])) + elif(design["filttype"] == "bpf"): + self.gui.startofBpfPassBandEdit + self.gui.endofBpfPassBandEdit + self.gui.bpfTransitionEdit + self.gui.bpfStopBandAttenEdit + elif(design["filttype"] == "cbpf"): + self.gui.startofBpfPassBandEdit + self.gui.endofBpfPassBandEdit + self.gui.bpfTransitionEdit + self.gui.bpfStopBandAttenEdit + elif(design["filttype"] == "bnf"): + self.gui.startofBnfStopBandEdit + self.gui.endofBnfStopBandEdit + self.gui.bnfTransitionEdit + self.gui.bnfStopBandAttenEdit + elif(design["filttype"] == "hpf"): + self.gui.endofHpfStopBandEdit + self.gui.startofHpfPassBandEdit + self.gui.hpfStopBandAttenEdit + elif(design["filttype"] == "rrc"): + self.gui.rrcSymbolRateEdit + self.gui.rrcAlphaEdit + self.gui.rrcNumTapsEdit + elif(design["filttype"] == "gauss"): + self.gui.gausSymbolRateEdit + self.gui.gausBTEdit + self.gui.gausNumTapsEdit + + + def draw_plots(self, taps, design): + self.design = design + self.taps = scipy.array(taps) + self.get_fft(self.design["fs"], self.taps, self.nfftpts) + self.update_time_curves() + self.update_freq_curves() + self.update_phase_curves() + self.update_group_curves() + + self.gui.nTapsEdit.setText(Qt.QString("%1").arg(self.taps.size)) + def setup_options(): usage="%prog: [options] (input_filename)" diff --git a/gr-utils/src/python/pyqt_filter.py b/gr-utils/src/python/pyqt_filter.py index 12ad183b0..0c781f234 100644 --- a/gr-utils/src/python/pyqt_filter.py +++ b/gr-utils/src/python/pyqt_filter.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'pyqt_filter.ui' # -# Created: Tue Aug 25 11:13:57 2009 -# by: PyQt4 UI code generator 4.4.3 +# Created: Thu Mar 17 10:51:17 2011 +# by: PyQt4 UI code generator 4.7.4 # # WARNING! All changes made in this file will be lost! @@ -27,23 +27,23 @@ class Ui_MainWindow(object): self.verticalLayout.setObjectName("verticalLayout") self.filterTypeComboBox = QtGui.QComboBox(self.filterFrame) self.filterTypeComboBox.setObjectName("filterTypeComboBox") - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) - self.filterTypeComboBox.addItem(QtCore.QString()) + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") + self.filterTypeComboBox.addItem("") self.verticalLayout.addWidget(self.filterTypeComboBox) self.filterDesignTypeComboBox = QtGui.QComboBox(self.filterFrame) self.filterDesignTypeComboBox.setObjectName("filterDesignTypeComboBox") - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) - self.filterDesignTypeComboBox.addItem(QtCore.QString()) + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") + self.filterDesignTypeComboBox.addItem("") self.verticalLayout.addWidget(self.filterDesignTypeComboBox) self.globalParamsLayout = QtGui.QFormLayout() self.globalParamsLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) @@ -255,6 +255,7 @@ class Ui_MainWindow(object): self.nTapsEdit.setMaximumSize(QtCore.QSize(100, 16777215)) self.nTapsEdit.setFrameShape(QtGui.QFrame.Box) self.nTapsEdit.setFrameShadow(QtGui.QFrame.Raised) + self.nTapsEdit.setText("") self.nTapsEdit.setObjectName("nTapsEdit") self.formLayout_8.setWidget(1, QtGui.QFormLayout.FieldRole, self.nTapsEdit) self.verticalLayout.addWidget(self.filterPropsBox) @@ -285,7 +286,7 @@ class Ui_MainWindow(object): self.freqTab.setObjectName("freqTab") self.horizontalLayout_2 = QtGui.QHBoxLayout(self.freqTab) self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.freqPlot = Qwt5.QwtPlot(self.freqTab) + self.freqPlot = QwtPlot(self.freqTab) self.freqPlot.setObjectName("freqPlot") self.horizontalLayout_2.addWidget(self.freqPlot) self.tabGroup.addTab(self.freqTab, "") @@ -293,7 +294,7 @@ class Ui_MainWindow(object): self.timeTab.setObjectName("timeTab") self.horizontalLayout = QtGui.QHBoxLayout(self.timeTab) self.horizontalLayout.setObjectName("horizontalLayout") - self.timePlot = Qwt5.QwtPlot(self.timeTab) + self.timePlot = QwtPlot(self.timeTab) self.timePlot.setObjectName("timePlot") self.horizontalLayout.addWidget(self.timePlot) self.tabGroup.addTab(self.timeTab, "") @@ -301,7 +302,7 @@ class Ui_MainWindow(object): self.phaseTab.setObjectName("phaseTab") self.horizontalLayout_3 = QtGui.QHBoxLayout(self.phaseTab) self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.phasePlot = Qwt5.QwtPlot(self.phaseTab) + self.phasePlot = QwtPlot(self.phaseTab) self.phasePlot.setObjectName("phasePlot") self.horizontalLayout_3.addWidget(self.phasePlot) self.tabGroup.addTab(self.phaseTab, "") @@ -309,14 +310,14 @@ class Ui_MainWindow(object): self.groupTab.setObjectName("groupTab") self.horizontalLayout_4 = QtGui.QHBoxLayout(self.groupTab) self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.groupPlot = Qwt5.QwtPlot(self.groupTab) + self.groupPlot = QwtPlot(self.groupTab) self.groupPlot.setObjectName("groupPlot") self.horizontalLayout_4.addWidget(self.groupPlot) self.tabGroup.addTab(self.groupTab, "") self.gridLayout.addWidget(self.tabGroup, 1, 1, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1124, 24)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1124, 27)) self.menubar.setObjectName("menubar") self.menu_File = QtGui.QMenu(self.menubar) self.menu_File.setObjectName("menu_File") @@ -324,15 +325,19 @@ class Ui_MainWindow(object): self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) - self.action_open = QtGui.QAction(MainWindow) - self.action_open.setObjectName("action_open") self.action_exit = QtGui.QAction(MainWindow) self.action_exit.setObjectName("action_exit") + self.action_save = QtGui.QAction(MainWindow) + self.action_save.setObjectName("action_save") + self.action_open = QtGui.QAction(MainWindow) + self.action_open.setObjectName("action_open") + self.menu_File.addAction(self.action_open) + self.menu_File.addAction(self.action_save) self.menu_File.addAction(self.action_exit) self.menubar.addAction(self.menu_File.menuAction()) self.retranslateUi(MainWindow) - self.filterTypeWidget.setCurrentIndex(0) + self.filterTypeWidget.setCurrentIndex(5) self.tabGroup.setCurrentIndex(0) QtCore.QObject.connect(self.action_exit, QtCore.SIGNAL("activated()"), MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -419,8 +424,12 @@ class Ui_MainWindow(object): self.tabGroup.setTabText(self.tabGroup.indexOf(self.phaseTab), QtGui.QApplication.translate("MainWindow", "Phase", None, QtGui.QApplication.UnicodeUTF8)) self.tabGroup.setTabText(self.tabGroup.indexOf(self.groupTab), QtGui.QApplication.translate("MainWindow", "Group Delay", None, QtGui.QApplication.UnicodeUTF8)) self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) + self.action_exit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) + self.action_save.setText(QtGui.QApplication.translate("MainWindow", "&Save", None, QtGui.QApplication.UnicodeUTF8)) + self.action_save.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+S", None, QtGui.QApplication.UnicodeUTF8)) self.action_open.setText(QtGui.QApplication.translate("MainWindow", "&Open", None, QtGui.QApplication.UnicodeUTF8)) self.action_open.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8)) - self.action_exit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) -from PyQt4 import Qwt5 +#from qwt_plot import QwtPlot +from PyQt4.Qwt5 import QwtPlot + diff --git a/gr-utils/src/python/pyqt_filter.ui b/gr-utils/src/python/pyqt_filter.ui index 9b31112e8..9853352e2 100644 --- a/gr-utils/src/python/pyqt_filter.ui +++ b/gr-utils/src/python/pyqt_filter.ui @@ -1,7 +1,8 @@ - + + MainWindow - - + + 0 0 @@ -9,131 +10,131 @@ 696 - + GNU Radio Filter Design Tool - - - - - + + + + + 300 0 - + 300 16777215 - + QFrame::StyledPanel - + QFrame::Raised - + - + - + Low Pass - + Band Pass - + Complex Band Pass - + Band Notch - + High Pass - + Root Raised Cosine - + Gaussian - + - + Hamming Window - + Hann Window - + Blackman Window - + Rectangular Window - + Kaiser Window - + Blackman-harris Window - + Equiripple - - + + QFormLayout::AllNonFixedFieldsGrow - - - + + + 16777215 30 - + Sample Rate (sps) - - - + + + 16777215 30 @@ -141,332 +142,332 @@ - - - + + + Filter Gain - - + + - - - 0 + + + 5 - - - - - + + + + + End of Pass Band (Hz) - - + + - - - + + + Start of Stop Band (Hz) - - + + - - - + + + Stop Band Attenuation (dB) - - + + - - + + - - - + + + Pass Band Ripple (dB) - - - - - + + + + + Start of Pass Band (Hz) - - + + - - - + + + End of Pass Band (Hz) - - + + - - + + - - - + + + Stop Band Attenuation (dB) - - - + + + Transition Width (Hz) - - + + - - + + - - - + + + Pass Band Ripple (dB) - - - + + + QFormLayout::AllNonFixedFieldsGrow - - - + + + Start of Stop Band (Hz) - - + + - - - + + + End of Stop Band (Hz) - - + + - - - + + + Transition Width (Hz) - - + + - - - + + + Stop Band Attenuation (dB) - - + + - - - + + + Pass Band Ripple (dB) - - + + - - - + + + QFormLayout::AllNonFixedFieldsGrow - - - + + + End of Stop Band (Hz) - - + + - - - + + + Start of Pass Band (Hz) - - + + - - - + + + Stop Band Attenuation (dB) - - + + - - - + + + Pass Band Ripple (dB) - - + + - - - - - + + + + + Symbol Rate (sps) - - - + + + Roll-off Factor - - - + + + Number of Taps - - + + - - + + - - + + - - - - - + + + + + Symbol Rate (sps) - - + + - - - + + + Roll-off Factor - - + + - - - + + + Number of Taps - - + + - - + + Filter Properties - - + + QFormLayout::AllNonFixedFieldsGrow - - - + + + 150 0 - + Number of Taps: - - - + + + 100 16777215 - + QFrame::Box - + QFrame::Raised - + @@ -475,23 +476,23 @@ - - + + System Parameters - - - + + + - - - + + + 150 0 - + Num FFT points @@ -500,26 +501,26 @@ - - + + 0 0 - + 200 16777215 - + Design - + true - + true @@ -527,54 +528,54 @@ - - - + + + 800 0 - + 0 - - + + Frequency Domain - + - + - - + + Time Domain - + - + - - + + Phase - + - + - - + + Group Delay - + - + @@ -582,35 +583,45 @@ - - + + 0 0 1124 - 24 + 27 - - + + &File - + + + - + - - - - &Open + + + + E&xit - - Ctrl+O + + + + &Save + + + Ctrl+S - - - E&xit + + + &Open + + + Ctrl+O @@ -662,11 +673,11 @@ MainWindow close() - + -1 -1 - + 399 347 -- cgit From cec3834a9da5e8b96be438f078fbd3a93ea230d6 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 17 Mar 2011 11:15:50 -0700 Subject: gr-utils: way to break something you just fixed a few days ago... --- gr-utils/src/python/gr_filter_design.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index 265bb3a03..d0ef44d8a 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -24,7 +24,7 @@ except ImportError: raise SystemExit, 1 try: - from pyqt_filter import Ui_MainWindow + from gnuradio.pyqt_filter import Ui_MainWindow except ImportError: print "Could not import from pyqt_filter. Please build with \"pyuic4 pyqt_filter.ui -o pyqt_filter.py\"" raise SystemExit, 1 -- cgit From add43f24de20d3fbf6b94920e142d636c4769d5a Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 17 Mar 2011 23:19:53 -0700 Subject: gr-utils: refactoring design parameters from 'design' to 'params' to not conflict with design function. --- gr-utils/src/python/gr_filter_design.py | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index d0ef44d8a..091af0092 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -314,10 +314,10 @@ class gr_plot_filter(QtGui.QMainWindow): "Root Raised Cosine" : self.design_win_rrc, "Gaussian" : self.design_win_gaus} wintype = self.filterWindows[winstr] - taps,design,r = designer[ftype](fs, gain, wintype) + taps,params,r = designer[ftype](fs, gain, wintype) if(r): - self.draw_plots(taps, design) + self.draw_plots(taps, params) # Filter design functions using a window @@ -335,10 +335,10 @@ class gr_plot_filter(QtGui.QMainWindow): taps = gr.firdes.low_pass_2(gain, fs, pb, tb, atten, wintype) - design = {"fs": fs, "gain": gain, "wintype": wintype, + params = {"fs": fs, "gain": gain, "wintype": wintype, "filttype": "lpf", "passband": pb, "stopband": sb, "atten": atten} - return (taps, design, ret) + return (taps, params, ret) else: return ([], [], ret) @@ -659,8 +659,8 @@ class gr_plot_filter(QtGui.QMainWindow): filename = QtGui.QFileDialog.getSaveFileName(self, "Save CSV Filter File", ".", "") handle = open(filename, "wb") csvhandle = csv.writer(handle, delimiter=",") - for k in self.design.keys(): - csvhandle.writerow([k, self.design[k]]) + for k in self.params.keys(): + csvhandle.writerow([k, self.params[k]]) csvhandle.writerow(["taps",] + self.taps.tolist()) handle.close() @@ -669,60 +669,60 @@ class gr_plot_filter(QtGui.QMainWindow): handle = open(filename, "rb") csvhandle = csv.reader(handle, delimiter=",") taps = [] - design = {} + params = {} for row in csvhandle: if(row[0] != "taps"): try: # if it's not a float, its a string - design[row[0]] = float(row[1]) + params[row[0]] = float(row[1]) except ValueError: - design[row[0]] = row[1] + params[row[0]] = row[1] else: taps = [float(r) for r in row[1:]] handle.close() - self.draw_plots(taps, design) + self.draw_plots(taps, params) - self.gui.sampleRateEdit.setText(Qt.QString("%1").arg(design["fs"])) - self.gui.filterGainEdit.setText(Qt.QString("%1").arg(design["gain"])) + self.gui.sampleRateEdit.setText(Qt.QString("%1").arg(params["fs"])) + self.gui.filterGainEdit.setText(Qt.QString("%1").arg(params["gain"])) #FIXME: work on setting filter type and window type dropdown boxes #FIXME: enable this and design for all other filt types - if(design["filttype"] == "lpf"): - self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(design["passband"])) - self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(design["stopband"])) - self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(design["atten"])) - elif(design["filttype"] == "bpf"): + if(params["filttype"] == "lpf"): + self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["passband"])) + self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["stopband"])) + self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + elif(params["filttype"] == "bpf"): self.gui.startofBpfPassBandEdit self.gui.endofBpfPassBandEdit self.gui.bpfTransitionEdit self.gui.bpfStopBandAttenEdit - elif(design["filttype"] == "cbpf"): + elif(params["filttype"] == "cbpf"): self.gui.startofBpfPassBandEdit self.gui.endofBpfPassBandEdit self.gui.bpfTransitionEdit self.gui.bpfStopBandAttenEdit - elif(design["filttype"] == "bnf"): + elif(params["filttype"] == "bnf"): self.gui.startofBnfStopBandEdit self.gui.endofBnfStopBandEdit self.gui.bnfTransitionEdit self.gui.bnfStopBandAttenEdit - elif(design["filttype"] == "hpf"): + elif(params["filttype"] == "hpf"): self.gui.endofHpfStopBandEdit self.gui.startofHpfPassBandEdit self.gui.hpfStopBandAttenEdit - elif(design["filttype"] == "rrc"): + elif(params["filttype"] == "rrc"): self.gui.rrcSymbolRateEdit self.gui.rrcAlphaEdit self.gui.rrcNumTapsEdit - elif(design["filttype"] == "gauss"): + elif(params["filttype"] == "gauss"): self.gui.gausSymbolRateEdit self.gui.gausBTEdit self.gui.gausNumTapsEdit - def draw_plots(self, taps, design): - self.design = design + def draw_plots(self, taps, params): + self.params = params self.taps = scipy.array(taps) - self.get_fft(self.design["fs"], self.taps, self.nfftpts) + self.get_fft(self.params["fs"], self.taps, self.nfftpts) self.update_time_curves() self.update_freq_curves() self.update_phase_curves() -- cgit From 831ca406706ec4c4cdcd2c5f36dc74fb658a3d26 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 18 Mar 2011 00:39:25 -0700 Subject: gr-utils: handling parameters and GUI updates when loading filters from file. Only for windowed filters. --- gr-utils/src/python/gr_filter_design.py | 144 ++++++++++++++++++++++---------- 1 file changed, 98 insertions(+), 46 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index 091af0092..ffd67528d 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys, os, csv +import sys, os, re, csv from optparse import OptionParser from gnuradio import gr, blks2, eng_notation @@ -190,6 +190,12 @@ class gr_plot_filter(QtGui.QMainWindow): "Rectangular Window" : gr.firdes.WIN_RECTANGULAR, "Kaiser Window" : gr.firdes.WIN_KAISER, "Blackman-harris Window" : gr.firdes.WIN_BLACKMAN_hARRIS} + self.filterWindowsMap = ["Hamming Window", + "Hann Window", + "Blackman Window", + "Rectangular Window", + "Kaiser Window", + "Blackman-harris Window"] self.show() @@ -336,8 +342,8 @@ class gr_plot_filter(QtGui.QMainWindow): taps = gr.firdes.low_pass_2(gain, fs, pb, tb, atten, wintype) params = {"fs": fs, "gain": gain, "wintype": wintype, - "filttype": "lpf", "passband": pb, "stopband": sb, - "atten": atten} + "filttype": "lpf", "pbend": pb, "sbstart": sb, + "atten": atten, "ntaps": len(taps)} return (taps, params, ret) else: return ([], [], ret) @@ -356,9 +362,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): taps = gr.firdes.band_pass_2(gain, fs, pb1, pb2, tb, atten, wintype) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "bpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_win_cbpf(self, fs, gain, wintype): ret = True @@ -374,9 +383,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): taps = gr.firdes.complex_band_pass_2(gain, fs, pb1, pb2, tb, atten, wintype) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "cbpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_win_bnf(self, fs, gain, wintype): ret = True @@ -392,9 +404,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): taps = gr.firdes.band_reject_2(gain, fs, pb1, pb2, tb, atten, wintype) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "bnf", "sbstart": pb1, "sbend": pb2, + "tb": tb, "atten": atten, "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_win_hpf(self, fs, gain, wintype): ret = True @@ -409,9 +424,12 @@ class gr_plot_filter(QtGui.QMainWindow): tb = pb - sb taps = gr.firdes.high_pass_2(gain, fs, pb, tb, atten, wintype) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "hpf", "sbend": sb, "pbstart": pb, + "atten": atten, "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_win_rrc(self, fs, gain, wintype): ret = True @@ -425,9 +443,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): taps = gr.firdes.root_raised_cosine(gain, fs, sr, alpha, ntaps) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "rrc", "srate": sr, "alpha": alpha, + "ntaps": ntaps} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_win_gaus(self, fs, gain, wintype): ret = True @@ -441,9 +462,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): spb = fs / sr taps = gr.firdes.gaussian(gain, spb, bt, ntaps) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": wintype, + "filttype": "gaus", "srate": sr, "bt": bt, + "ntaps": ntaps} + return (taps,params,r) else: - return ([],r) + return ([],[],r) # Design Functions for Equiripple Filters def design_opt_lpf(self, fs, gain): @@ -672,51 +696,79 @@ class gr_plot_filter(QtGui.QMainWindow): params = {} for row in csvhandle: if(row[0] != "taps"): - try: # if it's not a float, its a string - params[row[0]] = float(row[1]) - except ValueError: - params[row[0]] = row[1] + testcpx = re.findall("[+-]?\d+\.*\d*[Ee]?[-+]?\d+j", row[1]) + if(len(testcpx) > 0): # it's a complex + params[row[0]] = complex(row[1]) + else: # assume it's a float + try: # if it's not a float, its a string + params[row[0]] = float(row[1]) + except ValueError: + params[row[0]] = row[1] else: - taps = [float(r) for r in row[1:]] + testcpx = re.findall("[+-]?\d+\.*\d*[Ee]?[-+]?\d+j", row[1]) + if(len(testcpx) > 0): # it's a complex + taps = [complex(r) for r in row[1:]] + else: + taps = [float(r) for r in row[1:]] handle.close() self.draw_plots(taps, params) self.gui.sampleRateEdit.setText(Qt.QString("%1").arg(params["fs"])) self.gui.filterGainEdit.setText(Qt.QString("%1").arg(params["gain"])) - #FIXME: work on setting filter type and window type dropdown boxes - #FIXME: enable this and design for all other filt types + # Set up GUI parameters for each filter type if(params["filttype"] == "lpf"): - self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["passband"])) - self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["stopband"])) + self.gui.filterTypeComboBox.setCurrentIndex(0) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) + self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbstart"])) self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) elif(params["filttype"] == "bpf"): - self.gui.startofBpfPassBandEdit - self.gui.endofBpfPassBandEdit - self.gui.bpfTransitionEdit - self.gui.bpfStopBandAttenEdit + self.gui.filterTypeComboBox.setCurrentIndex(1) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.startofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"])) + self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) + self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) + self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) elif(params["filttype"] == "cbpf"): - self.gui.startofBpfPassBandEdit - self.gui.endofBpfPassBandEdit - self.gui.bpfTransitionEdit - self.gui.bpfStopBandAttenEdit + self.gui.filterTypeComboBox.setCurrentIndex(2) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.startofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"])) + self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) + self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) + self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) elif(params["filttype"] == "bnf"): - self.gui.startofBnfStopBandEdit - self.gui.endofBnfStopBandEdit - self.gui.bnfTransitionEdit - self.gui.bnfStopBandAttenEdit + self.gui.filterTypeComboBox.setCurrentIndex(3) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.startofBnfStopBandEdit.setText(Qt.QString("%1").arg(params["sbstart"])) + self.gui.endofBnfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"])) + self.gui.bnfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) + self.gui.bnfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) elif(params["filttype"] == "hpf"): - self.gui.endofHpfStopBandEdit - self.gui.startofHpfPassBandEdit - self.gui.hpfStopBandAttenEdit + self.gui.filterTypeComboBox.setCurrentIndex(4) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.endofHpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"])) + self.gui.startofHpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"])) + self.gui.hpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) elif(params["filttype"] == "rrc"): - self.gui.rrcSymbolRateEdit - self.gui.rrcAlphaEdit - self.gui.rrcNumTapsEdit - elif(params["filttype"] == "gauss"): - self.gui.gausSymbolRateEdit - self.gui.gausBTEdit - self.gui.gausNumTapsEdit + self.gui.filterTypeComboBox.setCurrentIndex(5) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.rrcSymbolRateEdit.setText(Qt.QString("%1").arg(params["srate"])) + self.gui.rrcAlphaEdit.setText(Qt.QString("%1").arg(params["alpha"])) + self.gui.rrcNumTapsEdit.setText(Qt.QString("%1").arg(params["ntaps"])) + elif(params["filttype"] == "gaus"): + self.gui.filterTypeComboBox.setCurrentIndex(6) + self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) + + self.gui.gausSymbolRateEdit.setText(Qt.QString("%1").arg(params["srate"])) + self.gui.gausBTEdit.setText(Qt.QString("%1").arg(params["bt"])) + self.gui.gausNumTapsEdit.setText(Qt.QString("%1").arg(params["ntaps"])) def draw_plots(self, taps, params): -- cgit From b0856456d63a7f50ad852bcdf4512606a1cfb34e Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 25 Mar 2011 19:37:39 -0400 Subject: gr-utils: adding save/open capabilities to equiripple filters. Also added some error checking on opening and saving files. --- gr-utils/src/python/gr_filter_design.py | 81 ++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 21 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index ffd67528d..7b5fa1305 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -190,13 +190,7 @@ class gr_plot_filter(QtGui.QMainWindow): "Rectangular Window" : gr.firdes.WIN_RECTANGULAR, "Kaiser Window" : gr.firdes.WIN_KAISER, "Blackman-harris Window" : gr.firdes.WIN_BLACKMAN_hARRIS} - self.filterWindowsMap = ["Hamming Window", - "Hann Window", - "Blackman Window", - "Rectangular Window", - "Kaiser Window", - "Blackman-harris Window"] - + self.EQUIRIPPLE_FILT = 6 # const for equiripple filter window types self.show() def changed_filter_type(self, ftype): @@ -309,7 +303,7 @@ class gr_plot_filter(QtGui.QMainWindow): "Complex Band Pass" : self.design_opt_cbpf, "Band Notch" : self.design_opt_bnf, "High Pass" : self.design_opt_hpf} - taps,r = designer[ftype](fs, gain) + taps,params,r = designer[ftype](fs, gain) else: designer = {"Low Pass" : self.design_win_lpf, @@ -484,9 +478,12 @@ class gr_plot_filter(QtGui.QMainWindow): if(ret): taps = blks2.optfir.low_pass(gain, fs, pb, sb, ripple, atten) - return (taps, ret) + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "lpf", "pbend": pb, "sbstart": sb, + "atten": atten, "ripple": ripple, "ntaps": len(taps)} + return (taps, params, ret) else: - return ([], ret) + return ([], [], ret) def design_opt_bpf(self, fs, gain): ret = True @@ -506,9 +503,13 @@ class gr_plot_filter(QtGui.QMainWindow): sb2 = pb2 + tb taps = blks2.optfir.band_pass(gain, fs, sb1, pb1, pb2, sb2, ripple, atten) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "bpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_opt_cbpf(self, fs, gain): ret = True @@ -528,9 +529,13 @@ class gr_plot_filter(QtGui.QMainWindow): sb2 = pb2 + tb taps = blks2.optfir.complex_band_pass(gain, fs, sb1, pb1, pb2, sb2, ripple, atten) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "cbpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_opt_bnf(self, fs, gain): ret = True @@ -550,9 +555,13 @@ class gr_plot_filter(QtGui.QMainWindow): pb2 = sb2 + tb taps = blks2.optfir.band_reject(gain, fs, pb1, sb1, sb2, pb2, ripple, atten) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "bnf", "sbstart": pb1, "sbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def design_opt_hpf(self, fs, gain): ret = True @@ -568,9 +577,13 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): taps = blks2.optfir.high_pass(gain, fs, sb, pb, atten, ripple) - return (taps,r) + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "hpf", "sbend": sb, "pbstart": pb, + "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: - return ([],r) + return ([],[],r) def nfft_edit_changed(self, nfft): infft,r = nfft.toInt() @@ -681,7 +694,14 @@ class gr_plot_filter(QtGui.QMainWindow): def action_save_dialog(self): filename = QtGui.QFileDialog.getSaveFileName(self, "Save CSV Filter File", ".", "") - handle = open(filename, "wb") + try: + handle = open(filename, "wb") + except IOError: + reply = QtGui.QMessageBox.information(self, 'File Name', + ("Could not save to file: %s" % filename), + "&Ok") + return + csvhandle = csv.writer(handle, delimiter=",") for k in self.params.keys(): csvhandle.writerow([k, self.params[k]]) @@ -690,7 +710,17 @@ class gr_plot_filter(QtGui.QMainWindow): def action_open_dialog(self): filename = QtGui.QFileDialog.getOpenFileName(self, "Open CSV Filter File", ".", "") - handle = open(filename, "rb") + if(len(filename) == 0): + return + + try: + handle = open(filename, "rb") + except IOError: + reply = QtGui.QMessageBox.information(self, 'File Name', + ("Could not open file: %s" % filename), + "&Ok") + return + csvhandle = csv.reader(handle, delimiter=",") taps = [] params = {} @@ -724,6 +754,8 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbstart"])) self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + if(params["wintype"] == self.EQUIRIPPLE_FILT): + self.gui.lpfPassBandRippleEdit.setText(Qt.QString("%1").arg(params["ripple"])) elif(params["filttype"] == "bpf"): self.gui.filterTypeComboBox.setCurrentIndex(1) self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) @@ -732,6 +764,8 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + if(params["wintype"] == self.EQUIRIPPLE_FILT): + self.gui.bpfPassBandRippleEdit.setText(Qt.QString("%1").arg(params["ripple"])) elif(params["filttype"] == "cbpf"): self.gui.filterTypeComboBox.setCurrentIndex(2) self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) @@ -740,6 +774,8 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"])) self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + if(params["wintype"] == self.EQUIRIPPLE_FILT): + self.gui.bpfPassBandRippleEdit.setText(Qt.QString("%1").arg(params["ripple"])) elif(params["filttype"] == "bnf"): self.gui.filterTypeComboBox.setCurrentIndex(3) self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) @@ -748,6 +784,8 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.endofBnfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"])) self.gui.bnfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"])) self.gui.bnfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + if(params["wintype"] == self.EQUIRIPPLE_FILT): + self.gui.bnfPassBandRippleEdit.setText(Qt.QString("%1").arg(params["ripple"])) elif(params["filttype"] == "hpf"): self.gui.filterTypeComboBox.setCurrentIndex(4) self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) @@ -755,6 +793,8 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.endofHpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"])) self.gui.startofHpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"])) self.gui.hpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"])) + if(params["wintype"] == self.EQUIRIPPLE_FILT): + self.gui.hpfPassBandRippleEdit.setText(Qt.QString("%1").arg(params["ripple"])) elif(params["filttype"] == "rrc"): self.gui.filterTypeComboBox.setCurrentIndex(5) self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) @@ -770,7 +810,6 @@ class gr_plot_filter(QtGui.QMainWindow): self.gui.gausBTEdit.setText(Qt.QString("%1").arg(params["bt"])) self.gui.gausNumTapsEdit.setText(Qt.QString("%1").arg(params["ntaps"])) - def draw_plots(self, taps, params): self.params = params self.taps = scipy.array(taps) -- cgit From 511e31d4fcd7341b5f1fb56aeba497f0ba36159c Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 25 Mar 2011 19:55:03 -0400 Subject: gr-utils: more error checking on filter designer. --- gr-utils/src/python/gr_filter_design.py | 99 ++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 34 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_filter_design.py b/gr-utils/src/python/gr_filter_design.py index 7b5fa1305..e8703db4f 100755 --- a/gr-utils/src/python/gr_filter_design.py +++ b/gr-utils/src/python/gr_filter_design.py @@ -476,12 +476,18 @@ class gr_plot_filter(QtGui.QMainWindow): ret = r and ret if(ret): - taps = blks2.optfir.low_pass(gain, fs, pb, sb, - ripple, atten) - params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, - "filttype": "lpf", "pbend": pb, "sbstart": sb, - "atten": atten, "ripple": ripple, "ntaps": len(taps)} - return (taps, params, ret) + try: + taps = blks2.optfir.low_pass(gain, fs, pb, sb, + ripple, atten) + except RuntimeError, e: + reply = QtGui.QMessageBox.information(self, "Filter did not converge", + e.args[0], "&Ok") + return ([],[],False) + else: + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "lpf", "pbend": pb, "sbstart": sb, + "atten": atten, "ripple": ripple, "ntaps": len(taps)} + return (taps, params, ret) else: return ([], [], ret) @@ -501,13 +507,20 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): sb1 = pb1 - tb sb2 = pb2 + tb - taps = blks2.optfir.band_pass(gain, fs, sb1, pb1, pb2, sb2, - ripple, atten) - params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, - "filttype": "bpf", "pbstart": pb1, "pbend": pb2, - "tb": tb, "atten": atten, "ripple": ripple, - "ntaps": len(taps)} - return (taps,params,r) + try: + taps = blks2.optfir.band_pass(gain, fs, sb1, pb1, pb2, sb2, + ripple, atten) + except RuntimeError, e: + reply = QtGui.QMessageBox.information(self, "Filter did not converge", + e.args[0], "&Ok") + return ([],[],False) + + else: + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "bpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: return ([],[],r) @@ -527,13 +540,19 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): sb1 = pb1 - tb sb2 = pb2 + tb - taps = blks2.optfir.complex_band_pass(gain, fs, sb1, pb1, pb2, sb2, - ripple, atten) - params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, - "filttype": "cbpf", "pbstart": pb1, "pbend": pb2, - "tb": tb, "atten": atten, "ripple": ripple, - "ntaps": len(taps)} - return (taps,params,r) + try: + taps = blks2.optfir.complex_band_pass(gain, fs, sb1, pb1, pb2, sb2, + ripple, atten) + except RuntimeError, e: + reply = QtGui.QMessageBox.information(self, "Filter did not converge", + e.args[0], "&Ok") + return ([],[],False) + else: + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "cbpf", "pbstart": pb1, "pbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: return ([],[],r) @@ -553,13 +572,19 @@ class gr_plot_filter(QtGui.QMainWindow): if(r): pb1 = sb1 - tb pb2 = sb2 + tb - taps = blks2.optfir.band_reject(gain, fs, pb1, sb1, sb2, pb2, - ripple, atten) - params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, - "filttype": "bnf", "sbstart": pb1, "sbend": pb2, - "tb": tb, "atten": atten, "ripple": ripple, - "ntaps": len(taps)} - return (taps,params,r) + try: + taps = blks2.optfir.band_reject(gain, fs, pb1, sb1, sb2, pb2, + ripple, atten) + except RuntimeError, e: + reply = QtGui.QMessageBox.information(self, "Filter did not converge", + e.args[0], "&Ok") + return ([],[],False) + else: + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "bnf", "sbstart": pb1, "sbend": pb2, + "tb": tb, "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: return ([],[],r) @@ -575,13 +600,19 @@ class gr_plot_filter(QtGui.QMainWindow): ret = r and ret if(r): - taps = blks2.optfir.high_pass(gain, fs, sb, pb, - atten, ripple) - params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, - "filttype": "hpf", "sbend": sb, "pbstart": pb, - "atten": atten, "ripple": ripple, - "ntaps": len(taps)} - return (taps,params,r) + try: + taps = blks2.optfir.high_pass(gain, fs, sb, pb, + atten, ripple) + except RuntimeError, e: + reply = QtGui.QMessageBox.information(self, "Filter did not converge", + e.args[0], "&Ok") + return ([],[],False) + else: + params = {"fs": fs, "gain": gain, "wintype": self.EQUIRIPPLE_FILT, + "filttype": "hpf", "sbend": sb, "pbstart": pb, + "atten": atten, "ripple": ripple, + "ntaps": len(taps)} + return (taps,params,r) else: return ([],[],r) -- cgit From e896fec51f576a169c8751573af3dcd90c80669f Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 24 May 2011 12:07:39 +0100 Subject: gr-utils: updating gr_plot_psd.py to protect against zero-length arrays in get_data. --- gr-utils/src/python/gr_plot_psd.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'gr-utils/src/python') diff --git a/gr-utils/src/python/gr_plot_psd.py b/gr-utils/src/python/gr_plot_psd.py index 3f90a7104..3dab0535a 100755 --- a/gr-utils/src/python/gr_plot_psd.py +++ b/gr-utils/src/python/gr_plot_psd.py @@ -93,12 +93,20 @@ class gr_plot_psd: self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length) except MemoryError: print "End of File" + return False else: - tstep = 1.0 / self.sample_rate - #self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))]) - self.time = scipy.array([tstep*(i) for i in xrange(len(self.iq))]) - - self.iq_psd, self.freq = self.dopsd(self.iq) + # retesting length here as newer version of scipy does not throw a MemoryError, just + # returns a zero-length array + if(len(self.iq) > 0): + tstep = 1.0 / self.sample_rate + #self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))]) + self.time = scipy.array([tstep*(i) for i in xrange(len(self.iq))]) + + self.iq_psd, self.freq = self.dopsd(self.iq) + return True + else: + print "End of File" + return False def dopsd(self, iq): ''' Need to do this here and plot later so we can do the fftshift ''' @@ -130,7 +138,7 @@ class gr_plot_psd: self.sp_psd.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold") self.sp_psd.set_ylabel("Power Spectrum (dBm)", fontsize=self.label_font_size, fontweight="bold") - self.get_data() + r = self.get_data() self.plot_iq = self.sp_iq.plot([], 'bo-') # make plot for reals self.plot_iq += self.sp_iq.plot([], 'ro-') # make plot for imags @@ -220,8 +228,9 @@ class gr_plot_psd: self.step_forward() def step_forward(self): - self.get_data() - self.update_plots() + r = self.get_data() + if(r): + self.update_plots() def step_backward(self): # Step back in file position @@ -229,8 +238,9 @@ class gr_plot_psd: self.hfile.seek(-2*self.sizeof_data*self.block_length, 1) else: self.hfile.seek(-self.hfile.tell(),1) - self.get_data() - self.update_plots() + r = self.get_data() + if(r): + self.update_plots() def find(item_in, list_search): try: -- cgit