Merge commit '25a8' from git@gnuradio.org:jblum
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 15 Oct 2009 19:02:04 +0000 (12:02 -0700)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 15 Oct 2009 19:02:04 +0000 (12:02 -0700)
* commit '25a8':
  use clean numbers for waterfall ref and range
  tweaks to scope autoscaling
  registered key to hide/show control panel in wxgui windows
  Added window size param to all wxgui wrappers.
  add canonical options for copy enable param

15 files changed:
gr-wxgui/src/python/common.py
gr-wxgui/src/python/const_window.py
gr-wxgui/src/python/constants.py
gr-wxgui/src/python/fft_window.py
gr-wxgui/src/python/histo_window.py
gr-wxgui/src/python/number_window.py
gr-wxgui/src/python/scope_window.py
gr-wxgui/src/python/waterfall_window.py
grc/blocks/wxgui_constellationsink2.xml
grc/blocks/wxgui_fftsink2.xml
grc/blocks/wxgui_histosink2.xml
grc/blocks/wxgui_numbersink2.xml
grc/blocks/wxgui_scopesink2.xml
grc/blocks/wxgui_waterfallsink2.xml
grc/python/Param.py

index a75f6810d8ce0732a7d9984ba8076ffd5566edd9..17a7dc0de550fa8ae5fa32da1f938d3f5fd7edd8 100644 (file)
@@ -216,12 +216,13 @@ def get_min_max(samples):
        @param samples the array of real values
        @return a tuple of min, max
        """
-       scale_factor = 3
+       factor = 2.0
        mean = numpy.average(samples)
-       rms = numpy.max([scale_factor*((numpy.sum((samples-mean)**2)/len(samples))**.5), .1])
-       min_val = mean - rms
-       max_val = mean + rms
-       return min_val, max_val
+       std = numpy.std(samples)
+       fft = numpy.abs(numpy.fft.fft(samples - mean))
+       envelope = 2*numpy.max(fft)/len(samples)
+       ampl = max(std, envelope) or 0.1
+       return mean - factor*ampl, mean + factor*ampl
 
 def get_min_max_fft(fft_samps):
        """
index b128a4a989a181291226b354992da2523c63b47e..f7c7caf07691be5e80be1fa1279277b35b4a1e82 100644 (file)
@@ -64,6 +64,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = forms.static_box_sizer(
                        parent=self, label='Options',
                        bold=True, orient=wx.VERTICAL,
index 8ff7fa8fee848f44870a23481375270133b179c3..825f71c3223369ac43ee263685a4bc38c84702a6 100644 (file)
@@ -69,3 +69,4 @@ MINIMUM_KEY = 'minimum'
 NUM_BINS_KEY = 'num_bins'
 FRAME_SIZE_KEY = 'frame_size'
 CHANNEL_OPTIONS_KEY = 'channel_options'
+SHOW_CONTROL_PANEL_KEY = 'show_control_panel'
index e025c28dd71872679776064878c26be1970a03e7..4ee5520f76167271af35a699266fd20521e9e6c3 100644 (file)
@@ -64,6 +64,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                control_box.AddStretchSpacer()
                #checkboxes for average and peak hold
index 5f434d70ee79064dbe952882c0c6055d1bccdc06..a1b520f9c121acbc3d9e7498c2b4c0fbcfd7c445 100644 (file)
@@ -52,6 +52,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                SIZE = (100, -1)
                control_box = forms.static_box_sizer(
index 8a8249764c03e94acdb573b6cbbeed42aaeff3dd..ab9d1ebc004e064f6ec66de9641b408a60244546 100644 (file)
@@ -58,6 +58,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                #checkboxes for average and peak hold
                control_box.AddStretchSpacer()
index 449046402ca2a08c486e4fe3f165b91ebc0454c9..9346a73d88c6401841a0cb2f555b0b7376ec23f2 100644 (file)
@@ -82,6 +82,8 @@ class control_panel(wx.Panel):
                WIDTH = 90
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                ##################################################
                # Axes Options
index 28e67a83006aa6af3123107fe4d3f79db06062d6..b7904e4d9742412269345dd870c8bb6657c9f89f 100644 (file)
@@ -41,6 +41,7 @@ DEFAULT_FRAME_RATE = gr.prefs().get_long('wxgui', 'waterfall_rate', 30)
 DEFAULT_WIN_SIZE = (600, 300)
 DIV_LEVELS = (1, 2, 5, 10, 20)
 MIN_DYNAMIC_RANGE, MAX_DYNAMIC_RANGE = 10, 200
+DYNAMIC_RANGE_STEP = 10.
 COLOR_MODES = (
        ('RGB1', 'rgb1'),
        ('RGB2', 'rgb2'),
@@ -63,6 +64,8 @@ class control_panel(wx.Panel):
                """
                self.parent = parent
                wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
+               parent[SHOW_CONTROL_PANEL_KEY] = True
+               parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
                control_box = wx.BoxSizer(wx.VERTICAL)
                control_box.AddStretchSpacer()
                options_box = forms.static_box_sizer(
@@ -143,13 +146,13 @@ class control_panel(wx.Panel):
        def _on_clear_button(self, event):
                self.parent[NUM_LINES_KEY] = self.parent[NUM_LINES_KEY]
        def _on_incr_dynamic_range(self, event):
-               self.parent[DYNAMIC_RANGE_KEY] = min(self.parent[DYNAMIC_RANGE_KEY] + 10, MAX_DYNAMIC_RANGE)
+               self.parent[DYNAMIC_RANGE_KEY] = min(MAX_DYNAMIC_RANGE, common.get_clean_incr(self.parent[DYNAMIC_RANGE_KEY]))
        def _on_decr_dynamic_range(self, event):
-               self.parent[DYNAMIC_RANGE_KEY] = max(self.parent[DYNAMIC_RANGE_KEY] - 10, MIN_DYNAMIC_RANGE)
+               self.parent[DYNAMIC_RANGE_KEY] = max(MIN_DYNAMIC_RANGE, common.get_clean_decr(self.parent[DYNAMIC_RANGE_KEY]))
        def _on_incr_ref_level(self, event):
-               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[DYNAMIC_RANGE_KEY]*.1
+               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] + self.parent[DYNAMIC_RANGE_KEY]/DYNAMIC_RANGE_STEP
        def _on_decr_ref_level(self, event):
-               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[DYNAMIC_RANGE_KEY]*.1
+               self.parent[REF_LEVEL_KEY] = self.parent[REF_LEVEL_KEY] - self.parent[DYNAMIC_RANGE_KEY]/DYNAMIC_RANGE_STEP
        def _on_incr_time_scale(self, event):
                old_rate = self.parent[FRAME_RATE_KEY]
                self.parent[FRAME_RATE_KEY] *= 0.75
@@ -239,8 +242,8 @@ class waterfall_window(wx.Panel, pubsub.pubsub):
                if not len(self.samples): return
                min_level, max_level = common.get_min_max_fft(self.samples)
                #set the range and level
-               self[REF_LEVEL_KEY] = max_level
-               self[DYNAMIC_RANGE_KEY] = max_level - min_level
+               self[DYNAMIC_RANGE_KEY] = common.get_clean_num(max_level - min_level)
+               self[REF_LEVEL_KEY] = DYNAMIC_RANGE_STEP*round(.5+max_level/DYNAMIC_RANGE_STEP)
 
        def handle_msg(self, msg):
                """
index 5969d8405322138bc227aeda083bb52c964bc976..598b550642d1dbeb321be11f1e317d5c68970aea 100644 (file)
@@ -23,6 +23,9 @@ constsink_gl.const_sink_c(
        gain_mu=$gain_mu,
        symbol_rate=$symbol_rate,
        omega_limit=$omega_limit,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -102,6 +105,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>0.005</value>
                <type>real</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -114,11 +124,14 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>complex</type>
        </sink>
        <doc>
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 6f19f1aa47d3e8c41725791a43da29db4d663006..42bca5ccf3174d82f0152e2d7ded2d802416a4db 100644 (file)
@@ -23,6 +23,9 @@ fftsink2.$(type.fcn)(
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
        peak_hold=$peak_hold,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -158,6 +161,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <type>real</type>
                <hide>#if $average() == 'True' then 'none' else 'all'#</hide>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -170,6 +180,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -177,6 +188,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 454a4932cfab4aefbd5d00e93c674ec08537a492..9edf9650d849575de9ee471cb706d5604cb856e4 100644 (file)
@@ -14,6 +14,9 @@ histosink_gl.histo_sink_f(
        title=$title,
        num_bins=$num_bins,
        frame_size=$frame_size,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -40,6 +43,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>1000</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -52,11 +62,14 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>float</type>
        </sink>
        <doc>
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index cc66cdcb088e75d2d7fc820e2cf3dddd8f3f3b2d..5289db8af9f1351338a886e30aa077054fdde9f2 100644 (file)
@@ -24,6 +24,9 @@ numbersink2.$(type.fcn)(
        label=$title,
        peak_hold=$peak_hold,
        show_gauge=$show_gauge,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -151,6 +154,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                        <key>False</key>
                </option>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -163,6 +173,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -170,6 +181,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 503d529727662578e219011abf2117c6c8e574aa..07d29ce8fffc0ddeb68ff9b8fa7e7d7717b28a61 100644 (file)
@@ -19,6 +19,9 @@ scopesink2.$(type.fcn)(
        ac_couple=$ac_couple,
        xy_mode=$xy_mode,
        num_inputs=$num_inputs,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -102,6 +105,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>1</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -114,6 +124,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <check>not $xy_mode or '$type' == 'complex' or $num_inputs != 1</check>
        <sink>
                <name>in</name>
@@ -127,6 +138,8 @@ Set the T Scale to 0 for automatic setting.
 
 XY Mode allows the scope to initialize as an XY plotter.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 35790f820b716b68de105d983bcf4b5521f213ba..cee598990e230da499006ff0658eadbec114f4a2 100644 (file)
@@ -21,6 +21,9 @@ waterfallsink2.$(type.fcn)(
        average=$options.average,
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
+#if $win_size()
+       size=$win_size,
+#end if
 )
 #if not $grid_pos()
 $(parent).Add(self.$(id).win)
@@ -115,6 +118,13 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                        <opt>average:True</opt>
                </option>
        </param>
+       <param>
+               <name>Window Size</name>
+               <key>win_size</key>
+               <value></value>
+               <type>int_vector</type>
+               <hide>#if $win_size() then 'none' else 'part'#</hide>
+       </param>
        <param>
                <name>Grid Position</name>
                <key>grid_pos</key>
@@ -127,6 +137,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value></value>
                <type>notebook</type>
        </param>
+       <check>not $win_size or len($win_size) == 2</check>
        <sink>
                <name>in</name>
                <type>$type</type>
@@ -134,6 +145,8 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
        <doc>
 Set Average Alpha to 0 for automatic setting.
 
+Leave the window blank for the default size, otherwise enter a tuple of (width, height) pixels.
+
 Use the Grid Position (row, column, row span, column span) to position the graphical element in the window.
 
 Use the Notebook Param (notebook-id, page-index) to place the graphical element inside of a notebook page.
index 34d5ab116b07e629f16ecf0d70c29361a16579da..81fb6ba7acb7b48407fc2197099223a7a6780fe5 100644 (file)
@@ -251,7 +251,7 @@ class Param(_Param, _GUIParam):
                #########################
                # Numeric Types
                #########################
-               elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex', 'bool'):
+               elif t in ('raw', 'complex', 'real', 'int', 'hex', 'bool'):
                        #raise exception if python cannot evaluate this value
                        try: e = self.get_parent().get_parent().evaluate(v)
                        except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
@@ -269,10 +269,22 @@ class Param(_Param, _GUIParam):
                                try: assert isinstance(e, INT_TYPES)
                                except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
                                return e
-                       #########################
-                       # Numeric Vector Types
-                       #########################
-                       elif t == 'complex_vector':
+                       elif t == 'hex': return hex(e)
+                       elif t == 'bool':
+                               try: assert isinstance(e, bool)
+                               except AssertionError: raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
+                               return e
+                       else: raise TypeError, 'Type "%s" not handled'%t
+               #########################
+               # Numeric Vector Types
+               #########################
+               elif t in ('complex_vector', 'real_vector', 'int_vector'):
+                       if not v: v = '()' #turn a blank string into an empty list, so it will eval
+                       #raise exception if python cannot evaluate this value
+                       try: e = self.get_parent().get_parent().evaluate(v)
+                       except Exception, e: raise Exception, 'Value "%s" cannot be evaluated:\n%s'%(v, e)
+                       #raise an exception if the data is invalid
+                       if t == 'complex_vector':
                                if not isinstance(e, VECTOR_TYPES):
                                        self._lisitify_flag = True
                                        e = [e]
@@ -296,12 +308,6 @@ class Param(_Param, _GUIParam):
                                        for ei in e: assert isinstance(ei, INT_TYPES)
                                except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
                                return e
-                       elif t == 'hex': return hex(e)
-                       elif t == 'bool':
-                               try: assert isinstance(e, bool)
-                               except AssertionError: raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
-                               return e
-                       else: raise TypeError, 'Type "%s" not handled'%t
                #########################
                # String Types
                #########################