Changeset 8581
- Timestamp:
- 06/11/08 18:29:56
- Files:
-
- gnuradio/trunk/gr-wxgui/src/python/fftsink2.py (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gnuradio/trunk/gr-wxgui/src/python/fftsink2.py
r8279 r8581 69 69 else: 70 70 self.avg.set_taps(1.0) 71 self.win.peak_vals = None72 71 self.win.peak_vals = None 72 73 73 def set_peak_hold(self, enable): 74 74 self.peak_hold = enable … … 121 121 # FIXME We need to add 3dB to all bins but the DC bin 122 122 self.log = gr.nlog10_ff(20, self.fft_size, 123 -10*math.log10(self.fft_size) # Adjust for number of bins124 -10*math.log10(power/self.fft_size)# Adjust for windowing loss125 -20*math.log10(ref_scale/2))# Adjust for reference scale126 123 -10*math.log10(self.fft_size) # Adjust for number of bins 124 -10*math.log10(power/self.fft_size) # Adjust for windowing loss 125 -20*math.log10(ref_scale/2)) # Adjust for reference scale 126 127 127 self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) 128 self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink)128 self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink) 129 129 130 130 self.win = fft_window(self, parent, size=size) 131 131 self.set_average(self.average) 132 132 self.set_peak_hold(self.peak_hold) 133 133 134 134 class fft_sink_c(gr.hier_block2, fft_sink_base): … … 164 164 # FIXME We need to add 3dB to all bins but the DC bin 165 165 self.log = gr.nlog10_ff(20, self.fft_size, 166 -10*math.log10(self.fft_size) # Adjust for number of bins167 -10*math.log10(power/self.fft_size)# Adjust for windowing loss168 -20*math.log10(ref_scale/2))# Adjust for reference scale169 166 -10*math.log10(self.fft_size) # Adjust for number of bins 167 -10*math.log10(power/self.fft_size) # Adjust for windowing loss 168 -20*math.log10(ref_scale/2)) # Adjust for reference scale 169 170 170 self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) 171 self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink)171 self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink) 172 172 173 173 self.win = fft_window(self, parent, size=size) 174 174 self.set_average(self.average) 175 self.set_peak_hold(self.peak_hold) 175 176 176 177 … … 219 220 wx.PostEvent (self.event_receiver, de) 220 221 del de 222 223 class LabelText(wx.StaticText): 224 """Label text class for uniform labels among all controls.""" 221 225 222 223 class fft_window (plot.PlotCanvas): 226 def __init__(self, window, label): 227 wx.StaticText.__init__(self, window, -1, str(label)) 228 font = self.GetFont() 229 font.SetWeight(wx.FONTWEIGHT_BOLD) 230 font.SetUnderlined(True) 231 self.SetFont(font) 232 233 DIV_LEVELS = (1, 2, 5, 10, 20) 234 235 class control_panel(wx.Panel): 236 def __init__(self, parent): 237 self.parent = parent 238 wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER) 239 control_box = wx.BoxSizer(wx.VERTICAL) 240 241 #checkboxes for average and peak hold 242 control_box.Add(LabelText(self, 'Options'), 0, wx.ALIGN_CENTER) 243 self.average_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Average") 244 self.average_check_box.SetValue(parent.fftsink.average) 245 self.average_check_box.Bind(wx.EVT_CHECKBOX, parent.on_average) 246 control_box.Add(self.average_check_box, 0, wx.EXPAND) 247 self.peak_hold_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Peak Hold") 248 self.peak_hold_check_box.SetValue(parent.fftsink.peak_hold) 249 self.peak_hold_check_box.Bind(wx.EVT_CHECKBOX, parent.on_peak_hold) 250 control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND) 251 252 #radio buttons for div size 253 control_box.Add(LabelText(self, 'Set dB/div'), 0, wx.ALIGN_CENTER) 254 radio_box = wx.BoxSizer(wx.VERTICAL) 255 self.radio_buttons = list() 256 for y_per_div in DIV_LEVELS: 257 radio_button = wx.RadioButton(self, -1, "%d dB/div"%y_per_div) 258 radio_button.SetValue(parent.fftsink.y_per_div == y_per_div) 259 radio_button.Bind(wx.EVT_RADIOBUTTON, self.on_radio_button_change) 260 self.radio_buttons.append(radio_button) 261 radio_box.Add(radio_button, 0, wx.ALIGN_LEFT) 262 control_box.Add(radio_box, 0, wx.EXPAND) 263 264 #ref lvl buttons 265 control_box.Add(LabelText(self, 'Adj Ref Lvl'), 0, wx.ALIGN_CENTER) 266 button_box = wx.BoxSizer(wx.HORIZONTAL) 267 self.ref_plus_button = wx.Button(self, -1, '+', style=wx.BU_EXACTFIT) 268 self.ref_plus_button.Bind(wx.EVT_BUTTON, parent.on_incr_ref_level) 269 button_box.Add(self.ref_plus_button, 0, wx.ALIGN_CENTER) 270 self.ref_minus_button = wx.Button(self, -1, ' - ', style=wx.BU_EXACTFIT) 271 self.ref_minus_button.Bind(wx.EVT_BUTTON, parent.on_decr_ref_level) 272 button_box.Add(self.ref_minus_button, 0, wx.ALIGN_CENTER) 273 control_box.Add(button_box, 0, wx.ALIGN_CENTER) 274 #set sizer 275 self.SetSizerAndFit(control_box) 276 277 def on_radio_button_change(self, evt): 278 selected_radio_button = filter(lambda rb: rb.GetValue(), self.radio_buttons)[0] 279 index = self.radio_buttons.index(selected_radio_button) 280 self.parent.fftsink.set_y_per_div(DIV_LEVELS[index]) 281 282 class fft_window (wx.Panel): 224 283 def __init__ (self, fftsink, parent, id = -1, 225 284 pos = wx.DefaultPosition, size = wx.DefaultSize, 226 285 style = wx.DEFAULT_FRAME_STYLE, name = ""): 227 plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) 228 286 287 self.fftsink = fftsink 288 #init panel and plot 289 wx.Panel.__init__(self, parent, -1) 290 self.plot = plot.PlotCanvas(self, id, pos, size, style, name) 291 #setup the box with plot and controls 292 self.control_panel = control_panel(self) 293 main_box = wx.BoxSizer (wx.HORIZONTAL) 294 main_box.Add (self.plot, 1, wx.EXPAND) 295 main_box.Add (self.control_panel, 0, wx.EXPAND) 296 self.SetSizerAndFit(main_box) 297 229 298 self.y_range = None 230 self.fftsink = fftsink231 299 self.peak_hold = False 232 300 self.peak_vals = None 233 301 234 self. SetEnableGrid (True)302 self.plot.SetEnableGrid (True) 235 303 # self.SetEnableZoom (True) 236 304 # self.SetBackgroundColour ('black') 237 305 238 306 self.build_popup_menu() 239 self.set_baseband_freq(0.0)240 307 self.set_baseband_freq(0.0) 308 241 309 EVT_DATA_EVENT (self, self.set_data) 242 310 wx.EVT_CLOSE (self, self.on_close_window) 243 self. Bind(wx.EVT_RIGHT_UP, self.on_right_click)244 self. Bind(wx.EVT_MOTION, self.evt_motion)245 311 self.plot.Bind(wx.EVT_RIGHT_UP, self.on_right_click) 312 self.plot.Bind(wx.EVT_MOTION, self.evt_motion) 313 246 314 self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, self) 247 315 248 316 def set_scale(self, freq): 249 x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq)) 317 x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq)) 250 318 if x >= 1e9: 251 319 self._scale_factor = 1e-9 252 320 self._units = "GHz" 253 self._format = "%3.6f"321 self._format = "%3.6f" 254 322 elif x >= 1e6: 255 323 self._scale_factor = 1e-6 256 324 self._units = "MHz" 257 self._format = "%3.3f"325 self._format = "%3.3f" 258 326 else: 259 327 self._scale_factor = 1e-3 260 328 self._units = "kHz" 261 self._format = "%3.3f"329 self._format = "%3.3f" 262 330 263 331 def set_baseband_freq(self, baseband_freq): 264 if self.peak_hold:265 self.peak_vals = None266 self.set_scale(baseband_freq)267 self.fftsink.set_baseband_freq(baseband_freq)268 332 if self.peak_hold: 333 self.peak_vals = None 334 self.set_scale(baseband_freq) 335 self.fftsink.set_baseband_freq(baseband_freq) 336 269 337 def on_close_window (self, event): 270 338 print "fft_window:on_close_window" … … 284 352 if self.fftsink.input_is_real: # only plot 1/2 the points 285 353 x_vals = ((numpy.arange (L/2) * (self.fftsink.sample_rate 286 * self._scale_factor / L))354 * self._scale_factor / L)) 287 355 + self.fftsink.baseband_freq * self._scale_factor) 288 356 self._points = numpy.zeros((len(x_vals), 2), numpy.float64) 289 357 self._points[:,0] = x_vals 290 358 self._points[:,1] = dB[0:L/2] 291 if self.peak_hold:292 self._peak_points = numpy.zeros((len(x_vals), 2), numpy.float64)293 self._peak_points[:,0] = x_vals294 self._peak_points[:,1] = self.peak_vals[0:L/2]359 if self.peak_hold: 360 self._peak_points = numpy.zeros((len(x_vals), 2), numpy.float64) 361 self._peak_points[:,0] = x_vals 362 self._peak_points[:,1] = self.peak_vals[0:L/2] 295 363 else: 296 364 # the "negative freqs" are in the second half of the array … … 301 369 self._points[:,0] = x_vals 302 370 self._points[:,1] = numpy.concatenate ((dB[L/2:], dB[0:L/2])) 303 if self.peak_hold:304 self._peak_points = numpy.zeros((len(x_vals), 2), numpy.float64)305 self._peak_points[:,0] = x_vals306 self._peak_points[:,1] = numpy.concatenate ((self.peak_vals[L/2:], self.peak_vals[0:L/2]))371 if self.peak_hold: 372 self._peak_points = numpy.zeros((len(x_vals), 2), numpy.float64) 373 self._peak_points[:,0] = x_vals 374 self._peak_points[:,1] = numpy.concatenate ((self.peak_vals[L/2:], self.peak_vals[0:L/2])) 307 375 308 376 lines = [plot.PolyLine (self._points, colour='BLUE'),] 309 if self.peak_hold:310 lines.append(plot.PolyLine (self._peak_points, colour='GREEN'))377 if self.peak_hold: 378 lines.append(plot.PolyLine (self._peak_points, colour='GREEN')) 311 379 312 380 graphics = plot.PlotGraphics (lines, … … 314 382 xLabel = self._units, yLabel = "dB") 315 383 316 self. Draw (graphics, xAxis=None, yAxis=self.y_range)384 self.plot.Draw (graphics, xAxis=None, yAxis=self.y_range) 317 385 self.update_y_range () 318 386 … … 325 393 ymax = self.fftsink.ref_level 326 394 ymin = self.fftsink.ref_level - self.fftsink.y_per_div * self.fftsink.y_divs 327 self.y_range = self. _axisInterval ('min', ymin, ymax)395 self.y_range = self.plot._axisInterval ('min', ymin, ymax) 328 396 329 397 def on_average(self, evt): … … 372 440 item = menu.FindItemById(id) 373 441 item.Check(pred()) 374 self. PopupMenu(menu, event.GetPosition())442 self.plot.PopupMenu(menu, event.GetPosition()) 375 443 376 444 def evt_motion(self, event): 377 445 if not hasattr(self, "_points"): 378 return # Got here before first window data update379 380 # Clip to plotted values381 (ux, uy) = self. GetXY(event) # Scaled position446 return # Got here before first window data update 447 448 # Clip to plotted values 449 (ux, uy) = self.plot.GetXY(event) # Scaled position 382 450 x_vals = numpy.array(self._points[:,0]) 383 451 if ux < x_vals[0] or ux > x_vals[-1]: … … 411 479 self.id_average = wx.NewId() 412 480 self.id_peak_hold = wx.NewId() 413 414 self. Bind(wx.EVT_MENU, self.on_average, id=self.id_average)415 self. Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)416 self. Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)417 self. Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)418 self. Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div)419 self. Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div)420 self. Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)421 self. Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)422 self. Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)423 self. Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)424 self. Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)481 482 self.plot.Bind(wx.EVT_MENU, self.on_average, id=self.id_average) 483 self.plot.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold) 484 self.plot.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) 485 self.plot.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) 486 self.plot.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div) 487 self.plot.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div) 488 self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1) 489 self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2) 490 self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5) 491 self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10) 492 self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20) 425 493 426 494 # make a menu … … 500 568 vbox.Add (sink1.win, 1, wx.EXPAND) 501 569 502 self.connect(src1, thr1, sink1)570 self.connect(src1, thr1, sink1) 503 571 504 572 #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1) … … 510 578 vbox.Add (sink2.win, 1, wx.EXPAND) 511 579 512 self.connect(src2, thr2, sink2)580 self.connect(src2, thr2, sink2) 513 581 514 582 def main ():
