diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-26 16:13:41 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-26 16:13:41 -0700 |
commit | 5d6e87870328ce45eab28805e456324f14b8bfed (patch) | |
tree | ef5591d4eccdaaa66d8ac87986916b67ecde7cbf /gnuradio-runtime/python/gnuradio | |
parent | c5e6d08637be1703af6f5905f21deceed49470a8 (diff) | |
parent | 327f07093aa75ff08a2509f77e8cbf4a840d3eed (diff) |
Merge branch 'master' into next
Diffstat (limited to 'gnuradio-runtime/python/gnuradio')
-rw-r--r-- | gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx | 143 | ||||
-rwxr-xr-x | gnuradio-runtime/python/gnuradio/gr/qa_tag_utils.py | 32 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/tag_utils.py | 33 |
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 |