commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 01/16: grc: Flowgraph complexity. Shows und


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/16: grc: Flowgraph complexity. Shows under options block when enabled.
Date: Sat, 3 Oct 2015 19:14:11 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit aaf5aa760a6876d7f5b878c563e002da19157cdb
Author: Seth Hitefield <address@hidden>
Date:   Fri Aug 28 13:55:29 2015 -0400

    grc: Flowgraph complexity. Shows under options block when enabled.
---
 grc/base/FlowGraph.py    | 54 +++++++++++++++++++++++++++++++++++++++++++++++-
 grc/gui/ActionHandler.py | 43 +++++++++++++++++++-------------------
 grc/gui/Actions.py       |  6 ++++++
 grc/gui/Bars.py          |  2 ++
 grc/gui/Block.py         | 35 ++++++++++++++++++++++++-------
 grc/gui/Constants.py     |  1 -
 grc/gui/FlowGraph.py     |  2 ++
 grc/python/Constants.py  | 11 ++++++++++
 grc/python/Param.py      | 40 +++++++++++++++--------------------
 9 files changed, 141 insertions(+), 53 deletions(-)

diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index 217c4d7..f61542c 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -67,6 +67,58 @@ class FlowGraph(Element):
     def __str__(self):
         return 'FlowGraph - %s(%s)' % (self.get_option('title'), 
self.get_option('id'))
 
+    def get_complexity(self):
+        """
+        Determines the complexity of a flowgraph
+        """
+        dbal = 0
+        block_list = self.get_blocks()
+        for block in block_list:
+            # Skip options block
+            if block.get_key() == 'options':
+                continue
+
+            # Don't worry about optional sinks?
+            sink_list = filter(lambda c: not c.get_optional(), 
block.get_sinks())
+            source_list = filter(lambda c: not c.get_optional(), 
block.get_sources())
+            sinks = float(len(sink_list))
+            sources = float(len(source_list))
+            base = max(min(sinks, sources), 1)
+
+            # Port ratio multiplier
+            if min(sinks, sources) > 0:
+                multi = sinks / sources
+                multi = (1 / multi) if multi > 1 else multi
+            else:
+                multi = 1
+
+            # Connection ratio multiplier
+            sink_multi = max(float(sum(map(lambda c: len(c.get_connections()), 
sink_list)) / max(sinks, 1.0)), 1.0)
+            source_multi = max(float(sum(map(lambda c: 
len(c.get_connections()), source_list)) / max(sources, 1.0)), 1.0)
+            dbal = dbal + (base * multi * sink_multi * source_multi)
+
+        elements = float(len(self.get_elements()))
+        connections = float(len(self.get_connections()))
+        disabled_connections = len(filter(lambda c: not c.get_enabled(), 
self.get_connections()))
+        blocks = float(len(block_list))
+        variables = elements - blocks - connections
+        enabled = float(len(self.get_enabled_blocks()))
+
+        # Disabled multiplier
+        if enabled > 0:
+            disabled_multi = 1 / (max(1 - ((blocks - enabled) / max(blocks, 
1)), 0.05))
+        else:
+            disabled_multi = 1
+
+        # Connection multiplier (How many connections )
+        if (connections - disabled_connections) > 0:
+            conn_multi = 1 / (max(1 - (disabled_connections / max(connections, 
1)), 0.05))
+        else:
+            conn_multi = 1
+
+        final = round(max((dbal - 1) * disabled_multi * conn_multi * 
connections, 0.0) / 1000000, 6)
+        return final
+
     def rewrite(self):
         def refactor_bus_structure():
 
@@ -102,7 +154,7 @@ class FlowGraph(Element):
                                 get_p().append(port);
 
         for child in self.get_children(): child.rewrite()
-        refactor_bus_structure();
+        refactor_bus_structure()
 
     def get_option(self, key):
         """
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 19c6edc..e6ffe9c 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -113,21 +113,6 @@ class ActionHandler:
         # Initialize/Quit
         ##################################################
         if action == Actions.APPLICATION_INITIALIZE:
-            for action in Actions.get_all_actions(): 
action.set_sensitive(False) #set all actions disabled
-            #enable a select few actions
-            for action in (
-                Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
-                Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
-                Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
-                Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
-                Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW,
-                Actions.TOGGLE_REPORTS_WINDOW, 
Actions.TOGGLE_HIDE_DISABLED_BLOCKS,
-                Actions.TOOLS_RUN_FDESIGN, Actions.TOGGLE_SCROLL_LOCK,
-                Actions.CLEAR_REPORTS, Actions.SAVE_REPORTS,
-                Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, 
Actions.TOGGLE_SNAP_TO_GRID,
-                Actions.TOGGLE_SHOW_BLOCK_COMMENTS,
-                Actions.TOGGLE_SHOW_CODE_PREVIEW_TAB,
-            ): action.set_sensitive(True)
             if ParseXML.xml_failures:
                 Messages.send_xml_errors_if_any(ParseXML.xml_failures)
                 Actions.XML_PARSER_ERRORS_DISPLAY.set_sensitive(True)
@@ -142,15 +127,27 @@ class ActionHandler:
             if not self.get_page(): self.main_window.new_page() #ensure that 
at least a blank page exists
 
             self.main_window.btwin.search_entry.hide()
+
+            # Disable all actions, then re-enable a few
+            for action in Actions.get_all_actions(): 
action.set_sensitive(False) #set all actions disabled
             for action in (
-                Actions.TOGGLE_REPORTS_WINDOW,
-                Actions.TOGGLE_BLOCKS_WINDOW,
-                Actions.TOGGLE_AUTO_HIDE_PORT_LABELS,
-                Actions.TOGGLE_SCROLL_LOCK,
-                Actions.TOGGLE_SNAP_TO_GRID,
+                Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
+                Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
+                Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
+                Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
+                Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW,
+                Actions.TOGGLE_REPORTS_WINDOW, 
Actions.TOGGLE_HIDE_DISABLED_BLOCKS,
+                Actions.TOOLS_RUN_FDESIGN, Actions.TOGGLE_SCROLL_LOCK,
+                Actions.CLEAR_REPORTS, Actions.SAVE_REPORTS,
+                Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, 
Actions.TOGGLE_SNAP_TO_GRID,
                 Actions.TOGGLE_SHOW_BLOCK_COMMENTS,
                 Actions.TOGGLE_SHOW_CODE_PREVIEW_TAB,
-            ): action.load_from_preferences()
+                Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY,
+            ):
+                action.set_sensitive(True)
+                if hasattr(action, 'load_from_preferences'):
+                    action.load_from_preferences()
+
         elif action == Actions.APPLICATION_QUIT:
             if self.main_window.close_pages():
                 gtk.main_quit()
@@ -416,6 +413,10 @@ class ActionHandler:
             action.save_to_preferences()
         elif action == Actions.TOGGLE_SHOW_CODE_PREVIEW_TAB:
             action.save_to_preferences()
+        elif action == Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY:
+            action.save_to_preferences()
+            for page in self.main_window.get_pages():
+                page.get_flow_graph().update()
         ##################################################
         # Param Modifications
         ##################################################
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index ce1f2cf..00184d5 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -284,6 +284,12 @@ TOGGLE_SHOW_CODE_PREVIEW_TAB = ToggleAction(
     preference_name='show_generated_code_tab',
     default=False,
 )
+TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY = ToggleAction(
+    label='Show Flowgraph Complexity',
+    tooltip="How many Balints is the flowgraph...",
+    preference_name='show_flowgraph_complexity',
+    default=False,
+)
 BLOCK_CREATE_HIER = Action(
     label='C_reate Hier',
     tooltip='Create hier block from selected blocks',
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index f0f8dac..f1f90e4 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -116,6 +116,8 @@ MENU_BAR_LIST = (
     (gtk.Action('Tools', '_Tools', None, None), [
         Actions.TOOLS_RUN_FDESIGN,
         None,
+        Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY,
+        None,
         Actions.TOOLS_MORE_TO_COME,
     ]),
     (gtk.Action('Help', '_Help', None, None), [
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 11273a5..94ed580 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -21,6 +21,7 @@ from Element import Element
 import Utils
 import Colors
 from .. base import odict
+from .. python.Param import num_to_str
 from Constants import BORDER_PROXIMITY_SENSITIVITY
 from Constants import (
     BLOCK_LABEL_PADDING, PORT_SPACING, PORT_SEPARATION, LABEL_SEPARATION,
@@ -35,9 +36,17 @@ import pango
 BLOCK_MARKUP_TMPL="""\
 #set $foreground = $block.is_valid() and 'black' or 'red'
 <span foreground="$foreground" 
font_desc="$font"><b>$encode($block.get_name())</b></span>"""
-COMMENT_MARKUP_TMPL="""\
+
+# Includes the additional complexity markup if enabled
+COMMENT_COMPLEXITY_MARKUP_TMPL="""\
 #set $foreground = $block.get_enabled() and '#444' or '#888'
-<span foreground="$foreground" 
font_desc="$font">$encode($block.get_comment())</span>"""
+#if $complexity
+<span foreground="#444" size="medium" 
font_desc="$font"><b>$encode($complexity)</b></span>
+#end if
+#if $comment
+<span foreground="$foreground" font_desc="$font">$encode($comment)</span>#slurp
+#end if"""
+
 
 class Block(Element):
     """The graphical signal block."""
@@ -218,11 +227,23 @@ class Block(Element):
         self.create_comment_label()
 
     def create_comment_label(self):
-        comment = self.get_comment()
-        if comment:
-            layout = gtk.DrawingArea().create_pango_layout('')
-            layout.set_markup(Utils.parse_template(COMMENT_MARKUP_TMPL, 
block=self, font=BLOCK_FONT))
-            width, height = layout.get_pixel_size()
+        comment = self.get_comment()    # Returns None if there are no comments
+        complexity = None
+
+        # Show the flowgraph complexity on the top block if enabled
+        if Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY.get_active() and 
self.get_key() == "options":
+            complexity = "Complexity: 
{}bal".format(num_to_str(self.get_parent().get_complexity()))
+
+        layout = gtk.DrawingArea().create_pango_layout('')
+        layout.set_markup(Utils.parse_template(COMMENT_COMPLEXITY_MARKUP_TMPL,
+                                               block=self,
+                                               comment=comment,
+                                               complexity=complexity,
+                                               font=BLOCK_FONT))
+
+        # Setup the pixel map. Make sure that layout is valid
+        width, height = layout.get_pixel_size()
+        if layout and width > 0 and height > 0:
             pixmap = self.get_parent().new_pixmap(width, height)
             gc = pixmap.new_gc()
             gc.set_foreground(Colors.COMMENT_BACKGROUND_COLOR)
diff --git a/grc/gui/Constants.py b/grc/gui/Constants.py
index a8395f6..32d6960 100644
--- a/grc/gui/Constants.py
+++ b/grc/gui/Constants.py
@@ -118,4 +118,3 @@ SCROLL_DISTANCE = 15
 
 # How close the mouse click can be to a line and register a connection select.
 LINE_SELECT_SENSITIVITY = 5
-
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index b1e88aa..fc6a711 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -285,10 +285,12 @@ class FlowGraph(Element):
         Draw all of the elements in this flow graph onto the pixmap.
         Draw the pixmap to the drawable window of this flow graph.
         """
+
         W,H = self.get_size()
         #draw the background
         gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR)
         window.draw_rectangle(gc, True, 0, 0, W, H)
+
         # draw comments first
         if Actions.TOGGLE_SHOW_BLOCK_COMMENTS.get_active():
             for block in self.iter_blocks():
diff --git a/grc/python/Constants.py b/grc/python/Constants.py
index 02be22a..b7a370c 100644
--- a/grc/python/Constants.py
+++ b/grc/python/Constants.py
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 02110-1301, USA
 
 import os
 from os.path import expanduser
+import numpy
 import stat
 from gnuradio import gr
 
@@ -53,6 +54,16 @@ FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 
'flow_graph.tmpl')
 BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd')
 DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc')
 
+#define types, native python + numpy
+VECTOR_TYPES = (tuple, list, set, numpy.ndarray)
+COMPLEX_TYPES = [complex, numpy.complex, numpy.complex64, numpy.complex128]
+REAL_TYPES = [float, numpy.float, numpy.float32, numpy.float64]
+INT_TYPES = [int, long, numpy.int, numpy.int8, numpy.int16, numpy.int32, 
numpy.uint64,
+    numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
+#cast to tuple for isinstance, concat subtypes
+COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
+REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
+INT_TYPES = tuple(INT_TYPES)
 
 # Updating colors. Using the standard color pallette from:
 #  http://www.google.com/design/spec/style/color.html#color-color-palette
diff --git a/grc/python/Param.py b/grc/python/Param.py
index 0e72fcb..27e5b76 100644
--- a/grc/python/Param.py
+++ b/grc/python/Param.py
@@ -19,8 +19,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA  02110-1301, USA
 
 from .. base.Param import Param as _Param
 from .. gui.Param import Param as _GUIParam
+
 import Constants
-import numpy
+from Constants import VECTOR_TYPES, COMPLEX_TYPES, REAL_TYPES, INT_TYPES
+
 from gnuradio import eng_notation
 import re
 from gnuradio import gr
@@ -33,16 +35,19 @@ _show_id_matcher = 
re.compile('^(variable\w*|parameter|options|notebook)$')
 import __builtin__
 ID_BLACKLIST = ['self', 'options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 
'forms', 'firdes'] + \
     filter(lambda x: not x.startswith('_'), dir(gr.top_block())) + 
dir(__builtin__)
-#define types, native python + numpy
-VECTOR_TYPES = (tuple, list, set, numpy.ndarray)
-COMPLEX_TYPES = [complex, numpy.complex, numpy.complex64, numpy.complex128]
-REAL_TYPES = [float, numpy.float, numpy.float32, numpy.float64]
-INT_TYPES = [int, long, numpy.int, numpy.int8, numpy.int16, numpy.int32, 
numpy.uint64,
-    numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
-#cast to tuple for isinstance, concat subtypes
-COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
-REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
-INT_TYPES = tuple(INT_TYPES)
+
+
+def num_to_str(num):
+    """ Display logic for numbers """
+    if isinstance(num, COMPLEX_TYPES):
+        num = complex(num) #cast to python complex
+        if num == 0: return '0' #value is zero
+        elif num.imag == 0: return '%s'%eng_notation.num_to_str(num.real) 
#value is real
+        elif num.real == 0: return '%sj'%eng_notation.num_to_str(num.imag) 
#value is imaginary
+        elif num.imag < 0: return '%s-%sj'%(eng_notation.num_to_str(num.real), 
eng_notation.num_to_str(abs(num.imag)))
+        else: return '%s+%sj'%(eng_notation.num_to_str(num.real), 
eng_notation.num_to_str(num.imag))
+    else: return str(num)
+
 
 class Param(_Param, _GUIParam):
 
@@ -88,18 +93,7 @@ class Param(_Param, _GUIParam):
         ##################################################
         if not self.is_valid(): return _truncate(self.get_value())
         if self.get_value() in self.get_option_keys(): return 
self.get_option(self.get_value()).get_name()
-        ##################################################
-        # display logic for numbers
-        ##################################################
-        def num_to_str(num):
-            if isinstance(num, COMPLEX_TYPES):
-                num = complex(num) #cast to python complex
-                if num == 0: return '0' #value is zero
-                elif num.imag == 0: return 
'%s'%eng_notation.num_to_str(num.real) #value is real
-                elif num.real == 0: return 
'%sj'%eng_notation.num_to_str(num.imag) #value is imaginary
-                elif num.imag < 0: return 
'%s-%sj'%(eng_notation.num_to_str(num.real), 
eng_notation.num_to_str(abs(num.imag)))
-                else: return '%s+%sj'%(eng_notation.num_to_str(num.real), 
eng_notation.num_to_str(num.imag))
-            else: return str(num)
+
         ##################################################
         # split up formatting by type
         ##################################################



reply via email to

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