diff options
author | jcorgan | 2009-03-20 02:16:20 +0000 |
---|---|---|
committer | jcorgan | 2009-03-20 02:16:20 +0000 |
commit | d9744799b7df6c09180778540bf55eb9dc84281b (patch) | |
tree | 311339459f5fae94417321c08b4d48710e03f30e /gr-wxgui/src/python/fft_window.py | |
parent | 88304ce16a97945d13510b5fdaefcc0f62462d9d (diff) | |
download | gnuradio-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.py | 123 |
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 |