Adding a spectrogram plot. The axis need work.
[debian/gnuradio] / gr-utils / src / python / gr_plot_qt.py
1 #!/usr/bin/env python
2
3 try:
4     import scipy
5     from scipy import fftpack
6 except ImportError:
7     print "Please install SciPy to run this script (http://www.scipy.org/)"
8     raise SystemExit, 1
9
10 import sys, os
11 from PyQt4 import Qt, QtCore, QtGui
12 import PyQt4.Qwt5 as Qwt
13 from matplotlib import mlab
14 from optparse import OptionParser
15 from gnuradio import eng_notation
16
17 from pyqt_plot import Ui_MainWindow
18
19 class SpectrogramData(Qwt.QwtRasterData):
20
21     def __init__(self, f, t):
22         Qwt.QwtArrayData.__init__(self, Qt.QRectF(0, 0, 0, 0))
23         self.sp = scipy.array([[0], [0]])
24
25     def set_data(self, xfreq, ytime, data):
26         self.sp = data
27         self.freq = xfreq
28         self.time = ytime
29         boundingBox = Qt.QRectF(0, 0, self.freq.size, self.time.size)
30         self.setBoundingRect(boundingBox)
31
32     def rasterHint(self, rect):
33         return Qt.QSize(self.sp.shape[0], self.sp.shape[1])
34         
35     def copy(self):
36         return self
37
38     def range(self):
39         
40         return Qwt.QwtDoubleInterval(self.sp.min(), self.sp.max())
41
42     def value(self, x, y):
43         #print x, y
44         x = int(x)
45         y = int(y)
46         return self.sp[x][y-1]
47
48
49 class gr_plot_qt(QtGui.QMainWindow):
50     def __init__(self, qapp, filename, options, parent=None):
51         QtGui.QWidget.__init__(self, parent)
52         self.gui = Ui_MainWindow()
53         self.gui.setupUi(self)
54                        
55         self.block_length = options.block_length
56         self.start = options.start
57         self.sample_rate = options.sample_rate
58         self.psdfftsize = options.psd_size
59         self.specfftsize = options.spec_size
60         self.winfunc = scipy.blackman
61         self.sizeof_data = 8
62         self.datatype = scipy.complex64
63         self.iq = list()
64         self.time = list()
65
66         # Set up basic plot attributes
67         self.gui.timePlot.setAxisTitle(self.gui.timePlot.xBottom, "Time (sec)")
68         self.gui.timePlot.setAxisTitle(self.gui.timePlot.yLeft, "Amplitude (V)")
69         self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.xBottom, "Frequency (Hz)")
70         self.gui.freqPlot.setAxisTitle(self.gui.freqPlot.yLeft, "Magnitude (dB)")
71
72         # Set up FFT size combo box
73         self.fftsizes = ["128", "256", "512", "1024", "2048",
74                          "4096", "8192", "16384", "32768"]
75         self.gui.psdFFTComboBox.addItems(self.fftsizes)
76         self.gui.specFFTComboBox.addItems(self.fftsizes)
77         pos = self.gui.psdFFTComboBox.findText(Qt.QString("%1").arg(self.psdfftsize))
78         self.gui.psdFFTComboBox.setCurrentIndex(pos)
79         pos = self.gui.specFFTComboBox.findText(Qt.QString("%1").arg(self.specfftsize))
80         self.gui.specFFTComboBox.setCurrentIndex(pos)
81
82         self.connect(self.gui.psdFFTComboBox,
83                      Qt.SIGNAL("activated (const QString&)"),
84                      self.psdFFTComboBoxEdit)
85         self.connect(self.gui.specFFTComboBox,
86                      Qt.SIGNAL("activated (const QString&)"),
87                      self.specFFTComboBoxEdit)
88
89         # Set up color scheme box
90         self.color_modes = {"Black on White" : self.color_black_on_white,
91                             "White on Black" : self.color_white_on_black,
92                             "Blue on Black"  : self.color_blue_on_black,
93                             "Green on Black" : self.color_green_on_black}
94         self.gui.colorComboBox.addItems(self.color_modes.keys())
95         pos = self.gui.colorComboBox.findText("Blue on Black")
96         self.gui.colorComboBox.setCurrentIndex(pos)
97         self.connect(self.gui.colorComboBox,
98                      Qt.SIGNAL("activated (const QString&)"),
99                      self.colorComboBoxEdit)
100         
101         
102         # Create zoom functionality for the plots
103         self.timeZoomer = Qwt.QwtPlotZoomer(self.gui.timePlot.xBottom,
104                                             self.gui.timePlot.yLeft,
105                                             Qwt.QwtPicker.PointSelection,
106                                             Qwt.QwtPicker.AlwaysOn,
107                                             self.gui.timePlot.canvas())
108
109         self.freqZoomer = Qwt.QwtPlotZoomer(self.gui.freqPlot.xBottom,
110                                             self.gui.freqPlot.yLeft,
111                                             Qwt.QwtPicker.PointSelection,
112                                             Qwt.QwtPicker.AlwaysOn,
113                                             self.gui.freqPlot.canvas())
114
115         self.specZoomer = Qwt.QwtPlotZoomer(self.gui.specPlot.xBottom,
116                                             self.gui.specPlot.yLeft,
117                                             Qwt.QwtPicker.PointSelection,
118                                             Qwt.QwtPicker.AlwaysOn,
119                                             self.gui.specPlot.canvas())
120
121         self.picker = Qwt.QwtPlotPicker(self.gui.timePlot.xBottom,
122                                         self.gui.timePlot.yLeft,
123                                         Qwt.QwtPicker.PointSelection,
124                                         Qwt.QwtPlotPicker.CrossRubberBand,
125                                         Qwt.QwtPicker.AlwaysOn,
126                                         self.gui.timePlot.canvas())
127         self.picker.connect(self.picker,
128                             Qt.SIGNAL('selected(const QwtDoublePoint&)'),
129                             self.clickMe)
130
131         # Set up action when tab is changed
132         self.connect(self.gui.tabGroup,
133                      Qt.SIGNAL("currentChanged (int)"),
134                      self.tabChanged)
135
136         # Add a legend to the Time plot
137         legend_real = Qwt.QwtLegend()
138         self.gui.timePlot.insertLegend(legend_real)
139
140         # Set up slider
141         self.gui.plotHBar.setSingleStep(1)
142         self.gui.plotHBar.setPageStep(self.block_length)
143         self.gui.plotHBar.setMinimum(0)
144         self.gui.plotHBar.setMaximum(self.block_length)
145         self.connect(self.gui.plotHBar,
146                      Qt.SIGNAL("valueChanged(int)"),
147                      self.sliderMoved)
148
149         # Connect Open action to Open Dialog box
150         self.connect(self.gui.action_open,
151                      Qt.SIGNAL("activated()"),
152                      self.open_file)
153         
154         # Set up file position boxes to update current figure
155         self.connect(self.gui.filePosStartLineEdit,
156                      Qt.SIGNAL("editingFinished()"),
157                      self.file_position_changed)
158         self.connect(self.gui.filePosStopLineEdit,
159                      Qt.SIGNAL("editingFinished()"),
160                      self.file_position_changed)
161         self.connect(self.gui.filePosLengthLineEdit,
162                      Qt.SIGNAL("editingFinished()"),
163                      self.file_length_changed)
164
165         self.connect(self.gui.fileTimeStartLineEdit,
166                      Qt.SIGNAL("editingFinished()"),
167                      self.file_time_changed)
168         self.connect(self.gui.fileTimeStopLineEdit,
169                      Qt.SIGNAL("editingFinished()"),
170                      self.file_time_changed)
171         self.connect(self.gui.fileTimeLengthLineEdit,
172                      Qt.SIGNAL("editingFinished()"),
173                      self.file_time_length_changed)
174
175         self.rcurve = Qwt.QwtPlotCurve("Real")
176         self.icurve = Qwt.QwtPlotCurve("Imaginary")
177
178         self.icurve.attach(self.gui.timePlot)
179         self.rcurve.attach(self.gui.timePlot)
180
181         self.psdcurve = Qwt.QwtPlotCurve("PSD")
182         self.psdcurve.attach(self.gui.freqPlot)
183
184         # Set up specTab plot as a spectrogram
185         self.specdata = SpectrogramData(range(0, 10), range(0, 10))
186
187         colorMap = Qwt.QwtLinearColorMap(Qt.Qt.darkCyan, Qt.Qt.red)
188         colorMap.addColorStop(0.1, Qt.Qt.cyan)
189         colorMap.addColorStop(0.6, Qt.Qt.green)
190         colorMap.addColorStop(0.95, Qt.Qt.yellow)
191
192         self.spec = Qwt.QwtPlotSpectrogram()
193         self.spec.setColorMap(colorMap)
194         self.spec.attach(self.gui.specPlot)
195         self.spec.setContourLevels([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5])
196         self.spec.setDisplayMode(Qwt.QwtPlotSpectrogram.ImageMode, True)
197         self.spec.setData(self.specdata)
198
199         # Set up initial color scheme
200         self.color_modes["Blue on Black"]()
201
202         self.set_sample_rate(self.sample_rate)
203         self.connect(self.gui.sampleRateLineEdit,
204                      Qt.SIGNAL("editingFinished()"),
205                      self.sample_rate_changed)
206
207         if(filename is not None):
208             self.initialize(filename)
209
210         self.show()
211
212     def open_file(self):
213         filename = Qt.QFileDialog.getOpenFileName(self, "Open", ".")
214         if(filename != ""):
215             print filename
216             self.initialize(filename)
217
218     def initialize(self, filename):
219         self.hfile = open(filename, "r")
220
221         self.setWindowTitle(("GNU Radio File Plot Utility: %s" % filename))
222
223         self.gui.filePosStartLineEdit.setText("0")
224         self.gui.filePosStopLineEdit.setText("0")
225         self.gui.fileTimeStartLineEdit.setText("0")
226         self.gui.fileTimeStopLineEdit.setText("0")
227
228         self.cur_start = 0
229         self.cur_stop = self.block_length
230
231         self.init_data_input()
232         self.get_data(self.cur_start, self.cur_stop)
233         self.get_psd()
234         self.get_specgram() 
235         self.gui.plotHBar.setSliderPosition(0)
236         self.gui.plotHBar.setMaximum(self.signal_size)
237
238
239         self.update_time_curves()
240         self.update_psd_curves()
241         self.update_specgram_curves()
242
243     def init_data_input(self):
244         self.hfile.seek(0, os.SEEK_END)
245         self.signal_size = self.hfile.tell()/self.sizeof_data
246         print "Sizeof File: ", self.signal_size
247         self.hfile.seek(0, os.SEEK_SET)
248         
249     def get_data(self, start, end):
250         if(end > start):
251             self.hfile.seek(start*self.sizeof_data, os.SEEK_SET)
252             self.position = start
253             try:
254                 iq = scipy.fromfile(self.hfile, dtype=self.datatype,
255                                     count=end-start)
256
257                 if(len(iq) < (end-start)):
258                     end = len(iq)
259                     self.gui.filePosLengthLineEdit.setText(Qt.QString("%1").arg(end))
260                     self.gui.plotHBar.setMaximum(end)
261                     self.gui.plotHBar.setSingleStep(end)
262                     self.file_length_changed()
263
264                 tstep = 1.0 / self.sample_rate
265                 self.iq = iq
266                 self.time = [tstep*(self.position + i) for i in xrange(len(self.iq))]
267
268                 self.set_file_pos_box(start, end)
269             except MemoryError:
270                 pass
271         else:
272             # Do we want to do anything about this?
273             pass
274
275     def get_psd(self):
276         winpoints = self.winfunc(self.psdfftsize)
277         iq_psd, freq = mlab.psd(self.iq, Fs=self.sample_rate,
278                                 NFFT=self.psdfftsize,
279                                 noverlap=self.psdfftsize/4.0,
280                                 window=winpoints,
281                                 scale_by_freq=False)
282
283         self.iq_psd = 10.0*scipy.log10(abs(fftpack.fftshift(iq_psd)))
284         self.freq = freq - self.sample_rate/2.0
285
286     def get_specgram(self):
287         winpoints = self.winfunc(self.specfftsize)
288         iq_spec, f, t = mlab.specgram(self.iq, Fs=self.sample_rate,
289                                       NFFT=self.specfftsize,
290                                       noverlap=self.specfftsize/4.0,
291                                       window=winpoints,
292                                       scale_by_freq=False)
293         
294         self.iq_spec = 10.0*scipy.log10(abs(iq_spec))
295         self.spec_f = f
296         self.spec_t = t
297
298     def clickMe(self, qPoint):
299         print qPoint.x()
300
301     def psdFFTComboBoxEdit(self, fftSize):
302         self.psdfftsize = fftSize.toInt()[0]
303         self.get_psd()
304         self.update_psd_curves()
305
306     def specFFTComboBoxEdit(self, fftSize):
307         self.specfftsize = fftSize.toInt()[0]
308         self.get_specgram()
309         self.update_specgram_curves()
310         
311     def colorComboBoxEdit(self, colorSelection):
312         colorstr = str(colorSelection.toAscii())
313         color_func = self.color_modes[colorstr]
314         color_func()
315
316     def sliderMoved(self, value):
317         pos_start = value
318         pos_end = value + self.gui.plotHBar.pageStep()
319
320         self.get_data(pos_start, pos_end)
321         self.get_psd()
322         self.get_specgram()
323         self.update_time_curves()
324         self.update_psd_curves()
325         self.update_specgram_curves()
326
327     def set_sample_rate(self, sr):
328         self.sample_rate = sr
329         srstr = eng_notation.num_to_str(self.sample_rate)
330         self.gui.sampleRateLineEdit.setText(Qt.QString("%1").arg(srstr))
331
332     def sample_rate_changed(self):
333         srstr = self.gui.sampleRateLineEdit.text().toAscii()
334         self.sample_rate = eng_notation.str_to_num(srstr)
335         self.set_file_pos_box(self.cur_start, self.cur_stop)
336         self.get_data(self.cur_start, self.cur_stop)
337         self.get_psd()
338         self.get_specgram()
339         self.update_time_curves()
340         self.update_psd_curves()
341
342     def set_file_pos_box(self, start, end):
343         tstart = start / self.sample_rate
344         tend = end / self.sample_rate
345
346         self.gui.filePosStartLineEdit.setText(Qt.QString("%1").arg(start))
347         self.gui.filePosStopLineEdit.setText(Qt.QString("%1").arg(end))
348         self.gui.filePosLengthLineEdit.setText(Qt.QString("%1").arg(end-start))
349
350         self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
351         self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
352         self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tend-tstart))
353
354     def file_position_changed(self):
355         start  = self.gui.filePosStartLineEdit.text().toInt()
356         end    = self.gui.filePosStopLineEdit.text().toInt()
357         if((start[1] == True) and (end[1] == True)):
358             self.cur_start = start[0]
359             self.cur_stop = end[0]
360
361             tstart = self.cur_start / self.sample_rate
362             tend = self.cur_stop / self.sample_rate
363             self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
364             self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
365             
366             self.get_data(self.cur_start, self.cur_stop)
367
368             self.update_time_curves()
369             self.update_psd_curves()
370             self.update_specgram_curves()
371
372         # If there's a non-digit character, reset box
373         else:
374             self.set_file_pos_box(self.cur_start, self.cur_stop)
375
376     def file_time_changed(self):
377         tstart = self.gui.fileTimeStartLineEdit.text().toDouble()
378         tstop  = self.gui.fileTimeStopLineEdit.text().toDouble()
379         if((tstart[1] == True) and (tstop[1] == True)):
380             self.cur_start = int(tstart[0] * self.sample_rate)
381             self.cur_stop = int(tstop[0] * self.sample_rate)
382             self.get_data(self.cur_start, self.cur_stop)
383
384             self.gui.filePosStartLineEdit.setText(Qt.QString("%1").arg(self.cur_start))
385             self.gui.filePosStopLineEdit.setText(Qt.QString("%1").arg(self.cur_stop))
386
387             self.update_time_curves()
388             self.update_psd_curves()
389             self.update_specgram_curves()
390         # If there's a non-digit character, reset box
391         else:
392             self.set_file_pos_box(self.cur_start, self.cur_stop)
393
394     def file_length_changed(self):
395         start = self.gui.filePosStartLineEdit.text().toInt()
396         length = self.gui.filePosLengthLineEdit.text().toInt()
397
398         if((start[1] == True) and (length[1] == True)):
399             self.cur_start = start[0]
400             self.block_length = length[0]
401             self.cur_stop = self.cur_start + self.block_length
402
403             tstart = self.cur_start / self.sample_rate
404             tend = self.cur_stop / self.sample_rate
405             tlen = self.block_length / self.sample_rate
406             self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
407             self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
408             self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tlen))
409
410             self.gui.plotHBar.setPageStep(self.block_length)
411
412             self.get_data(self.cur_start, self.cur_stop)
413             self.get_psd()
414             self.get_specgram()
415
416             self.update_time_curves()
417             self.update_psd_curves()
418             self.update_specgram_curves()
419         # If there's a non-digit character, reset box
420         else:
421             self.set_file_pos_box(self.cur_start, self.cur_stop)
422
423     def file_time_length_changed(self):
424         tstart = self.gui.fileTimeStartLineEdit.text().toDouble()
425         tlength = self.gui.fileTimeLengthLineEdit.text().toDouble()
426         if((tstart[1] == True) and (tlength[1] == True)):
427             self.cur_start = int(tstart[0] * self.sample_rate)
428             self.block_length = int(tlength[0] * self.sample_rate)
429             self.cur_stop = self.cur_start + self.block_length
430
431             tstart = self.cur_start / self.sample_rate
432             tend = self.cur_stop / self.sample_rate
433             tlen = self.block_length / self.sample_rate
434             self.gui.fileTimeStartLineEdit.setText(Qt.QString("%1").arg(tstart))
435             self.gui.fileTimeStopLineEdit.setText(Qt.QString("%1").arg(tend))
436             self.gui.fileTimeLengthLineEdit.setText(Qt.QString("%1").arg(tlen))
437
438             self.get_data(self.cur_start, self.cur_stop)
439             self.get_psd()
440             self.get_specgram()
441
442             self.update_time_curves()
443             self.update_psd_curves()
444             self.update_specgram_curves()
445         # If there's a non-digit character, reset box
446         else:
447             self.set_file_pos_box(self.cur_start, self.cur_stop)
448
449
450     def update_time_curves(self):
451         self.icurve.setData(self.time, self.iq.imag)
452         self.rcurve.setData(self.time, self.iq.real)
453
454         # Reset the x-axis to the new time scale
455         iqmax = 1.5 * max(max(self.iq.real), max(self.iq.imag))
456         iqmin = 1.5 * min(min(self.iq.real), min(self.iq.imag))
457         self.gui.timePlot.setAxisScale(self.gui.timePlot.xBottom,
458                                        min(self.time),
459                                        max(self.time))
460         self.gui.timePlot.setAxisScale(self.gui.timePlot.yLeft,
461                                        iqmin,
462                                        iqmax)
463
464         # Set the zoomer base to unzoom to the new axis
465         self.timeZoomer.setZoomBase()
466     
467         self.gui.timePlot.replot()
468         
469     def update_psd_curves(self):
470         self.psdcurve.setData(self.freq, self.iq_psd)
471
472         self.gui.freqPlot.setAxisScale(self.gui.freqPlot.xBottom,
473                                        min(self.freq),
474                                        max(self.freq))
475                                        
476         # Set the zoomer base to unzoom to the new axis
477         self.freqZoomer.setZoomBase()
478
479         self.gui.freqPlot.replot()
480
481     def update_specgram_curves(self):
482         # We don't have to reset the data for the speccurve here
483         # since this is taken care of in the SpectrogramData class
484         self.specdata.set_data(self.spec_f, self.spec_t, self.iq_spec)
485
486         # Set the zoomer base to unzoom to the new axis
487         self.specZoomer.setZoomBase()
488
489         self.gui.specPlot.replot()
490
491     def tabChanged(self, index):
492         self.gui.timePlot.replot()
493         self.gui.freqPlot.replot()
494
495     def color_black_on_white(self):
496         blue = QtGui.qRgb(0x00, 0x00, 0xFF)
497         red = QtGui.qRgb(0xFF, 0x00, 0x00)
498
499         blackBrush = Qt.QBrush(Qt.QColor("black"))
500         blueBrush = Qt.QBrush(Qt.QColor(blue))
501         redBrush = Qt.QBrush(Qt.QColor(red))
502
503         self.gui.timePlot.setCanvasBackground(Qt.QColor("white"))
504         self.gui.freqPlot.setCanvasBackground(Qt.QColor("white"))
505         self.picker.setTrackerPen(Qt.QPen(blackBrush, 2))
506         self.timeZoomer.setTrackerPen(Qt.QPen(blackBrush, 2))
507         self.timeZoomer.setRubberBandPen(Qt.QPen(blackBrush, 2))
508         self.freqZoomer.setTrackerPen(Qt.QPen(blackBrush, 2))
509         self.freqZoomer.setRubberBandPen(Qt.QPen(blackBrush, 2))
510         self.psdcurve.setPen(Qt.QPen(blueBrush, 1))
511         self.rcurve.setPen(Qt.QPen(blueBrush, 2))
512         self.icurve.setPen(Qt.QPen(redBrush, 2))
513
514         self.gui.timePlot.replot()
515         self.gui.freqPlot.replot()
516
517     def color_white_on_black(self):
518         white = QtGui.qRgb(0xFF, 0xFF, 0xFF)
519         red = QtGui.qRgb(0xFF, 0x00, 0x00)
520
521         whiteBrush = Qt.QBrush(Qt.QColor("white"))
522         whiteBrush = Qt.QBrush(Qt.QColor(white))
523         redBrush = Qt.QBrush(Qt.QColor(red))
524         
525         self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
526         self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
527         self.picker.setTrackerPen(Qt.QPen(whiteBrush, 2))
528         self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
529         self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
530         self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
531         self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
532         self.psdcurve.setPen(Qt.QPen(whiteBrush, 1))
533         self.rcurve.setPen(Qt.QPen(whiteBrush, 2))
534         self.icurve.setPen(Qt.QPen(redBrush, 2))
535
536         self.gui.timePlot.replot()
537         self.gui.freqPlot.replot()
538
539
540     def color_green_on_black(self):
541         green = QtGui.qRgb(0x00, 0xFF, 0x00)
542         red = QtGui.qRgb(0xFF, 0x00, 0x50)
543
544         whiteBrush = Qt.QBrush(Qt.QColor("white"))
545         greenBrush = Qt.QBrush(Qt.QColor(green))
546         redBrush = Qt.QBrush(Qt.QColor(red))
547         
548         self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
549         self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
550         self.picker.setTrackerPen(Qt.QPen(whiteBrush, 2))
551         self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
552         self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
553         self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
554         self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
555         self.psdcurve.setPen(Qt.QPen(greenBrush, 1))
556         self.rcurve.setPen(Qt.QPen(greenBrush, 2))
557         self.icurve.setPen(Qt.QPen(redBrush, 2))
558
559         self.gui.timePlot.replot()
560         self.gui.freqPlot.replot()
561
562     def color_blue_on_black(self):
563         blue = QtGui.qRgb(0x00, 0x00, 0xFF)
564         red = QtGui.qRgb(0xFF, 0x00, 0x00)
565
566         whiteBrush = Qt.QBrush(Qt.QColor("white"))
567         blueBrush = Qt.QBrush(Qt.QColor(blue))
568         redBrush = Qt.QBrush(Qt.QColor(red))
569         
570         self.gui.timePlot.setCanvasBackground(QtGui.QColor("black"))
571         self.gui.freqPlot.setCanvasBackground(QtGui.QColor("black"))
572         self.picker.setTrackerPen(Qt.QPen(whiteBrush, 2))
573         self.timeZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
574         self.timeZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
575         self.freqZoomer.setTrackerPen(Qt.QPen(whiteBrush, 2))
576         self.freqZoomer.setRubberBandPen(Qt.QPen(whiteBrush, 2))
577         self.psdcurve.setPen(Qt.QPen(blueBrush, 1))
578         self.rcurve.setPen(Qt.QPen(blueBrush, 2))
579         self.icurve.setPen(Qt.QPen(redBrush, 2))
580
581         self.gui.timePlot.replot()
582         self.gui.freqPlot.replot()
583
584 def setup_options():
585     usage="%prog: [options] (input_filename)"
586     description = ""
587
588     parser = OptionParser(conflict_handler="resolve", usage=usage, description=description)
589     parser.add_option("-B", "--block-length", type="int", default=8192,
590                       help="Specify the block size [default=%default]")
591     parser.add_option("-s", "--start", type="int", default=0,
592                       help="Specify where to start in the file [default=%default]")
593     parser.add_option("-R", "--sample-rate", type="float", default=1.0,
594                       help="Set the sampler rate of the data [default=%default]")
595     parser.add_option("", "--psd-size", type="int", default=2048,
596                       help="Set the size of the PSD FFT [default=%default]")
597     parser.add_option("", "--spec-size", type="int", default=2048,
598                       help="Set the size of the spectrogram FFT [default=%default]")
599
600     return parser
601
602 def main(args):
603     parser = setup_options()
604     (options, args) = parser.parse_args ()
605
606     if(len(args) == 1):
607         filename = args[0]
608     else:
609         filename = None
610
611     app = Qt.QApplication(args)
612     gplt = gr_plot_qt(app, filename, options)
613     app.exec_()
614
615 if __name__ == '__main__':
616     main(sys.argv)
617