summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/python/gnuradio
diff options
context:
space:
mode:
authorJohnathan Corgan <johnathan@corganlabs.com>2015-04-26 16:13:41 -0700
committerJohnathan Corgan <johnathan@corganlabs.com>2015-04-26 16:13:41 -0700
commit5d6e87870328ce45eab28805e456324f14b8bfed (patch)
treeef5591d4eccdaaa66d8ac87986916b67ecde7cbf /gnuradio-runtime/python/gnuradio
parentc5e6d08637be1703af6f5905f21deceed49470a8 (diff)
parent327f07093aa75ff08a2509f77e8cbf4a840d3eed (diff)
Merge branch 'master' into next
Diffstat (limited to 'gnuradio-runtime/python/gnuradio')
-rw-r--r--gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx143
-rwxr-xr-xgnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py32
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/tag_utils.py33
3 files changed, 146 insertions, 62 deletions
diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx
index 23e11d4174..cebc00dcf4 100644
--- a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx
+++ b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx
@@ -254,18 +254,23 @@ class DataTable(QtGui.QWidget):
def update(self):
print "update"
+ def closeEvent(self, event):
+ self.timer = None
+
def __init__(self, radioclient, G):
QtGui.QWidget.__init__( self)
- self.layout = QtGui.QVBoxLayout(self);
- self.hlayout = QtGui.QHBoxLayout();
- self.layout.addLayout(self.hlayout);
+ self.layout = QtGui.QVBoxLayout(self)
+ self.hlayout = QtGui.QHBoxLayout()
+ self.layout.addLayout(self.hlayout)
- self.G = G;
- self.radioclient = radioclient;
+ self.G = G
+ self.radioclient = radioclient
self._keymap = None
+ self.disp = None
+
# Create a combobox to set the type of statistic we want.
self._statistic = "Instantaneous"
self._statistics_table = {"Instantaneous": "",
@@ -276,7 +281,7 @@ class DataTable(QtGui.QWidget):
self.stattype.addItem("Average")
self.stattype.addItem("Variance")
self.stattype.setMaximumWidth(200)
- self.hlayout.addWidget(self.stattype);
+ self.hlayout.addWidget(self.stattype)
self.stattype.currentIndexChanged.connect(self.stat_changed)
# Create a checkbox to toggle sorting of graphs
@@ -287,18 +292,18 @@ class DataTable(QtGui.QWidget):
self.checksort.stateChanged.connect(self.checksort_changed)
# set up table
- self.perfTable = Qt.QTableWidget();
+ self.perfTable = Qt.QTableWidget()
self.perfTable.setColumnCount(2)
- self.perfTable.verticalHeader().hide();
- self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Runtime"] );
- self.perfTable.horizontalHeader().setStretchLastSection(True);
+ self.perfTable.verticalHeader().hide()
+ self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Runtime"] )
+ self.perfTable.horizontalHeader().setStretchLastSection(True)
self.perfTable.setSortingEnabled(True)
nodes = self.G.nodes(data=True)
# set up plot
self.f = plt.figure(figsize=(10,8), dpi=90)
- self.sp = self.f.add_subplot(111);
- self.sp.autoscale_view(True,True,True);
+ self.sp = self.f.add_subplot(111)
+ self.sp.autoscale_view(True,True,True)
self.sp.set_autoscale_on(True)
self.canvas = FigureCanvas(self.f)
@@ -339,63 +344,71 @@ class DataTable(QtGui.QWidget):
class DataTableBuffers(DataTable):
def __init__(self, radioclient, G):
super(DataTableBuffers, self).__init__(radioclient, G)
- self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Buffer Full"] );
+ self.perfTable.setHorizontalHeaderLabels( ["Block Name", "Percent Buffer Full"] )
def update(self):
nodes = self.G.nodes();
# get buffer fullness for all blocks
kl = map(lambda x: "%s::%soutput %% full" % \
- (x, self._statistics_table[self._statistic]),
+ (x, self._statistics_table[self._statistic]),
nodes);
buf_knobs = self.radioclient.getKnobs(kl)
# strip values out of ctrlport response
buffer_fullness = dict(zip(
- map(lambda x: x.split("::")[0], buf_knobs.keys()),
- map(lambda x: x.value, buf_knobs.values())))
+ map(lambda x: x.split("::")[0], buf_knobs.keys()),
+ map(lambda x: x.value, buf_knobs.values())))
blockport_fullness = {}
for blk in buffer_fullness:
bdata = buffer_fullness[blk]
if bdata:
for port in range(0,len(bdata)):
- blockport_fullness["%s:%d"%(blk,port)] = bdata[port];
+ blockport_fullness["%s:%d"%(blk,port)] = bdata[port]
- self.table_update(blockport_fullness);
+ if(self.perfTable.isVisible()):
+ self.table_update(blockport_fullness);
- if(self._sort):
- sorted_fullness = sorted(blockport_fullness.iteritems(), key=operator.itemgetter(1))
- self._keymap = map(operator.itemgetter(0), sorted_fullness)
else:
- if self._keymap:
- sorted_fullness = len(self._keymap)*['',]
- for b in blockport_fullness:
- sorted_fullness[self._keymap.index(b)] = (b, blockport_fullness[b])
+ if(self._sort):
+ sorted_fullness = sorted(blockport_fullness.iteritems(),
+ key=operator.itemgetter(1))
+ self._keymap = map(operator.itemgetter(0), sorted_fullness)
+ else:
+ if self._keymap:
+ sorted_fullness = len(self._keymap)*['',]
+ for b in blockport_fullness:
+ sorted_fullness[self._keymap.index(b)] = (b, blockport_fullness[b])
+ else:
+ sorted_fullness = blockport_fullness.items()
+
+ if(not self.disp):
+ self.disp = self.sp.bar(range(0,len(sorted_fullness)),
+ map(lambda x: x[1], sorted_fullness),
+ alpha=0.5)
+ self.sp.set_ylabel("% Buffers Full");
+ self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_fullness))))
+ self.sp.set_xticklabels(map(lambda x: " " + x, map(lambda x: x[0], sorted_fullness)),
+ rotation="vertical", verticalalignment="bottom")
else:
- sorted_fullness = blockport_fullness.items()
+ self.sp.set_xticklabels(map(lambda x: " " + x, map(lambda x: x[0], sorted_fullness)),
+ rotation="vertical", verticalalignment="bottom")
+ for r,w in zip(self.disp, sorted_fullness):
+ r.set_height(w[1])
- self.sp.clear();
- self.sp.bar(range(0,len(sorted_fullness)), map(lambda x: x[1], sorted_fullness),
- alpha=0.5)
- self.sp.set_ylabel("% Buffers Full");
- self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_fullness))))
- self.sp.set_xticklabels( map(lambda x: " " + x, map(lambda x: x[0], sorted_fullness)),
- rotation="vertical", verticalalignment="bottom" )
- self.canvas.draw()
- self.canvas.show()
+ self.canvas.draw()
class DataTableRuntimes(DataTable):
def __init__(self, radioclient, G):
super(DataTableRuntimes, self).__init__( radioclient, G)
- #self.perfTable.setRowCount(len( self.G.nodes() ))
def update(self):
nodes = self.G.nodes();
# get work time for all blocks
kl = map(lambda x: "%s::%swork time" % \
- (x, self._statistics_table[self._statistic]),
+ (x, self._statistics_table[self._statistic]),
nodes);
wrk_knobs = self.radioclient.getKnobs(kl)
@@ -408,31 +421,37 @@ class DataTableRuntimes(DataTable):
map(lambda x: x.value/total_work, wrk_knobs.values())))
# update table view
- self.table_update(work_times)
+ if(self.perfTable.isVisible()):
+ self.table_update(work_times)
- if(self._sort):
- sorted_work = sorted(work_times.iteritems(), key=operator.itemgetter(1))
- self._keymap = map(operator.itemgetter(0), sorted_work)
else:
- if self._keymap:
- sorted_work = len(self._keymap)*['',]
- for b in work_times:
- sorted_work[self._keymap.index(b)] = (b, work_times[b])
+ if(self._sort):
+ sorted_work = sorted(work_times.iteritems(), key=operator.itemgetter(1))
+ self._keymap = map(operator.itemgetter(0), sorted_work)
else:
- sorted_work = work_times.items()
-
- self.sp.clear();
- plt.figure(self.f.number)
- plt.subplot(111);
- self.sp.bar(range(0,len(sorted_work)), map(lambda x: x[1], sorted_work),
- alpha=0.5)
- self.sp.set_ylabel("% Runtime");
- self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_work))))
- self.sp.set_xticklabels( map(lambda x: " " + x[0], sorted_work),
- rotation="vertical", verticalalignment="bottom" )
+ if self._keymap:
+ sorted_work = len(self._keymap)*['',]
+ for b in work_times:
+ sorted_work[self._keymap.index(b)] = (b, work_times[b])
+ else:
+ sorted_work = work_times.items()
+
+ f = plt.figure(self.f.number)
+ if(not self.disp):
+ self.disp = self.sp.bar(range(0,len(sorted_work)),
+ map(lambda x: x[1], sorted_work),
+ alpha=0.5)
+ self.sp.set_ylabel("% Runtime");
+ self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_work))))
+ self.sp.set_xticklabels( map(lambda x: " " + x[0], sorted_work),
+ rotation="vertical", verticalalignment="bottom" )
+ else:
+ self.sp.set_xticklabels( map(lambda x: " " + x[0], sorted_work),
+ rotation="vertical", verticalalignment="bottom" )
+ for r,w in zip(self.disp, sorted_work):
+ r.set_height(w[1])
- self.canvas.draw();
- self.canvas.show();
+ self.canvas.draw()
class MForm(QtGui.QWidget):
def update(self):
@@ -835,10 +854,10 @@ class MForm(QtGui.QWidget):
class MyApp(object):
def __init__(self, args):
p = gr.prefs()
- cp_on = p.get_bool("ControlPort", "on", None)
- cp_edges = p.get_bool("ControlPort", "edges_list", None)
- pcs_on = p.get_bool("PerfCounters", "on", None)
- pcs_exported = p.get_bool("PerfCounters", "export", None)
+ cp_on = p.get_bool("ControlPort", "on", False)
+ cp_edges = p.get_bool("ControlPort", "edges_list", False)
+ pcs_on = p.get_bool("PerfCounters", "on", False)
+ pcs_exported = p.get_bool("PerfCounters", "export", False)
if(not (pcs_on and cp_on and pcs_exported and cp_edges)):
print("Configuration has not turned on all of the appropriate ControlPort features:")
print("\t[ControlPort] on = {0}".format(cp_on))
diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py b/gnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py
index 1a08ac5ae6..55b62a12ac 100755
--- a/gnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py
+++ b/gnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py
@@ -76,6 +76,38 @@ class test_tag_utils (gr_unittest.TestCase):
self.assertTrue(pmt.equal(t_tuple.value, value))
self.assertEqual(t_tuple.offset, offset)
+ def test_003(self):
+ offsets = (6, 3, 8)
+ key = pmt.string_to_symbol('key')
+ srcid = pmt.string_to_symbol('qa_tag_utils')
+ tags = []
+
+ for k in offsets:
+ t = gr.tag_t()
+ t.offset = k
+ t.key = key
+ t.value = pmt.from_long(k)
+ t.srcid = srcid
+ tags.append(t)
+
+ for k, t in zip(sorted(offsets),
+ sorted(tags, key=gr.tag_t_offset_compare_key())):
+ self.assertEqual(t.offset, k)
+ self.assertTrue(pmt.equal(t.key, key))
+ self.assertTrue(pmt.equal(t.value, pmt.from_long(k)))
+ self.assertTrue(pmt.equal(t.srcid, srcid))
+
+ tmin = min(tags, key=gr.tag_t_offset_compare_key())
+ self.assertEqual(tmin.offset, min(offsets))
+ self.assertTrue(pmt.equal(tmin.key, key))
+ self.assertTrue(pmt.equal(tmin.value, pmt.from_long(min(offsets))))
+ self.assertTrue(pmt.equal(tmin.srcid, srcid))
+
+ tmax = max(tags, key=gr.tag_t_offset_compare_key())
+ self.assertEqual(tmax.offset, max(offsets))
+ self.assertTrue(pmt.equal(tmax.key, key))
+ self.assertTrue(pmt.equal(tmax.value, pmt.from_long(max(offsets))))
+ self.assertTrue(pmt.equal(tmax.srcid, srcid))
if __name__ == '__main__':
diff --git a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
index dc36e05250..a7745428c7 100644
--- a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
+++ b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
@@ -108,3 +108,36 @@ def python_to_tag(tag_struct):
return tag
else:
return None
+
+def tag_t_offset_compare_key():
+ """
+ Convert a tag_t_offset_compare function into a key=function
+ This method is modeled after functools.cmp_to_key(_func_).
+ It can be used by functions that accept a key function, such as
+ sorted(), min(), max(), etc. to compare tags by their offsets,
+ e.g., sorted(tag_list, key=gr.tag_t_offset_compare_key()).
+ """
+ class K(object):
+ def __init__(self, obj, *args):
+ self.obj = obj
+ def __lt__(self, other):
+ # x.offset < y.offset
+ return gr.tag_t_offset_compare(self.obj, other.obj)
+ def __gt__(self, other):
+ # y.offset < x.offset
+ return gr.tag_t_offset_compare(other.obj, self.obj)
+ def __eq__(self, other):
+ # not (x.offset < y.offset) and not (y.offset < x.offset)
+ return not gr.tag_t_offset_compare(self.obj, other.obj) and \
+ not gr.tag_t_offset_compare(other.obj, self.obj)
+ def __le__(self, other):
+ # not (y.offset < x.offset)
+ return not gr.tag_t_offset_compare(other.obj, self.obj)
+ def __ge__(self, other):
+ # not (x.offset < y.offset)
+ return not gr.tag_t_offset_compare(self.obj, other.obj)
+ def __ne__(self, other):
+ # (x.offset < y.offset) or (y.offset < x.offset)
+ return gr.tag_t_offset_compare(self.obj, other.obj) or \
+ gr.tag_t_offset_compare(other.obj, self.obj)
+ return K