diff options
-rw-r--r-- | gr-qtgui/apps/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_constellation_plot | 40 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_b | 158 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_c | 149 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_f | 147 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_i | 158 | ||||
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_s | 156 | ||||
-rw-r--r-- | gr-qtgui/apps/plot_spectrogram_base.py | 164 |
8 files changed, 311 insertions, 662 deletions
diff --git a/gr-qtgui/apps/CMakeLists.txt b/gr-qtgui/apps/CMakeLists.txt index 8d66b6d5ff..eb11897a08 100644 --- a/gr-qtgui/apps/CMakeLists.txt +++ b/gr-qtgui/apps/CMakeLists.txt @@ -23,6 +23,7 @@ GR_PYTHON_INSTALL( FILES plot_base.py plot_psd_base.py + plot_spectrogram_base.py plot_time_base.py plot_form.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/qtgui diff --git a/gr-qtgui/apps/gr_constellation_plot b/gr-qtgui/apps/gr_constellation_plot index 02805a8fd1..f7782d4009 100755 --- a/gr-qtgui/apps/gr_constellation_plot +++ b/gr-qtgui/apps/gr_constellation_plot @@ -41,22 +41,10 @@ except ImportError: try: from gnuradio.qtgui.plot_form import * + from gnuradio.qtgui.plot_base import * except ImportError: from plot_form import * - -def read_samples(filename, start, in_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_gr_complex, 0) - data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size) - data = data.tolist() - fhandle.close() - - if(len(data) < in_size): - print "Warning: read in {0} samples but asked for {1} samples.".format( - len(data), in_size) - - return data + from plot_base import * class my_top_block(gr.top_block): def __init__(self, filelist, start, nsamples, max_nsamples): @@ -66,11 +54,13 @@ class my_top_block(gr.top_block): self._start = start self._max_nsamps = max_nsamples self._nsigs = len(self._filelist) + self._nsamps = nsamples - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples + self._y_min = -20 + self._y_max = 20 + self._y_range = 4 + self._y_value = 2 + self.gui_y_axis = None self.qapp = QtGui.QApplication(sys.argv) @@ -81,7 +71,7 @@ class my_top_block(gr.top_block): n = 0 self.srcs = list() for f in filelist: - data = read_samples(f, self._start, self._nsamps) + data,_min,_max = read_samples_c(f, self._start, self._nsamps) self.srcs.append(gr.vector_source_c(data)) # Set default labels based on file names @@ -109,7 +99,7 @@ class my_top_block(gr.top_block): self._start = newstart for s,f in zip(self.srcs, self._filelist): - data = read_samples(f, self._start, newnsamps) + data,_min,_max = read_samples_c(f, self._start, newnsamps) s.set_data(data) if(len(data) < newnsamps): newnsamps = len(data) @@ -119,12 +109,18 @@ class my_top_block(gr.top_block): self.start() + def set_y_axis(self, y_min, y_max): + y_min = -y_max + self.gui_snk.set_y_axis(y_min, y_max) + self.gui_snk.set_x_axis(y_min, y_max) + return y_min, y_max + def main(): description = "Plots the constellations of a list of files." parser = OptionParser(option_class=eng_option, description=description, conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") + parser.add_option("-N", "--nsamples", type="int", default=1000000, + help="Set the number of samples to display [default=%default]") parser.add_option("-S", "--start", type="int", default=0, help="Starting sample number [default=%default]") (options, args) = parser.parse_args() diff --git a/gr-qtgui/apps/gr_spectrogram_plot_b b/gr-qtgui/apps/gr_spectrogram_plot_b index 649c2834d6..93bed17d1e 100755 --- a/gr-qtgui/apps/gr_spectrogram_plot_b +++ b/gr-qtgui/apps/gr_spectrogram_plot_b @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,12 @@ # from gnuradio import gr -from gnuradio import blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import os, sys +import scipy + +try: + import gnuradio.qtgui.plot_spectrogram_base as plot_base +except ImportError: + import plot_spectrogram_base as plot_base try: from gnuradio import qtgui @@ -34,141 +36,35 @@ except ImportError: print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) -try: - import scipy -except ImportError: - print "Error: Scipy required (www.scipy.org)." - sys.exit(1) - -try: - from gnuradio.qtgui.plot_form import * -except ImportError: - from plot_form import * - -def read_samples_and_pad(filename, start, in_size, min_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_char, 0) - data = scipy.fromfile(fhandle, dtype=scipy.uint8, count=in_size) - data = data.tolist() - fhandle.close() - - # If we have to, append 0's to create min_size samples of data - if(len(data) < min_size): - data += (min_size - len(data)) * [scipy.uint8(0)] - - return data - -class my_top_block(gr.top_block): +class spectrogram_plot_b(plot_base.plot_base): def __init__(self, filelist, fc, samp_rate, psdsize, start, - nsamples, max_nsamples, scale, avg=1.0): - gr.top_block.__init__(self) - - self._filelist = filelist - self._center_freq = fc - self._samp_rate = samp_rate - self._psd_size = psdsize - self._start = start - self._max_nsamps = max_nsamples - self._scale = scale - self._nsigs = len(self._filelist) - self._avg = avg - - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples - - self.qapp = QtGui.QApplication(sys.argv) - - self.skip = gr.skiphead(gr.sizeof_float, self._start) - self.add = blocks.add_ff() + nsamples, max_nsamples, avg=1.0): + plot_base.plot_base.__init__(self, filelist, fc, samp_rate, + psdsize, start, nsamples, + max_nsamples, avg) + + self.read_samples = plot_base.read_samples_b + self.dsize = gr.sizeof_float + self.src_type = plot_base.source_chars_to_float self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._center_freq, self._samp_rate, - "GNU Radio Spectrogram Plot") - n = 0 - self.srcs = list() - self.cnvrt = list() - for f in filelist: - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - self.srcs.append(gr.vector_source_b(data)) - self.cnvrt.append(blocks.char_to_float(1, self._scale)) - n += 1 - - self.connect(self.add, self.skip) - self.connect(self.skip, (self.gui_snk, 0)) - - for i,s in enumerate(self.srcs): - self.connect(s, self.cnvrt[i], (self.add, i)) - - self.gui_snk.set_update_time(0); - self.gui_snk.set_fft_average(self._avg) - - # Get Python Qt references - pyQt = self.gui_snk.pyqwidget() - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - - def get_gui(self): - return self.pyWin - - def reset(self, newstart, newnsamps): - self.stop() - self.wait() - - self._start = newstart - self._nsamps = newnsamps - - for s,f in zip(self.srcs, self._filelist): - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - s.set_data(data) - - self.start() + "GNU Radio Spectrogram Plot", 1) + self.setup() def main(): - description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of chars/bytes." - parser = OptionParser(option_class=eng_option, description=description, - conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") - parser.add_option("-S", "--start", type="int", default=0, - help="Starting sample number [default=%default]") - parser.add_option("-L", "--psd-size", type="int", default=2048, - help="Set the FFT size of the PSD [default=%default]") - parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, - help="Set the center frequency of the signal [default=%default]") - parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, - help="Set the sample rate of the signal [default=%default]") - parser.add_option("-a", "--average", type="float", default=1.0, - help="Set amount of averaging (smaller=more averaging) [default=%default]") - parser.add_option("-s", "--scale", type="eng_float", default=2**(8-1)-1, - help="Set a scaling factor for the char->float conversion [default=%default]") - (options, args) = parser.parse_args() - - if(len(args) < 1): - parser.print_help() - sys.exit(0) + description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of chars." + (options, args) = plot_base.setup_options(description) filelist = list(args) + max_nsamples = plot_base.find_max_nsamples(filelist) - nsamples = options.nsamples - - # Find the smallest number of samples in all files and use that as - # a maximum value possible. - filesizes = [] - for f in filelist: - if(os.path.exists(f)): - filesizes.append(os.path.getsize(f) / gr.sizeof_char) - max_nsamples = min(filesizes) - - tb = my_top_block(filelist, - options.center_frequency, options.sample_rate, - options.psd_size, - options.start, nsamples, max_nsamples, - options.scale, options.average); + tb = spectrogram_plot_b(filelist, + options.center_frequency, options.sample_rate, + options.psd_size, + options.start, options.nsamples, max_nsamples, + options.average); - main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box = plot_base.dialog_box(tb, 'GNU Radio Spectrogram Plot', False) main_box.show() tb.run() diff --git a/gr-qtgui/apps/gr_spectrogram_plot_c b/gr-qtgui/apps/gr_spectrogram_plot_c index de2bd09f39..c8b904742b 100755 --- a/gr-qtgui/apps/gr_spectrogram_plot_c +++ b/gr-qtgui/apps/gr_spectrogram_plot_c @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,12 @@ # from gnuradio import gr -from gnuradio import blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import os, sys +import scipy + +try: + import gnuradio.qtgui.plot_spectrogram_base as plot_base +except ImportError: + import plot_spectrogram_base as plot_base try: from gnuradio import qtgui @@ -34,138 +36,35 @@ except ImportError: print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) -try: - import scipy -except ImportError: - print "Error: Scipy required (www.scipy.org)." - sys.exit(1) - -try: - from gnuradio.qtgui.plot_form import * -except ImportError: - from plot_form import * - -def read_samples_and_pad(filename, start, in_size, min_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_gr_complex, 0) - data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size) - data = data.tolist() - fhandle.close() - - # If we have to, append 0's to create min_size samples of data - if(len(data) < min_size): - data += (min_size - len(data)) * [complex(0,0)] - - return data - -class my_top_block(gr.top_block): +class spectrogram_plot_c(plot_base.plot_base): def __init__(self, filelist, fc, samp_rate, psdsize, start, nsamples, max_nsamples, avg=1.0): - gr.top_block.__init__(self) - - self._filelist = filelist - self._center_freq = fc - self._samp_rate = samp_rate - self._psd_size = psdsize - self._start = start - self._max_nsamps = max_nsamples - self._nsigs = len(self._filelist) - self._avg = avg - - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples + plot_base.plot_base.__init__(self, filelist, fc, samp_rate, + psdsize, start, nsamples, + max_nsamples, avg) - self.qapp = QtGui.QApplication(sys.argv) - - self.skip = gr.skiphead(gr.sizeof_gr_complex, self._start) - self.add = blocks.add_cc() + self.read_samples = plot_base.read_samples_c + self.dsize = gr.sizeof_gr_complex + self.src_type = gr.vector_source_c self.gui_snk = qtgui.waterfall_sink_c(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._center_freq, self._samp_rate, - "GNU Radio Spectrogram Plot") - - n = 0 - self.srcs = list() - for f in filelist: - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - self.srcs.append(gr.vector_source_c(data)) - n += 1 - - self.connect(self.add, self.skip) - self.connect(self.skip, (self.gui_snk, 0)) - - for i,s in enumerate(self.srcs): - self.connect(s, (self.add, i)) - - self.gui_snk.set_update_time(0); - self.gui_snk.set_fft_average(self._avg) - - # Get Python Qt references - pyQt = self.gui_snk.pyqwidget() - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - - def get_gui(self): - return self.pyWin - - def reset(self, newstart, newnsamps): - self.stop() - self.wait() - self.gui_snk.clear_data() - - self._start = newstart - self._nsamps = newnsamps - - for s,f in zip(self.srcs, self._filelist): - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - s.set_data(data) - - self.start() + "GNU Radio Spectrogram Plot", 1) + self.setup() def main(): description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of complex floats." - parser = OptionParser(option_class=eng_option, description=description, - conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") - parser.add_option("-S", "--start", type="int", default=0, - help="Starting sample number [default=%default]") - parser.add_option("-L", "--psd-size", type="int", default=2048, - help="Set the FFT size of the PSD [default=%default]") - parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, - help="Set the center frequency of the signal [default=%default]") - parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, - help="Set the sample rate of the signal [default=%default]") - parser.add_option("-a", "--average", type="float", default=1.0, - help="Set amount of averaging (smaller=more averaging) [default=%default]") - (options, args) = parser.parse_args() - - if(len(args) < 1): - parser.print_help() - sys.exit(0) + (options, args) = plot_base.setup_options(description) filelist = list(args) + max_nsamples = plot_base.find_max_nsamples(filelist) - nsamples = options.nsamples - - # Find the smallest number of samples in all files and use that as - # a maximum value possible. - filesizes = [] - for f in filelist: - if(os.path.exists(f)): - filesizes.append(os.path.getsize(f) / gr.sizeof_gr_complex) - max_nsamples = min(filesizes) - - tb = my_top_block(filelist, - options.center_frequency, options.sample_rate, - options.psd_size, - options.start, nsamples, max_nsamples, - options.average); + tb = spectrogram_plot_c(filelist, + options.center_frequency, options.sample_rate, + options.psd_size, + options.start, options.nsamples, max_nsamples, + options.average); - main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box = plot_base.dialog_box(tb, 'GNU Radio Spectrogram Plot', False) main_box.show() tb.run() diff --git a/gr-qtgui/apps/gr_spectrogram_plot_f b/gr-qtgui/apps/gr_spectrogram_plot_f index 3e799395b3..dcda269424 100755 --- a/gr-qtgui/apps/gr_spectrogram_plot_f +++ b/gr-qtgui/apps/gr_spectrogram_plot_f @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,12 @@ # from gnuradio import gr -from gnuradio import blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import os, sys +import scipy + +try: + import gnuradio.qtgui.plot_spectrogram_base as plot_base +except ImportError: + import plot_spectrogram_base as plot_base try: from gnuradio import qtgui @@ -34,136 +36,35 @@ except ImportError: print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) -try: - import scipy -except ImportError: - print "Error: Scipy required (www.scipy.org)." - sys.exit(1) - -try: - from gnuradio.qtgui.plot_form import * -except ImportError: - from plot_form import * - -def read_samples_and_pad(filename, start, in_size, min_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_float, 0) - data = scipy.fromfile(fhandle, dtype=scipy.float32, count=in_size) - data = data.tolist() - fhandle.close() - - # If we have to, append 0's to create min_size samples of data - if(len(data) < min_size): - data += (min_size - len(data)) * [scipy.float32(0.0)] - - return data - -class my_top_block(gr.top_block): +class spectrogram_plot_f(plot_base.plot_base): def __init__(self, filelist, fc, samp_rate, psdsize, start, nsamples, max_nsamples, avg=1.0): - gr.top_block.__init__(self) - - self._filelist = filelist - self._center_freq = fc - self._samp_rate = samp_rate - self._psd_size = psdsize - self._start = start - self._max_nsamps = max_nsamples - self._nsigs = len(self._filelist) - self._avg = avg + plot_base.plot_base.__init__(self, filelist, fc, samp_rate, + psdsize, start, nsamples, + max_nsamples, avg) - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples - - self.qapp = QtGui.QApplication(sys.argv) - - self.skip = gr.skiphead(gr.sizeof_float, self._start) - self.add = blocks.add_ff() + self.read_samples = plot_base.read_samples_f + self.dsize = gr.sizeof_float + self.src_type = gr.vector_source_f self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._center_freq, self._samp_rate, - "GNU Radio Spectrogram Plot") - n = 0 - self.srcs = list() - for f in filelist: - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - self.srcs.append(gr.vector_source_f(data)) - n += 1 - - self.connect(self.add, self.skip) - self.connect(self.skip, (self.gui_snk, 0)) - - for i,s in enumerate(self.srcs): - self.connect(s, (self.add, i)) - - self.gui_snk.set_update_time(0); - self.gui_snk.set_fft_average(self._avg) - - # Get Python Qt references - pyQt = self.gui_snk.pyqwidget() - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - - def get_gui(self): - return self.pyWin - - def reset(self, newstart, newnsamps): - self.stop() - self.wait() - - self._start = newstart - self._nsamps = newnsamps - - for s,f in zip(self.srcs, self._filelist): - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - s.set_data(data) - - self.start() + "GNU Radio Spectrogram Plot", 1) + self.setup() def main(): description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of floats." - parser = OptionParser(option_class=eng_option, description=description, - conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") - parser.add_option("-S", "--start", type="int", default=0, - help="Starting sample number [default=%default]") - parser.add_option("-L", "--psd-size", type="int", default=2048, - help="Set the FFT size of the PSD [default=%default]") - parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, - help="Set the center frequency of the signal [default=%default]") - parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, - help="Set the sample rate of the signal [default=%default]") - parser.add_option("-a", "--average", type="float", default=1.0, - help="Set amount of averaging (smaller=more averaging) [default=%default]") - (options, args) = parser.parse_args() - - if(len(args) < 1): - parser.print_help() - sys.exit(0) + (options, args) = plot_base.setup_options(description) filelist = list(args) + max_nsamples = plot_base.find_max_nsamples(filelist) - nsamples = options.nsamples - - # Find the smallest number of samples in all files and use that as - # a maximum value possible. - filesizes = [] - for f in filelist: - if(os.path.exists(f)): - filesizes.append(os.path.getsize(f) / gr.sizeof_float) - max_nsamples = min(filesizes) - - tb = my_top_block(filelist, - options.center_frequency, options.sample_rate, - options.psd_size, - options.start, nsamples, max_nsamples, - options.average); + tb = spectrogram_plot_f(filelist, + options.center_frequency, options.sample_rate, + options.psd_size, + options.start, options.nsamples, max_nsamples, + options.average); - main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box = plot_base.dialog_box(tb, 'GNU Radio Spectrogram Plot', False) main_box.show() tb.run() diff --git a/gr-qtgui/apps/gr_spectrogram_plot_i b/gr-qtgui/apps/gr_spectrogram_plot_i index 444f4115ad..838d802ed6 100755 --- a/gr-qtgui/apps/gr_spectrogram_plot_i +++ b/gr-qtgui/apps/gr_spectrogram_plot_i @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,12 @@ # from gnuradio import gr -from gnuradio import blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import os, sys +import scipy + +try: + import gnuradio.qtgui.plot_spectrogram_base as plot_base +except ImportError: + import plot_spectrogram_base as plot_base try: from gnuradio import qtgui @@ -34,141 +36,35 @@ except ImportError: print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) -try: - import scipy -except ImportError: - print "Error: Scipy required (www.scipy.org)." - sys.exit(1) - -try: - from gnuradio.qtgui.plot_form import * -except ImportError: - from plot_form import * - -def read_samples_and_pad(filename, start, in_size, min_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_int, 0) - data = scipy.fromfile(fhandle, dtype=scipy.int32, count=in_size) - data = data.tolist() - fhandle.close() - - # If we have to, append 0's to create min_size samples of data - if(len(data) < min_size): - data += (min_size - len(data)) * [scipy.int32(0)] - - return data - -class my_top_block(gr.top_block): +class spectrogram_plot_i(plot_base.plot_base): def __init__(self, filelist, fc, samp_rate, psdsize, start, - nsamples, max_nsamples, scale, avg=1.0): - gr.top_block.__init__(self) - - self._filelist = filelist - self._center_freq = fc - self._samp_rate = samp_rate - self._psd_size = psdsize - self._start = start - self._max_nsamps = max_nsamples - self._scale = scale - self._nsigs = len(self._filelist) - self._avg = avg - - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples - - self.qapp = QtGui.QApplication(sys.argv) - - self.skip = gr.skiphead(gr.sizeof_float, self._start) - self.add = blocks.add_ff() + nsamples, max_nsamples, avg=1.0): + plot_base.plot_base.__init__(self, filelist, fc, samp_rate, + psdsize, start, nsamples, + max_nsamples, avg) + + self.read_samples = plot_base.read_samples_i + self.dsize = gr.sizeof_float + self.src_type = plot_base.source_ints_to_float self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._center_freq, self._samp_rate, - "GNU Radio Spectrogram Plot") - n = 0 - self.srcs = list() - self.cnvrt = list() - for f in filelist: - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - self.srcs.append(gr.vector_source_i(data)) - self.cnvrt.append(blocks.int_to_float(1, self._scale)) - n += 1 - - self.connect(self.add, self.skip) - self.connect(self.skip, (self.gui_snk, 0)) - - for i,s in enumerate(self.srcs): - self.connect(s, self.cnvrt[i], (self.add, i)) - - self.gui_snk.set_update_time(0); - self.gui_snk.set_fft_average(self._avg) - - # Get Python Qt references - pyQt = self.gui_snk.pyqwidget() - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - - def get_gui(self): - return self.pyWin - - def reset(self, newstart, newnsamps): - self.stop() - self.wait() - - self._start = newstart - self._nsamps = newnsamps - - for s,f in zip(self.srcs, self._filelist): - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - s.set_data(data) - - self.start() + "GNU Radio Spectrogram Plot", 1) + self.setup() def main(): - description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of integers." - parser = OptionParser(option_class=eng_option, description=description, - conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") - parser.add_option("-S", "--start", type="int", default=0, - help="Starting sample number [default=%default]") - parser.add_option("-L", "--psd-size", type="int", default=2048, - help="Set the FFT size of the PSD [default=%default]") - parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, - help="Set the center frequency of the signal [default=%default]") - parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, - help="Set the sample rate of the signal [default=%default]") - parser.add_option("-a", "--average", type="float", default=1.0, - help="Set amount of averaging (smaller=more averaging) [default=%default]") - parser.add_option("-s", "--scale", type="eng_float", default=2**(32-1)-1, - help="Set a scaling factor for the int->float conversion [default=%default]") - (options, args) = parser.parse_args() - - if(len(args) < 1): - parser.print_help() - sys.exit(0) + description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of ints." + (options, args) = plot_base.setup_options(description) filelist = list(args) + max_nsamples = plot_base.find_max_nsamples(filelist) - nsamples = options.nsamples - - # Find the smallest number of samples in all files and use that as - # a maximum value possible. - filesizes = [] - for f in filelist: - if(os.path.exists(f)): - filesizes.append(os.path.getsize(f) / gr.sizeof_int) - max_nsamples = min(filesizes) - - tb = my_top_block(filelist, - options.center_frequency, options.sample_rate, - options.psd_size, - options.start, nsamples, max_nsamples, - options.scale, options.average); + tb = spectrogram_plot_i(filelist, + options.center_frequency, options.sample_rate, + options.psd_size, + options.start, options.nsamples, max_nsamples, + options.average); - main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box = plot_base.dialog_box(tb, 'GNU Radio Spectrogram Plot', False) main_box.show() tb.run() diff --git a/gr-qtgui/apps/gr_spectrogram_plot_s b/gr-qtgui/apps/gr_spectrogram_plot_s index bb3573ba2c..03cb231e4f 100755 --- a/gr-qtgui/apps/gr_spectrogram_plot_s +++ b/gr-qtgui/apps/gr_spectrogram_plot_s @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,12 @@ # from gnuradio import gr -from gnuradio import blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import os, sys +import scipy + +try: + import gnuradio.qtgui.plot_spectrogram_base as plot_base +except ImportError: + import plot_spectrogram_base as plot_base try: from gnuradio import qtgui @@ -34,141 +36,35 @@ except ImportError: print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) -try: - import scipy -except ImportError: - print "Error: Scipy required (www.scipy.org)." - sys.exit(1) - -try: - from gnuradio.qtgui.plot_form import * -except ImportError: - from plot_form import * - -def read_samples_and_pad(filename, start, in_size, min_size): - # Read in_size number of samples from file - fhandle = open(filename, 'r') - fhandle.seek(start*gr.sizeof_short, 0) - data = scipy.fromfile(fhandle, dtype=scipy.int16, count=in_size) - data = data.tolist() - fhandle.close() - - # If we have to, append 0's to create min_size samples of data - if(len(data) < min_size): - data += (min_size - len(data)) * [scipy.int16(0)] - - return data - -class my_top_block(gr.top_block): +class spectrogram_plot_s(plot_base.plot_base): def __init__(self, filelist, fc, samp_rate, psdsize, start, - nsamples, max_nsamples, scale, avg=1.0): - gr.top_block.__init__(self) - - self._filelist = filelist - self._center_freq = fc - self._samp_rate = samp_rate - self._psd_size = psdsize - self._start = start - self._max_nsamps = max_nsamples - self._scale = scale - self._nsigs = len(self._filelist) - self._avg = avg - - if(nsamples is None): - self._nsamps = max_nsamples - else: - self._nsamps = nsamples - - self.qapp = QtGui.QApplication(sys.argv) - - self.skip = gr.skiphead(gr.sizeof_float, self._start) - self.add = blocks.add_ff() + nsamples, max_nsamples, avg=1.0): + plot_base.plot_base.__init__(self, filelist, fc, samp_rate, + psdsize, start, nsamples, + max_nsamples, avg) + + self.read_samples = plot_base.read_samples_s + self.dsize = gr.sizeof_float + self.src_type = plot_base.source_shorts_to_float self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS, self._center_freq, self._samp_rate, - "GNU Radio Spectrogram Plot") - n = 0 - self.srcs = list() - self.cnvrt = list() - for f in filelist: - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - self.srcs.append(gr.vector_source_s(data)) - self.cnvrt.append(blocks.short_to_float(1, self._scale)) - n += 1 - - self.connect(self.add, self.skip) - self.connect(self.skip, (self.gui_snk, 0)) - - for i,s in enumerate(self.srcs): - self.connect(s, self.cnvrt[i], (self.add, i)) - - self.gui_snk.set_update_time(0); - self.gui_snk.set_fft_average(self._avg) - - # Get Python Qt references - pyQt = self.gui_snk.pyqwidget() - self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) - - def get_gui(self): - return self.pyWin - - def reset(self, newstart, newnsamps): - self.stop() - self.wait() - - self._start = newstart - self._nsamps = newnsamps - - for s,f in zip(self.srcs, self._filelist): - data = read_samples_and_pad(f, self._start, - self._nsamps, self._psd_size) - s.set_data(data) - - self.start() + "GNU Radio Spectrogram Plot", 1) + self.setup() def main(): description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of shorts." - parser = OptionParser(option_class=eng_option, description=description, - conflict_handler="resolve") - parser.add_option("-N", "--nsamples", type="int", default=None, - help="Set the number of samples to display [default=prints entire file]") - parser.add_option("-S", "--start", type="int", default=0, - help="Starting sample number [default=%default]") - parser.add_option("-L", "--psd-size", type="int", default=2048, - help="Set the FFT size of the PSD [default=%default]") - parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, - help="Set the center frequency of the signal [default=%default]") - parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, - help="Set the sample rate of the signal [default=%default]") - parser.add_option("-a", "--average", type="float", default=1.0, - help="Set amount of averaging (smaller=more averaging) [default=%default]") - parser.add_option("-s", "--scale", type="eng_float", default=2**(16-1)-1, - help="Set a scaling factor for the short->float conversion [default=%default]") - (options, args) = parser.parse_args() - - if(len(args) < 1): - parser.print_help() - sys.exit(0) + (options, args) = plot_base.setup_options(description) filelist = list(args) + max_nsamples = plot_base.find_max_nsamples(filelist) - nsamples = options.nsamples - - # Find the smallest number of samples in all files and use that as - # a maximum value possible. - filesizes = [] - for f in filelist: - if(os.path.exists(f)): - filesizes.append(os.path.getsize(f) / gr.sizeof_short) - max_nsamples = min(filesizes) - - tb = my_top_block(filelist, - options.center_frequency, options.sample_rate, - options.psd_size, - options.start, nsamples, max_nsamples, - options.scale, options.average); + tb = spectrogram_plot_s(filelist, + options.center_frequency, options.sample_rate, + options.psd_size, + options.start, options.nsamples, max_nsamples, + options.average); - main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box = plot_base.dialog_box(tb, 'GNU Radio Spectrogram Plot', False) main_box.show() tb.run() diff --git a/gr-qtgui/apps/plot_spectrogram_base.py b/gr-qtgui/apps/plot_spectrogram_base.py new file mode 100644 index 0000000000..b48eb1526c --- /dev/null +++ b/gr-qtgui/apps/plot_spectrogram_base.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, blocks +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import os, sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) + +try: + import scipy +except ImportError: + print "Error: Scipy required (www.scipy.org)." + sys.exit(1) + +try: + from gnuradio.qtgui.plot_form import * + from gnuradio.qtgui.plot_base import * +except ImportError: + from plot_form import * + from plot_base import * + +class plot_base(gr.top_block): + def __init__(self, filelist, fc, samp_rate, psdsize, start, + nsamples, max_nsamples, avg=1.0): + gr.top_block.__init__(self) + + self._filelist = filelist + self._center_freq = fc + self._samp_rate = samp_rate + self._psd_size = psdsize + self._start = start + self._max_nsamps = max_nsamples + self._nsigs = len(self._filelist) + self._avg = avg + self._nsamps = nsamples + self._auto_scale = False + + self._y_min = -200 + self._y_max = 400 + self._y_range = 130 + self._y_value = 10 + + self._is_setup = False + + self.qapp = QtGui.QApplication(sys.argv) + + def setup(self): + self.skip = gr.skiphead(self.dsize, self._start) + + n = 0 + self.srcs = list() + self._data_min = sys.maxint + self._data_max = -sys.maxint - 1 + for f in self._filelist: + data,_min,_max = self.read_samples(f, self._start, + self._nsamps, self._psd_size) + if(_min < self._data_min): + self._data_min = _min + if(_max > self._data_max): + self._data_max = _max + + self.srcs.append(self.src_type(data)) + + n += 1 + + self.connect(self.srcs[0], self.skip) + self.connect(self.skip, (self.gui_snk, 0)) + + for i,s in enumerate(self.srcs[1:]): + self.connect(s, (self.gui_snk, i+1)) + + self.gui_snk.set_update_time(0); + self.gui_snk.set_fft_average(self._avg) + + # Get Python Qt references + pyQt = self.gui_snk.pyqwidget() + self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self._is_setup = True + + def is_setup(self): + return self._is_setup + + def set_y_axis(self, y_min, y_max): + self.gui_snk.set_intensity_range(y_min, y_max) + return y_min, y_max + + def get_gui(self): + if(self.is_setup()): + return self.pyWin + else: + return None + + def reset(self, newstart, newnsamps): + self.stop() + self.wait() + self.gui_snk.clear_data() + + self._start = newstart + self._nsamps = newnsamps + + self._data_min = sys.maxint + self._data_max = -sys.maxint - 1 + for s,f in zip(self.srcs, self._filelist): + data,_min,_max = self.read_samples(f, self._start, newnsamps, self._psd_size) + if(_min < self._data_min): + self._data_min = _min + if(_max > self._data_max): + self._data_max = _max + + s.set_data(data) + + self.start() + +def setup_options(desc): + parser = OptionParser(option_class=eng_option, description=desc, + conflict_handler="resolve") + parser.add_option("-N", "--nsamples", type="int", default=1000000, + help="Set the number of samples to display [default=%default]") + parser.add_option("-S", "--start", type="int", default=0, + help="Starting sample number [default=%default]") + parser.add_option("-L", "--psd-size", type="int", default=2048, + help="Set the FFT size of the PSD [default=%default]") + parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0, + help="Set the center frequency of the signal [default=%default]") + parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0, + help="Set the sample rate of the signal [default=%default]") + parser.add_option("-a", "--average", type="float", default=1.0, + help="Set amount of averaging (smaller=more averaging) [default=%default]") + (options, args) = parser.parse_args() + + if(len(args) < 1): + parser.print_help() + sys.exit(0) + + return (options, args) + |