summaryrefslogtreecommitdiff
path: root/gr-wxgui/src/python/histo_window.py
diff options
context:
space:
mode:
Diffstat (limited to 'gr-wxgui/src/python/histo_window.py')
-rw-r--r--gr-wxgui/src/python/histo_window.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/gr-wxgui/src/python/histo_window.py b/gr-wxgui/src/python/histo_window.py
new file mode 100644
index 000000000..dce52ff9b
--- /dev/null
+++ b/gr-wxgui/src/python/histo_window.py
@@ -0,0 +1,154 @@
+#
+# Copyright 2009 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.
+#
+
+##################################################
+# Imports
+##################################################
+import plotter
+import common
+import wx
+import numpy
+import math
+import pubsub
+from constants import *
+from gnuradio import gr #for gr.prefs
+
+##################################################
+# Constants
+##################################################
+DEFAULT_WIN_SIZE = (600, 300)
+
+##################################################
+# histo window control panel
+##################################################
+class control_panel(wx.Panel):
+ """
+ A control panel with wx widgits to control the plotter and histo sink.
+ """
+
+ def __init__(self, parent):
+ """
+ Create a new control panel.
+ @param parent the wx parent window
+ """
+ self.parent = parent
+ wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+ control_box = wx.BoxSizer(wx.VERTICAL)
+ SIZE = (100, -1)
+ control_box.Add(common.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
+ control_box.AddStretchSpacer()
+ #num bins
+ def num_bins_cast(num):
+ num = int(num)
+ assert num > 1
+ return num
+ num_bins_ctrl = common.TextBoxController(self, parent, NUM_BINS_KEY, cast=num_bins_cast)
+ control_box.Add(common.LabelBox(self, ' Num Bins ', num_bins_ctrl), 0, wx.EXPAND)
+ control_box.AddStretchSpacer()
+ #frame size
+ frame_size_ctrl = common.TextBoxController(self, parent, FRAME_SIZE_KEY, cast=num_bins_cast)
+ control_box.Add(common.LabelBox(self, ' Frame Size ', frame_size_ctrl), 0, wx.EXPAND)
+ control_box.AddStretchSpacer()
+ #run/stop
+ self.run_button = common.ToggleButtonController(self, parent, RUNNING_KEY, 'Stop', 'Run')
+ control_box.Add(self.run_button, 0, wx.EXPAND)
+ #set sizer
+ self.SetSizerAndFit(control_box)
+
+##################################################
+# histo window with plotter and control panel
+##################################################
+class histo_window(wx.Panel, pubsub.pubsub):
+ def __init__(
+ self,
+ parent,
+ controller,
+ size,
+ title,
+ maximum_key,
+ minimum_key,
+ num_bins_key,
+ frame_size_key,
+ msg_key,
+ ):
+ pubsub.pubsub.__init__(self)
+ #setup
+ self.samples = list()
+ #proxy the keys
+ self.proxy(MAXIMUM_KEY, controller, maximum_key)
+ self.proxy(MINIMUM_KEY, controller, minimum_key)
+ self.proxy(NUM_BINS_KEY, controller, num_bins_key)
+ self.proxy(FRAME_SIZE_KEY, controller, frame_size_key)
+ self.proxy(MSG_KEY, controller, msg_key)
+ #init panel and plot
+ wx.Panel.__init__(self, parent, style=wx.SIMPLE_BORDER)
+ self.plotter = plotter.bar_plotter(self)
+ self.plotter.SetSize(wx.Size(*size))
+ self.plotter.set_title(title)
+ self.plotter.enable_point_label(True)
+ self.plotter.enable_grid_lines(False)
+ #setup the box with plot and controls
+ self.control_panel = control_panel(self)
+ main_box = wx.BoxSizer(wx.HORIZONTAL)
+ main_box.Add(self.plotter, 1, wx.EXPAND)
+ main_box.Add(self.control_panel, 0, wx.EXPAND)
+ self.SetSizerAndFit(main_box)
+ #initialize values
+ self[NUM_BINS_KEY] = self[NUM_BINS_KEY]
+ self[FRAME_SIZE_KEY] = self[FRAME_SIZE_KEY]
+ self[RUNNING_KEY] = True
+ self[X_DIVS_KEY] = 8
+ self[Y_DIVS_KEY] = 4
+ #register events
+ self.subscribe(MSG_KEY, self.handle_msg)
+ self.subscribe(X_DIVS_KEY, self.update_grid)
+ self.subscribe(Y_DIVS_KEY, self.update_grid)
+
+ def handle_msg(self, msg):
+ """
+ Handle the message from the fft sink message queue.
+ @param msg the frame as a character array
+ """
+ if not self[RUNNING_KEY]: return
+ #convert to floating point numbers
+ self.samples = 100*numpy.fromstring(msg, numpy.float32)[:self[NUM_BINS_KEY]] #only take first frame
+ self.plotter.set_bars(
+ bars=self.samples,
+ bar_width=0.6,
+ color_spec=(0, 0, 1),
+ )
+ self.update_grid()
+
+ def update_grid(self):
+ if not len(self.samples): return
+ #calculate the maximum y value
+ y_off = math.ceil(numpy.max(self.samples))
+ y_off = min(max(y_off, 1.0), 100.0) #between 1% and 100%
+ #update the x grid
+ self.plotter.set_x_grid(
+ self[MINIMUM_KEY], self[MAXIMUM_KEY],
+ common.get_clean_num((self[MAXIMUM_KEY] - self[MINIMUM_KEY])/self[X_DIVS_KEY]),
+ )
+ self.plotter.set_x_label('Counts')
+ #update the y grid
+ self.plotter.set_y_grid(0, y_off, y_off/self[Y_DIVS_KEY])
+ self.plotter.set_y_label('Frequency', '%')
+ self.plotter.update()