summaryrefslogtreecommitdiff
path: root/gr-wxgui/src/python/fft_window.py
diff options
context:
space:
mode:
authorjcorgan2009-03-20 02:16:20 +0000
committerjcorgan2009-03-20 02:16:20 +0000
commitd9744799b7df6c09180778540bf55eb9dc84281b (patch)
tree311339459f5fae94417321c08b4d48710e03f30e /gr-wxgui/src/python/fft_window.py
parent88304ce16a97945d13510b5fdaefcc0f62462d9d (diff)
downloadgnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.tar.gz
gnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.tar.bz2
gnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.zip
Merged r10463:10658 from jblum/gui_guts into trunk. Trunk passes distcheck.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10660 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gr-wxgui/src/python/fft_window.py')
-rw-r--r--gr-wxgui/src/python/fft_window.py123
1 files changed, 63 insertions, 60 deletions
diff --git a/gr-wxgui/src/python/fft_window.py b/gr-wxgui/src/python/fft_window.py
index 6e54aec87..fdd5562dc 100644
--- a/gr-wxgui/src/python/fft_window.py
+++ b/gr-wxgui/src/python/fft_window.py
@@ -39,8 +39,8 @@ AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
DEFAULT_WIN_SIZE = (600, 300)
DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'fft_rate', 30)
DIV_LEVELS = (1, 2, 5, 10, 20)
-FFT_PLOT_COLOR_SPEC = (0, 0, 1)
-PEAK_VALS_COLOR_SPEC = (0, 1, 0)
+FFT_PLOT_COLOR_SPEC = (0.3, 0.3, 1.0)
+PEAK_VALS_COLOR_SPEC = (0.0, 0.8, 0.0)
NO_PEAK_VALS = list()
##################################################
@@ -57,31 +57,31 @@ class control_panel(wx.Panel):
@param parent the wx parent window
"""
self.parent = parent
- wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
+ wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
control_box = wx.BoxSizer(wx.VERTICAL)
#checkboxes for average and peak hold
control_box.AddStretchSpacer()
control_box.Add(common.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
- self.average_check_box = common.CheckBoxController(self, 'Average', parent.ext_controller, parent.average_key)
- control_box.Add(self.average_check_box, 0, wx.EXPAND)
- self.peak_hold_check_box = common.CheckBoxController(self, 'Peak Hold', parent, PEAK_HOLD_KEY)
- control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND)
+ peak_hold_check_box = common.CheckBoxController(self, 'Peak Hold', parent, PEAK_HOLD_KEY)
+ control_box.Add(peak_hold_check_box, 0, wx.EXPAND)
+ average_check_box = common.CheckBoxController(self, 'Average', parent, AVERAGE_KEY)
+ control_box.Add(average_check_box, 0, wx.EXPAND)
control_box.AddSpacer(2)
- self.avg_alpha_slider = common.LogSliderController(
+ avg_alpha_slider = common.LogSliderController(
self, 'Avg Alpha',
AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP, SLIDER_STEPS,
- parent.ext_controller, parent.avg_alpha_key,
+ parent, AVG_ALPHA_KEY,
formatter=lambda x: ': %.4f'%x,
)
- parent.ext_controller.subscribe(parent.average_key, self.avg_alpha_slider.Enable)
- control_box.Add(self.avg_alpha_slider, 0, wx.EXPAND)
+ parent.subscribe(AVERAGE_KEY, avg_alpha_slider.Enable)
+ control_box.Add(avg_alpha_slider, 0, wx.EXPAND)
#radio buttons for div size
control_box.AddStretchSpacer()
control_box.Add(common.LabelText(self, 'Set dB/div'), 0, wx.ALIGN_CENTER)
radio_box = wx.BoxSizer(wx.VERTICAL)
self.radio_buttons = list()
for y_per_div in DIV_LEVELS:
- radio_button = wx.RadioButton(self, -1, "%d dB/div"%y_per_div)
+ radio_button = wx.RadioButton(self, label="%d dB/div"%y_per_div)
radio_button.Bind(wx.EVT_RADIOBUTTON, self._on_y_per_div)
self.radio_buttons.append(radio_button)
radio_box.Add(radio_button, 0, wx.ALIGN_LEFT)
@@ -91,18 +91,23 @@ class control_panel(wx.Panel):
control_box.AddStretchSpacer()
control_box.Add(common.LabelText(self, 'Set Ref Level'), 0, wx.ALIGN_CENTER)
control_box.AddSpacer(2)
- self._ref_lvl_buttons = common.IncrDecrButtons(self, self._on_incr_ref_level, self._on_decr_ref_level)
- control_box.Add(self._ref_lvl_buttons, 0, wx.ALIGN_CENTER)
+ _ref_lvl_buttons = common.IncrDecrButtons(self, self._on_incr_ref_level, self._on_decr_ref_level)
+ control_box.Add(_ref_lvl_buttons, 0, wx.ALIGN_CENTER)
#autoscale
control_box.AddStretchSpacer()
- self.autoscale_button = wx.Button(self, label='Autoscale', style=wx.BU_EXACTFIT)
- self.autoscale_button.Bind(wx.EVT_BUTTON, self.parent.autoscale)
- control_box.Add(self.autoscale_button, 0, wx.EXPAND)
+ autoscale_button = wx.Button(self, label='Autoscale', style=wx.BU_EXACTFIT)
+ autoscale_button.Bind(wx.EVT_BUTTON, self.parent.autoscale)
+ control_box.Add(autoscale_button, 0, wx.EXPAND)
#run/stop
- self.run_button = common.ToggleButtonController(self, parent, RUNNING_KEY, 'Stop', 'Run')
- control_box.Add(self.run_button, 0, wx.EXPAND)
+ run_button = common.ToggleButtonController(self, parent, RUNNING_KEY, 'Stop', 'Run')
+ control_box.Add(run_button, 0, wx.EXPAND)
#set sizer
self.SetSizerAndFit(control_box)
+ #mouse wheel event
+ def on_mouse_wheel(event):
+ if event.GetWheelRotation() < 0: self._on_incr_ref_level(event)
+ else: self._on_decr_ref_level(event)
+ parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)
##################################################
# Event handlers
@@ -117,16 +122,14 @@ class control_panel(wx.Panel):
index = self.radio_buttons.index(selected_radio_button)
self.parent[Y_PER_DIV_KEY] = DIV_LEVELS[index]
def _on_incr_ref_level(self, event):
- self.parent.set_ref_level(
- self.parent[REF_LEVEL_KEY] + self.parent[Y_PER_DIV_KEY])
+ self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[Y_PER_DIV_KEY]
def _on_decr_ref_level(self, event):
- self.parent.set_ref_level(
- self.parent[REF_LEVEL_KEY] - self.parent[Y_PER_DIV_KEY])
+ self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[Y_PER_DIV_KEY]
##################################################
# FFT window with plotter and control panel
##################################################
-class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
+class fft_window(wx.Panel, pubsub.pubsub):
def __init__(
self,
parent,
@@ -150,47 +153,48 @@ class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
if y_per_div not in DIV_LEVELS: y_per_div = DIV_LEVELS[0]
#setup
self.samples = list()
- self.ext_controller = controller
self.real = real
self.fft_size = fft_size
- self.sample_rate_key = sample_rate_key
- self.average_key = average_key
- self.avg_alpha_key = avg_alpha_key
self._reset_peak_vals()
+ #proxy the keys
+ self.proxy(MSG_KEY, controller, msg_key)
+ self.proxy(AVERAGE_KEY, controller, average_key)
+ self.proxy(AVG_ALPHA_KEY, controller, avg_alpha_key)
+ self.proxy(SAMPLE_RATE_KEY, controller, sample_rate_key)
#init panel and plot
- wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)
+ wx.Panel.__init__(self, parent, style=wx.SIMPLE_BORDER)
self.plotter = plotter.channel_plotter(self)
self.plotter.SetSize(wx.Size(*size))
self.plotter.set_title(title)
+ self.plotter.enable_legend(True)
self.plotter.enable_point_label(True)
+ self.plotter.enable_grid_lines(True)
#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)
- #initial setup
- self.ext_controller[self.average_key] = self.ext_controller[self.average_key]
- self.ext_controller[self.avg_alpha_key] = self.ext_controller[self.avg_alpha_key]
- self._register_set_prop(self, PEAK_HOLD_KEY, peak_hold)
- self._register_set_prop(self, Y_PER_DIV_KEY, y_per_div)
- self._register_set_prop(self, Y_DIVS_KEY, y_divs)
- self._register_set_prop(self, X_DIVS_KEY, 8) #approximate
- self._register_set_prop(self, REF_LEVEL_KEY, ref_level)
- self._register_set_prop(self, BASEBAND_FREQ_KEY, baseband_freq)
- self._register_set_prop(self, RUNNING_KEY, True)
+ #initialize values
+ self[AVERAGE_KEY] = self[AVERAGE_KEY]
+ self[AVG_ALPHA_KEY] = self[AVG_ALPHA_KEY]
+ self[PEAK_HOLD_KEY] = peak_hold
+ self[Y_PER_DIV_KEY] = y_per_div
+ self[Y_DIVS_KEY] = y_divs
+ self[X_DIVS_KEY] = 8 #approximate
+ self[REF_LEVEL_KEY] = ref_level
+ self[BASEBAND_FREQ_KEY] = baseband_freq
+ self[RUNNING_KEY] = True
#register events
- self.subscribe(PEAK_HOLD_KEY, self.plotter.enable_legend)
- self.ext_controller.subscribe(AVERAGE_KEY, lambda x: self._reset_peak_vals())
- self.ext_controller.subscribe(msg_key, self.handle_msg)
- self.ext_controller.subscribe(self.sample_rate_key, self.update_grid)
+ self.subscribe(AVERAGE_KEY, lambda x: self._reset_peak_vals())
+ self.subscribe(MSG_KEY, self.handle_msg)
+ self.subscribe(SAMPLE_RATE_KEY, self.update_grid)
for key in (
BASEBAND_FREQ_KEY,
Y_PER_DIV_KEY, X_DIVS_KEY,
Y_DIVS_KEY, REF_LEVEL_KEY,
): self.subscribe(key, self.update_grid)
#initial update
- self.plotter.enable_legend(self[PEAK_HOLD_KEY])
self.update_grid()
def autoscale(self, *args):
@@ -207,9 +211,9 @@ class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
noise_floor -= abs(noise_floor)*.5
peak_level += abs(peak_level)*.1
#set the reference level to a multiple of y divs
- self.set_ref_level(self[Y_DIVS_KEY]*math.ceil(peak_level/self[Y_DIVS_KEY]))
+ self[REF_LEVEL_KEY] = self[Y_DIVS_KEY]*math.ceil(peak_level/self[Y_DIVS_KEY])
#set the range to a clean number of the dynamic range
- self.set_y_per_div(common.get_clean_num((peak_level - noise_floor)/self[Y_DIVS_KEY]))
+ self[Y_PER_DIV_KEY] = common.get_clean_num((peak_level - noise_floor)/self[Y_DIVS_KEY])
def _reset_peak_vals(self): self.peak_vals = NO_PEAK_VALS
@@ -234,19 +238,21 @@ class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
if self[PEAK_HOLD_KEY]:
if len(self.peak_vals) != len(samples): self.peak_vals = samples
self.peak_vals = numpy.maximum(samples, self.peak_vals)
- else: self._reset_peak_vals()
+ #plot the peak hold
+ self.plotter.set_waveform(
+ channel='Peak',
+ samples=self.peak_vals,
+ color_spec=PEAK_VALS_COLOR_SPEC,
+ )
+ else:
+ self._reset_peak_vals()
+ self.plotter.clear_waveform(channel='Peak')
#plot the fft
self.plotter.set_waveform(
channel='FFT',
samples=samples,
color_spec=FFT_PLOT_COLOR_SPEC,
)
- #plot the peak hold
- self.plotter.set_waveform(
- channel='Peak',
- samples=self.peak_vals,
- color_spec=PEAK_VALS_COLOR_SPEC,
- )
#update the plotter
self.plotter.update()
@@ -259,7 +265,7 @@ class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
The y axis depends on y per div, y divs, and ref level.
"""
#grid parameters
- sample_rate = self.ext_controller[self.sample_rate_key]
+ sample_rate = self[SAMPLE_RATE_KEY]
baseband_freq = self[BASEBAND_FREQ_KEY]
y_per_div = self[Y_PER_DIV_KEY]
y_divs = self[Y_DIVS_KEY]
@@ -269,24 +275,21 @@ class fft_window(wx.Panel, pubsub.pubsub, common.prop_setter):
if self.real: x_width = sample_rate/2.0
else: x_width = sample_rate/1.0
x_per_div = common.get_clean_num(x_width/x_divs)
- coeff, exp, prefix = common.get_si_components(abs(baseband_freq) + abs(sample_rate/2.0))
#update the x grid
if self.real:
self.plotter.set_x_grid(
baseband_freq,
baseband_freq + sample_rate/2.0,
- x_per_div,
- 10**(-exp),
+ x_per_div, True,
)
else:
self.plotter.set_x_grid(
baseband_freq - sample_rate/2.0,
baseband_freq + sample_rate/2.0,
- x_per_div,
- 10**(-exp),
+ x_per_div, True,
)
#update x units
- self.plotter.set_x_label('Frequency', prefix+'Hz')
+ self.plotter.set_x_label('Frequency', 'Hz')
#update y grid
self.plotter.set_y_grid(ref_level-y_per_div*y_divs, ref_level, y_per_div)
#update y units