discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Simple display sink in wx


From: Martin Dvh
Subject: Re: [Discuss-gnuradio] Simple display sink in wx
Date: Wed, 14 Feb 2007 01:35:39 +0100
User-agent: Debian Thunderbird 1.0.2 (X11/20070113)

Achilleas Anastasopoulos wrote:
> Martin,
> 
> thanks for the block.
> Indeed it is exactly what I wanted (and even more)!!!
> 
> One question: since a throttle is not attached to this block,
> why do we need separate sample_rate and number_rate parameters?
> The only place I saw them used is
> 
> one_in_n = gr.keep_one_in_n(gr.sizeof_float,
>                     max(1, int(sample_rate/number_rate)))
> 
> which implies that only the ratio of sample_rate/number_rate
> is important. Unless number_rate actually controls the
> real rate at which numbers are displayed (which I cannot figure out how)...
The number_rate limits the outputting of numbers to the screen.
If this would get more then around 50 numbers/sec this will use up all display 
resources and your gui will freeze.
(xfree can't display more numbers/sec then your monitors refreshrate anyway)

This is the same effect you get when using the fftsink with a too high fft_rate.

Martin
> 
> Thanks
> Achilleas
> 
> 
> Martin Dvh wrote:
> 
>> Achilleas Anastasopoulos wrote:
>>
>>> Hi,
>>>
>>> it would be very useful to have a
>>> wx sink that displays the value of its input.
>>> This way we can check in real time values
>>> that change slowly (eg, snr, bit error rate, etc.)
>>
>>
>> Your widh is my command:
>> Attached is a patch which adds a number_sink_f and number_sink_c to
>> gr-wxgui.
>> You must apply it in the root of your gnuradio tree.
>> patch -p0 <numbersink.patch
>>
>> You can also find it in gr-wxgui in my work-in-progress development
>> tree in svn:
>> gnuradio/branches/developers/nldudok1/general-wip
>>
>> You use it in the following way:
>>
>> from gnuradio.wxgui import numbersink
>>
>>    numsink = numbersink.number_sink_f (self, panel,
>> unit='volts',label="input level", avg_alpha=1.0e-5,average=True,
>>                           sample_rate=input_rate/sw_decim,
>> factor=1.0,base_value=0,
>>                           minval=-100.0, maxval=100.0,
>>                           ref_level=0, decimal_places=5,number_rate=15)
>>    vbox.Add (numsink.win, 1, wx.EXPAND)
>>    self.connect(some_float_source,numsink)
>>
>> You can set several options by right-mouse-click.
>> (Show gauge, number of digits, avaraging)
>> You use it just like an oscope or fft sink.
>>
>> the parameters:
>> fg        flowgraph, the flowgraph (use self if you work with a
>> stdgui.gui_flow_graph)
>> parent      wxguipanel, The wxgui parent (use panel if you work with a
>> stdgui.gui_flow_graph)
>> unit        string, the unit you want to display, for example 'volt'
>> or 'Watt', free text.
>> base_value    float, an offset which is added to the value
>> minval        float, min value for the gauge
>> maxval        float, max value for the gauge
>> factor        float, scaling factor, value is multiplied by this (sort
>> of gain)
>> decimal_places    int, the number of decimal places shown
>> ref_level    ignored (API compatibility with scope and fft-sink)
>> sample_rate    float, samplerate of input
>> number_rate    float or int, rate at which values are displayed
>> (framerate, default is 15)
>> average        bool, use averaging or not
>> avg_alpha    float, average alpha, determines the speed of averaging
>> label        string, the label which goes with this value (for example
>> 'frequency' or 'input power')
>> size        default=(640,240), the graphical size of this numbersink
>> peak_hold    bool, hold at peak or not.
>>
>>
>>> Unfortunately there is no how_to_write_a_wx_block
>>> so I have no idea how to go about it.
>>>
>>> If someone can help me by providing a stripped down
>>> version of one of the wx sinks (*eg, the oscope, or fft)
>>> then I can take a crack at it.
>>> Even better if one can implement this :-)
>>
>>
>> I hope you like it.
>>
>> Eric, is this maybe something for trunk.
>> I don't know if the code is clean enough.
>>
>> Greetings,
>> Martin
>>
>>> Thanks,
>>> Achilleas
>>>
>>>
>>> _______________________________________________
>>> Discuss-gnuradio mailing list
>>> address@hidden
>>> http://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>>>
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> Index: gr-wxgui/src/python/numbersink.py
>> ===================================================================
>> --- gr-wxgui/src/python/numbersink.py    (revision 0)
>> +++ gr-wxgui/src/python/numbersink.py    (revision 0)
>> @@ -0,0 +1,614 @@
>> +#!/usr/bin/env python
>> +#
>> +# Copyright 2003,2004,2005,2006 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 2, 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., 59 Temple Place - Suite 330,
>> +# Boston, MA 02111-1307, USA.
>> +# +
>> +from gnuradio import gr, gru, window
>> +from gnuradio.wxgui import stdgui
>> +import wx
>> +#from wx import StaticText
>> +import gnuradio.wxgui.plot as plot
>> +import Numeric
>> +import threading
>> +import math    +
>> +default_numbersink_size = (640,240)
>> +default_number_rate = gr.prefs().get_long('wxgui', 'number_rate', 15)
>> +
>> +class number_sink_base(object):
>> +    def __init__(self, input_is_real=False, unit='',base_value=0,
>> minval=-100.0,maxval=100.0,factor=1.0,decimal_places=10, ref_level=50,
>> +                 sample_rate=1, +                
>> number_rate=default_number_rate,
>> +                 average=False, avg_alpha=None, label='',
>> peak_hold=False):
>> +
>> +        # initialize common attributes
>> +        self.unit=unit
>> +        self.base_value = base_value
>> +        self.minval=minval
>> +        self.maxval=maxval
>> +        self.factor=factor
>> +        self.y_divs = 8
>> +        self.decimal_places=decimal_places
>> +        self.ref_level = ref_level
>> +        self.sample_rate = sample_rate
>> +        number_size=1
>> +        self.number_size = number_size
>> +        self.number_rate = number_rate
>> +        self.average = average
>> +        if avg_alpha is None:
>> +            self.avg_alpha = 2.0 / number_rate
>> +        else:
>> +            self.avg_alpha = avg_alpha
>> +        self.label = label
>> +        self.peak_hold = peak_hold
>> +        self.show_gauge = True
>> +        self.input_is_real = input_is_real
>> +        self.msgq = gr.msg_queue(2)         # queue that holds a
>> maximum of 2 messages
>> +
>> +    def set_decimal_places(self, decimal_places):
>> +        self.decimal_places = decimal_places
>> +
>> +    def set_ref_level(self, ref_level):
>> +        self.ref_level = ref_level
>> +
>> +    def print_current_value(self, comment):
>> +        print comment,self.win.current_value
>> +
>> +    def set_average(self, average):
>> +        self.average = average
>> +        if average:
>> +            self.avg.set_taps(self.avg_alpha)
>> +            self.set_peak_hold(False)
>> +        else:
>> +            self.avg.set_taps(1.0)
>> +
>> +    def set_peak_hold(self, enable):
>> +        self.peak_hold = enable
>> +        if enable:
>> +            self.set_average(False)
>> +        self.win.set_peak_hold(enable)
>> +
>> +    def set_show_gauge(self, enable):
>> +        self.show_gauge = enable
>> +        self.win.set_show_gauge(enable)
>> +
>> +    def set_avg_alpha(self, avg_alpha):
>> +        self.avg_alpha = avg_alpha
>> +
>> +    def set_base_value(self, base_value):
>> +        self.base_value = base_value
>> +        +
>> +class number_sink_f(gr.hier_block, number_sink_base):
>> +    def __init__(self, fg, parent,
>> unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0,
>> +                 decimal_places=10, ref_level=50, sample_rate=1,
>> #number_size=512,
>> +                 number_rate=default_number_rate, average=False,
>> avg_alpha=None,
>> +                 label='', size=default_numbersink_size,
>> peak_hold=False):
>> +
>> +        number_sink_base.__init__(self, unit=unit,
>> input_is_real=True, base_value=base_value,
>> +                              
>> minval=minval,maxval=maxval,factor=factor,
>> +                               decimal_places=decimal_places,
>> ref_level=ref_level,
>> +                               sample_rate=sample_rate,
>> #number_size=number_size,
>> +                               number_rate=number_rate,
>> +                               average=average, avg_alpha=avg_alpha,
>> label=label,
>> +                               peak_hold=peak_hold)
>> +         +        number_size=1                      +        #s2p =
>> gr.stream_to_vector(gr.sizeof_float, number_size)
>> +        one_in_n = gr.keep_one_in_n(gr.sizeof_float,
>> +                                    max(1,
>> int(sample_rate/number_rate)))
>> +
>> +            +        #c2mag = gr.complex_to_mag(number_size)
>> +        self.avg = gr.single_pole_iir_filter_ff(1.0, number_size)
>> +
>> +        # FIXME  We need to add 3dB to all bins but the DC bin
>> +        #log = gr.nlog10_ff(20, number_size,
>> +        #                  
>> -20*math.log10(number_size)-10*math.log10(power/number_size))
>> +        sink = gr.message_sink(gr.sizeof_float , self.msgq, True)
>> +
>> +        #fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink)
>> +        fg.connect(self.avg,one_in_n,sink)
>> +        gr.hier_block.__init__(self, fg, self.avg, sink)
>> +        self.win = number_window(self, parent, size=size,label=label)
>> +        self.set_average(self.average)
>> +
>> +
>> +class number_sink_c(gr.hier_block, number_sink_base):
>> +    def __init__(self, fg, parent,
>> unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0,
>> +                 decimal_places=10, ref_level=50, sample_rate=1,
>> #number_size=512,
>> +                 number_rate=default_number_rate, average=False,
>> avg_alpha=None,
>> +                 label='', size=default_numbersink_size,
>> peak_hold=False):
>> +
>> +        number_sink_base.__init__(self, unit=unit,
>> input_is_real=False, base_value=base_value,factor=factor,
>> +                              
>> minval=minval,maxval=maxval,decimal_places=decimal_places,
>> ref_level=ref_level,
>> +                               sample_rate=sample_rate,
>> #number_size=number_size,
>> +                               number_rate=number_rate,
>> +                               average=average, avg_alpha=avg_alpha,
>> label=label,
>> +                               peak_hold=peak_hold)
>> +
>> +        number_size=1                      +        one_in_n =
>> gr.keep_one_in_n(gr.sizeof_gr_complex,
>> +                                    max(1,
>> int(sample_rate/number_rate)))
>> +
>> +            +        #c2mag = gr.complex_to_mag(number_size)
>> +        self.avg = gr.single_pole_iir_filter_cc(1.0, number_size)
>> +
>> +        # FIXME  We need to add 3dB to all bins but the DC bin
>> +        #log = gr.nlog10_ff(20, number_size,
>> +        #                  
>> -20*math.log10(number_size)-10*math.log10(power/number_size))
>> +        sink = gr.message_sink(gr.sizeof_gr_complex , self.msgq, True)
>> +
>> +        #fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink)
>> +        fg.connect(self.avg,one_in_n,sink)
>> +        gr.hier_block.__init__(self, fg, self.avg, sink)
>> +        self.win = number_window(self, parent, size=size,label=label)
>> +        self.set_average(self.average)
>> +
>> +
>> +#
>> ------------------------------------------------------------------------
>> +
>> +myDATA_EVENT = wx.NewEventType()
>> +EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
>> +
>> +
>> +class DataEvent(wx.PyEvent):
>> +    def __init__(self, data):
>> +        wx.PyEvent.__init__(self)
>> +        self.SetEventType (myDATA_EVENT)
>> +        self.data = data
>> +
>> +    def Clone (self): +        self.__class__ (self.GetId())
>> +
>> +
>> +class input_watcher (threading.Thread):
>> +    def __init__ (self, msgq, number_size, event_receiver, **kwds):
>> +        threading.Thread.__init__ (self, **kwds)
>> +        self.setDaemon (1)
>> +        self.msgq = msgq
>> +        self.number_size = number_size
>> +        self.event_receiver = event_receiver
>> +        self.keep_running = True
>> +        self.start ()
>> +
>> +    def run (self):
>> +        while (self.keep_running):
>> +            msg = self.msgq.delete_head()  # blocking read of message
>> queue
>> +            itemsize = int(msg.arg1())
>> +            nitems = int(msg.arg2())
>> +
>> +            s = msg.to_string()            # get the body of the msg
>> as a string
>> +
>> +            # There may be more than one number in the message.
>> +            # If so, we take only the last one
>> +            if nitems > 1:
>> +                start = itemsize * (nitems - 1)
>> +                s = s[start:start+itemsize]
>> +
>> +            complex_data = Numeric.fromstring (s, Numeric.Float32)
>> +            de = DataEvent (complex_data)
>> +            wx.PostEvent (self.event_receiver, de)
>> +            del de
>> +   
>> +#========================================================================================
>>
>> +class static_text_window (wx.StaticText): #plot.PlotCanvas):
>> +    def __init__ (self, parent, numbersink,id = -1,label="number",
>> +                  pos = wx.DefaultPosition, size = wx.DefaultSize,
>> +                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
>> +        #plot.PlotCanvas.__init__ (self, parent, id, pos, size,
>> style, name)
>> +        wx.StaticText.__init__(self, parent, id, label, pos, size,
>> style, name)
>> +        #self.static_text=wx.StaticText( parent, id, label, pos,
>> (size[0]/2,size[1]/2), style, name)
>> +        #gauge_style = wx.GA_HORIZONTAL
>> +        #self.gauge=wx.Gauge( parent, id, range=1000,
>> pos=(pos[0],pos[1]+size[1]/2),size=(size[0]/2,size[1]/2),
>> style=gauge_style,  name = "gauge")
>> +        #wx.BoxSizer.__init__ (self,wx.VERTICAL)
>> +        #self.Add (self.static_text, 0, wx.EXPAND)
>> +        #self.Add (self.gauge, 1, wx.EXPAND)
>> +        self.parent=parent
>> +        self.label=label
>> +        #self.y_range = None
>> +        self.numbersink = numbersink
>> +        self.peak_hold = False
>> +        self.peak_vals = None
>> +
>> +        #self.SetEnableGrid (True)
>> +        # self.SetEnableZoom (True)
>> +        # self.SetBackgroundColour ('black')
>> +        +        self.build_popup_menu()
>> +        +        #EVT_DATA_EVENT (self, self.set_data)
>> +        #wx.EVT_CLOSE (self, self.on_close_window)
>> +        #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
>> +        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
>> +
>> +        #self.input_watcher = input_watcher(numbersink.msgq,
>> numbersink.number_size, self)
>> +
>> +
>> +    def on_close_window (self, event):
>> +        print "number_window:on_close_window"
>> +        self.keep_running = False
>> +
>> +
>> +    def set_peak_hold(self, enable):
>> +        self.peak_hold = enable
>> +        self.peak_vals = None
>> +
>> +    def update_y_range (self):
>> +        ymax = self.numbersink.ref_level
>> +        ymin = self.numbersink.ref_level -
>> self.numbersink.decimal_places * self.numbersink.y_divs
>> +        self.y_range = self._axisInterval ('min', ymin, ymax)
>> +
>> +    def on_average(self, evt):
>> +        # print "on_average"
>> +        self.numbersink.set_average(evt.IsChecked())
>> +
>> +    def on_peak_hold(self, evt):
>> +        # print "on_peak_hold"
>> +        self.numbersink.set_peak_hold(evt.IsChecked())
>> +
>> +    def on_show_gauge(self, evt):
>> +        # print "on_show_gauge"
>> +        #if evt.IsChecked():
>> +        self.numbersink.set_show_gauge(evt.IsChecked())
>> +        print evt.IsChecked()
>> +        #  print "show gauge"
>> +        #else:
>> +        #  self.parent.gauge.Hide()
>> +        #  print "hide gauge"
>> +
>> +    def on_incr_ref_level(self, evt):
>> +        # print "on_incr_ref_level"
>> +        self.numbersink.set_ref_level(self.numbersink.ref_level
>> +                                   + self.numbersink.decimal_places)
>> +
>> +    def on_decr_ref_level(self, evt):
>> +        # print "on_decr_ref_level"
>> +        self.numbersink.set_ref_level(self.numbersink.ref_level
>> +                                   - self.numbersink.decimal_places)
>> +
>> +    def on_incr_decimal_places(self, evt):
>> +        # print "on_incr_decimal_places"
>> +       
>> self.numbersink.set_decimal_places(self.numbersink.decimal_places+1)
>> #next_up(self.numbersink.decimal_places, (1,2,5,10,20)))
>> +
>> +    def on_decr_decimal_places(self, evt):
>> +        # print "on_decr_decimal_places"
>> +       
>> self.numbersink.set_decimal_places(max(self.numbersink.decimal_places-1,0))
>> #next_down(self.numbersink.decimal_places, (1,2,5,10,20)))
>> +
>> +    def on_decimal_places(self, evt):
>> +        # print "on_decimal_places"
>> +        Id = evt.GetId()
>> +        if Id == self.id_decimal_places_0:
>> +            self.numbersink.set_decimal_places(0)
>> +        elif Id == self.id_decimal_places_1:
>> +            self.numbersink.set_decimal_places(1)
>> +        elif Id == self.id_decimal_places_2:
>> +            self.numbersink.set_decimal_places(2)
>> +        elif Id == self.id_decimal_places_3:
>> +            self.numbersink.set_decimal_places(3)
>> +        elif Id == self.id_decimal_places_6:
>> +            self.numbersink.set_decimal_places(6)
>> +        elif Id == self.id_decimal_places_9:
>> +            self.numbersink.set_decimal_places(9)
>> +
>> +        +    def on_right_click(self, event):
>> +        menu = self.popup_menu
>> +        for id, pred in self.checkmarks.items():
>> +            item = menu.FindItemById(id)
>> +            item.Check(pred())
>> +        self.PopupMenu(menu, event.GetPosition())
>> +
>> +
>> +    def build_popup_menu(self):
>> +        #self.id_hide_gauge = wx.NewId()
>> +        self.id_show_gauge = wx.NewId()
>> +        self.id_incr_ref_level = wx.NewId()
>> +        self.id_decr_ref_level = wx.NewId()
>> +        self.id_incr_decimal_places = wx.NewId()
>> +        self.id_decr_decimal_places = wx.NewId()
>> +        self.id_decimal_places_0 = wx.NewId()
>> +        self.id_decimal_places_1 = wx.NewId()
>> +        self.id_decimal_places_2 = wx.NewId()
>> +        self.id_decimal_places_3 = wx.NewId()
>> +        self.id_decimal_places_6 = wx.NewId()
>> +        self.id_decimal_places_9 = wx.NewId()
>> +        self.id_average = wx.NewId()
>> +        self.id_peak_hold = wx.NewId()
>> +
>> +        self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
>> +        self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)
>> +        #self.Bind(wx.EVT_MENU, self.on_hide_gauge,
>> id=self.id_hide_gauge)
>> +        self.Bind(wx.EVT_MENU, self.on_show_gauge,
>> id=self.id_show_gauge)
>> +        self.Bind(wx.EVT_MENU, self.on_incr_ref_level,
>> id=self.id_incr_ref_level)
>> +        self.Bind(wx.EVT_MENU, self.on_decr_ref_level,
>> id=self.id_decr_ref_level)
>> +        self.Bind(wx.EVT_MENU, self.on_incr_decimal_places,
>> id=self.id_incr_decimal_places)
>> +        self.Bind(wx.EVT_MENU, self.on_decr_decimal_places,
>> id=self.id_decr_decimal_places)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_0)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_1)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_2)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_3)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_6)
>> +        self.Bind(wx.EVT_MENU, self.on_decimal_places,
>> id=self.id_decimal_places_9)
>> +
>> +
>> +        # make a menu
>> +        menu = wx.Menu()
>> +        self.popup_menu = menu
>> +        menu.AppendCheckItem(self.id_average, "Average")
>> +        menu.AppendCheckItem(self.id_peak_hold, "Peak Hold")
>> +        #menu.Append(self.id_hide_gauge, "Hide gauge")
>> +        menu.AppendCheckItem(self.id_show_gauge, "Show gauge")
>> +        menu.Append(self.id_incr_ref_level, "Incr Ref Level")
>> +        menu.Append(self.id_decr_ref_level, "Decr Ref Level")
>> +        menu.Append(self.id_incr_decimal_places, "Incr decimal places")
>> +        menu.Append(self.id_decr_decimal_places, "Decr decimal places")
>> +        menu.AppendSeparator()
>> +        # we'd use RadioItems for these, but they're not supported on
>> Mac
>> +        menu.AppendCheckItem(self.id_decimal_places_0, "0 decimal
>> places")
>> +        menu.AppendCheckItem(self.id_decimal_places_1, "1 decimal
>> places")
>> +        menu.AppendCheckItem(self.id_decimal_places_2, "2 decimal
>> places")
>> +        menu.AppendCheckItem(self.id_decimal_places_3, "3 decimal
>> places")
>> +        menu.AppendCheckItem(self.id_decimal_places_6, "6 decimal
>> places")
>> +        menu.AppendCheckItem(self.id_decimal_places_9, "9 decimal
>> places")
>> +
>> +        self.checkmarks = {
>> +            self.id_average : lambda : self.numbersink.average,
>> +            self.id_peak_hold : lambda :
>> self.numbersink.peak_hold,#            self.id_hide_gauge : lambda :
>> self.numbersink.hide_gauge,
>> +            self.id_show_gauge : lambda : self.numbersink.show_gauge,
>> +            self.id_decimal_places_0 : lambda :
>> self.numbersink.decimal_places == 0,
>> +            self.id_decimal_places_1 : lambda :
>> self.numbersink.decimal_places == 1,
>> +            self.id_decimal_places_2 : lambda :
>> self.numbersink.decimal_places == 2,
>> +            self.id_decimal_places_3 : lambda :
>> self.numbersink.decimal_places == 3,
>> +            self.id_decimal_places_6 : lambda :
>> self.numbersink.decimal_places == 6,
>> +            self.id_decimal_places_9 : lambda :
>> self.numbersink.decimal_places == 9,
>> +            }
>> +
>> +
>> +def next_up(v, seq):
>> +    """
>> +    Return the first item in seq that is > v.
>> +    """
>> +    for s in seq:
>> +        if s > v:
>> +            return s
>> +    return v
>> +
>> +def next_down(v, seq):
>> +    """
>> +    Return the last item in seq that is < v.
>> +    """
>> +    rseq = list(seq[:])
>> +    rseq.reverse()
>> +
>> +    for s in rseq:
>> +        if s < v:
>> +            return s
>> +    return v
>> +
>> +
>> +#========================================================================================
>>
>> +class number_window (plot.PlotCanvas):
>> +    def __init__ (self, numbersink, parent, id = -1,label="number",
>> +                  pos = wx.DefaultPosition, size = wx.DefaultSize,
>> +                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
>> +        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style,
>> name)
>> +        #wx.StaticText.__init__(self, parent, id, label, pos,
>> (size[0]/2,size[1]/2), style, name)
>> +        #print 'parent',parent
>> +        self.static_text=static_text_window( self, numbersink,id,
>> label, pos, (size[0]/2,size[1]/2), style, name)
>> +        gauge_style = wx.GA_HORIZONTAL
>> +        vbox=wx.BoxSizer(wx.VERTICAL)
>> +        vbox.Add (self.static_text, 0, wx.EXPAND)
>> +        self.current_value=None
>> +        if numbersink.input_is_real:
>> +          self.gauge=wx.Gauge( self, id, range=1000,
>> pos=(pos[0],pos[1]+size[1]/2),size=(size[0]/2,size[1]/2),
>> style=gauge_style,  name = "gauge")
>> +          vbox.Add (self.gauge, 1, wx.EXPAND)
>> +        else:
>> +          self.gauge=wx.Gauge( self, id, range=1000,
>> pos=(pos[0],pos[1]+size[1]/3),size=(size[0]/2,size[1]/3),
>> style=gauge_style,  name = "gauge")
>> +          #hbox=wx.BoxSizer(wx.HORIZONTAL)
>> +          self.gauge_imag=wx.Gauge( self, id, range=1000,
>> pos=(pos[0],pos[1]+size[1]*2/3),size=(size[0]/2,size[1]/3),
>> style=gauge_style,  name = "gauge_imag")
>> +          vbox.Add (self.gauge, 1, wx.EXPAND)
>> +          vbox.Add (self.gauge_imag, 1, wx.EXPAND)
>> +          #vbox.Add (hbox, 1, wx.EXPAND)
>> +        self.sizer = vbox
>> +        self.SetSizer (self.sizer)
>> +        self.SetAutoLayout (True)
>> +        self.sizer.Fit (self)
>> +
>> +        self.label=label
>> +        #self.y_range = None
>> +        self.numbersink = numbersink
>> +        self.peak_hold = False
>> +        self.peak_vals = None
>> +
>> +        #self.SetEnableGrid (True)
>> +        # self.SetEnableZoom (True)
>> +        # self.SetBackgroundColour ('black')
>> +        +        #self.build_popup_menu()
>> +        +        EVT_DATA_EVENT (self, self.set_data)
>> +        wx.EVT_CLOSE (self, self.on_close_window)
>> +        #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
>> +        #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
>> +
>> +        self.input_watcher = input_watcher(numbersink.msgq,
>> numbersink.number_size, self)
>> +
>> +
>> +    def on_close_window (self, event):
>> +        print "number_window:on_close_window"
>> +        self.keep_running = False
>> +
>> +    def set_show_gauge(self, enable):
>> +        self.show_gauge = enable
>> +        if enable:
>> +          self.gauge.Show()
>> +          if not self.numbersink.input_is_real:
>> +            self.gauge_imag.Show()
>> +          #print 'show'
>> +        else:
>> +          self.gauge.Hide()
>> +          if not self.numbersink.input_is_real:
>> +            self.gauge_imag.Hide()
>> +          #print 'hide'
>> +
>> +    def set_data (self, evt):
>> +        numbers = evt.data
>> +        L = len (numbers)
>> +
>> +        if self.peak_hold:
>> +            if self.peak_vals is None:
>> +                self.peak_vals = numbers
>> +            else:
>> +                self.peak_vals = Numeric.maximum(numbers,
>> self.peak_vals)
>> +                numbers = self.peak_vals
>> +
>> +        if self.numbersink.input_is_real:
>> +            real_value=numbers[0]*self.numbersink.factor +
>> self.numbersink.base_value
>> +            imag_value=0.0
>> +            self.current_value=real_value
>> +        else:
>> +            real_value=numbers[0]*self.numbersink.factor +
>> self.numbersink.base_value
>> +            imag_value=numbers[1]*self.numbersink.factor +
>> self.numbersink.base_value
>> +            self.current_value=complex(real_value,imag_value)
>> +        #x = max(abs(self.numbersink.sample_rate),
>> abs(self.numbersink.base_value))
>> +        x = max(real_value, imag_value)
>> +        if x >= 1e9:
>> +            sf = 1e-9
>> +            unit_prefix = "G"
>> +        elif x >= 1e6:
>> +            sf = 1e-6
>> +            unit_prefix = "M"
>> +        elif x>= 1e3:
>> +            sf = 1e-3
>> +            unit_prefix = "k"
>> +        else :
>> +            sf = 1
>> +            unit_prefix = ""
>> +        #self.update_y_range ()
>> +        if self.numbersink.input_is_real:
>> +          showtext = "%s: %.*f %s%s" % (self.label,
>> self.numbersink.decimal_places,real_value*sf,unit_prefix,self.numbersink.unit)
>>
>> +        else:
>> +          showtext = "%s: %.*f,%.*f %s%s" % (self.label,
>> self.numbersink.decimal_places,real_value*sf,
>> +                                                      
>> self.numbersink.decimal_places,imag_value*sf,unit_prefix,self.numbersink.unit)
>>
>> +        self.static_text.SetLabel(showtext)
>> +        #print
>> (int(float((real_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500)
>>
>> +       
>> self.gauge.SetValue(int(float((real_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500)
>>
>> +        if not self.numbersink.input_is_real:
>> +         
>> self.gauge.SetValue(int(float((imag_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500)
>>
>> +
>> +    def set_peak_hold(self, enable):
>> +        self.peak_hold = enable
>> +        self.peak_vals = None
>> +
>> +    def update_y_range (self):
>> +        ymax = self.numbersink.ref_level
>> +        ymin = self.numbersink.ref_level -
>> self.numbersink.decimal_places * self.numbersink.y_divs
>> +        self.y_range = self._axisInterval ('min', ymin, ymax)
>> +
>> +    def on_average(self, evt):
>> +        # print "on_average"
>> +        self.numbersink.set_average(evt.IsChecked())
>> +
>> +    def on_peak_hold(self, evt):
>> +        # print "on_peak_hold"
>> +        self.numbersink.set_peak_hold(evt.IsChecked())
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +# ----------------------------------------------------------------
>> +#                    Deprecated interfaces
>> +# ----------------------------------------------------------------
>> +
>> +# returns (block, win).
>> +#   block requires a single input stream of float
>> +#   win is a subclass of wxWindow
>> +
>> +def make_number_sink_f(fg, parent, label, number_size, input_rate,
>> ymin = 0, ymax=50):
>> +    +    block = number_sink_f(fg, parent, label=label,
>> number_size=number_size, sample_rate=input_rate,
>> +                       decimal_places=(ymax - ymin)/8, ref_level=ymax)
>> +    return (block, block.win)
>> +
>> +# returns (block, win).
>> +#   block requires a single input stream of gr_complex
>> +#   win is a subclass of wxWindow
>> +
>> +def make_number_sink_c(fg, parent, label, number_size, input_rate,
>> ymin=0, ymax=50):
>> +    block = number_sink_c(fg, parent, label=label,
>> number_size=number_size, sample_rate=input_rate,
>> +                       decimal_places=(ymax - ymin)/8, ref_level=ymax)
>> +    return (block, block.win)
>> +
>> +
>> +# ----------------------------------------------------------------
>> +# Standalone test app
>> +# ----------------------------------------------------------------
>> +
>> +class test_app_flow_graph (stdgui.gui_flow_graph):
>> +    def __init__(self, frame, panel, vbox, argv):
>> +        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
>> +
>> +        #number_size = 256
>> +
>> +        # build our flow graph
>> +        input_rate = 20.48e3
>> +
>> +        # Generate a complex sinusoid
>> +        src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
>> +        #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE,
>> 5.75e3, 1)
>> +
>> +        # We add these throttle blocks so that this demo doesn't
>> +        # suck down all the CPU available.  Normally you wouldn't use
>> these.
>> +        thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
>> +
>> +        #sink1 = number_sink_c (self, panel, label="Complex Data",
>> number_size=number_size,
>> +        #                    sample_rate=input_rate, base_value=100e3,
>> +        #                    ref_level=0, decimal_places=3)
>> +        #vbox.Add (sink1.win, 1, wx.EXPAND)
>> +        #self.connect (src1, thr1, sink1)
>> +
>> +        src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
>> +        #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE,
>> 5.75e3, 1)
>> +        thr2 = gr.throttle(gr.sizeof_float, input_rate)
>> +        sink2 = number_sink_f (self, panel, unit='Hz',label="Real
>> Data", avg_alpha=0.001,#number_size=number_size*2,
>> +                            sample_rate=input_rate, base_value=100e3,
>> +                            ref_level=0, decimal_places=3)
>> +        vbox.Add (sink2.win, 1, wx.EXPAND)
>> +        sink3 = number_sink_c (self, panel, unit='V',label="Complex
>> Data", avg_alpha=0.001,#number_size=number_size*2,
>> +                            sample_rate=input_rate, base_value=0,
>> +                            ref_level=0, decimal_places=3)
>> +        vbox.Add (sink3.win, 1, wx.EXPAND)
>> +        self.connect (src2, thr2, sink2)
>> +        self.connect (src1, thr1, sink3)
>> +def main ():
>> +    app = stdgui.stdapp (test_app_flow_graph,
>> +                         "Number Sink Test App")
>> +    app.MainLoop ()
>> +
>> +if __name__ == '__main__':
>> +    main ()
>>
>> Property changes on: gr-wxgui/src/python/numbersink.py
>> ___________________________________________________________________
>> Name: svn:executable
>>    + *
>>
>> Index: gr-wxgui/src/python/Makefile.am
>> ===================================================================
>> --- gr-wxgui/src/python/Makefile.am    (revision 4343)
>> +++ gr-wxgui/src/python/Makefile.am    (working copy)
>> @@ -37,4 +37,5 @@
>>      scopesink.py            \
>>      waterfallsink.py        \
>>      slider.py            \
>> -    stdgui.py           
>> +    stdgui.py            \
>> +    numbersink.py       
> 
> 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]